Module: EllipticCurve::Ecdsa

Defined in:
lib/ecdsa.rb

Class Method Summary collapse

Class Method Details

.sign(message, privateKey, hashfunc = nil) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ecdsa.rb', line 6

def self.sign(message, privateKey, hashfunc=nil)
    if hashfunc.nil? then hashfunc = lambda{ |x| Digest::SHA256.digest(x) } end
    curve = privateKey.curve
    byteMessage = hashfunc.call(message)
    numberMessage = Utils::Binary.numberFromByteString(byteMessage, curve.nBitLength)

    r, s, randSignPoint = 0, 0, nil
    kIterator = Utils::RandomInteger.rfc6979(byteMessage, privateKey.secret, curve, hashfunc)
    while r == 0 or s == 0
        randNum = kIterator.next
        randSignPoint = Math.multiplyGenerator(curve, randNum)
        r = randSignPoint.x % curve.n
        s = ((numberMessage + r * privateKey.secret) * (Math.inv(randNum, curve.n))) % curve.n
    end
    recoveryId = randSignPoint.y & 1
    if randSignPoint.y > curve.n
        recoveryId += 2
    end
    if s > curve.n / 2
        s = curve.n - s
        recoveryId ^= 1
    end

    return Signature.new(r, s, recoveryId)
end

.verify(message, signature, publicKey, hashfunc = nil) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/ecdsa.rb', line 32

def self.verify(message, signature, publicKey, hashfunc=nil)
    if hashfunc.nil? then hashfunc = lambda{ |x| Digest::SHA256.digest(x) } end
    curve = publicKey.curve
    byteMessage = hashfunc.call(message)
    numberMessage = Utils::Binary.numberFromByteString(byteMessage, curve.nBitLength)

    r = signature.r
    s = signature.s

    if not (1 <= r and r <= curve.n - 1)
        return false
    end
    if not (1 <= s and s <= curve.n - 1)
        return false
    end
    if not curve.contains(publicKey.point)
        return false
    end
    inv = Math.inv(s, curve.n)
    v = Math.multiplyAndAdd(
        curve.g, (numberMessage * inv) % curve.n,
        publicKey.point, (r * inv) % curve.n,
        curve.n, curve.a, curve.p, curve,
    )
    if v.isAtInfinity
        return false
    end
    return v.x % curve.n == r
end