Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/ellipticcurve/ecdsa.py: 25%
40 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from hashlib import sha256
2from .signature import Signature
3from .math import Math
4from .utils.integer import RandomInteger
5from .utils.binary import numberFromByteString
6from .utils.compatibility import *
9class Ecdsa:
11 @classmethod
12 def sign(cls, message, privateKey, hashfunc=sha256):
13 byteMessage = hashfunc(toBytes(message)).digest()
14 numberMessage = numberFromByteString(byteMessage)
15 curve = privateKey.curve
17 r, s, randSignPoint = 0, 0, None
18 while r == 0 or s == 0:
19 randNum = RandomInteger.between(1, curve.N - 1)
20 randSignPoint = Math.multiply(curve.G, n=randNum, A=curve.A, P=curve.P, N=curve.N)
21 r = randSignPoint.x % curve.N
22 s = ((numberMessage + r * privateKey.secret) * (Math.inv(randNum, curve.N))) % curve.N
23 recoveryId = randSignPoint.y & 1
24 if randSignPoint.y > curve.N:
25 recoveryId += 2
27 return Signature(r=r, s=s, recoveryId=recoveryId)
29 @classmethod
30 def verify(cls, message, signature, publicKey, hashfunc=sha256):
31 byteMessage = hashfunc(toBytes(message)).digest()
32 numberMessage = numberFromByteString(byteMessage)
33 curve = publicKey.curve
34 r = signature.r
35 s = signature.s
36 if not 1 <= r <= curve.N - 1:
37 return False
38 if not 1 <= s <= curve.N - 1:
39 return False
40 inv = Math.inv(s, curve.N)
41 u1 = Math.multiply(curve.G, n=(numberMessage * inv) % curve.N, N=curve.N, A=curve.A, P=curve.P)
42 u2 = Math.multiply(publicKey.point, n=(r * inv) % curve.N, N=curve.N, A=curve.A, P=curve.P)
43 v = Math.add(u1, u2, A=curve.A, P=curve.P)
44 if v.isAtInfinity():
45 return False
46 return v.x % curve.N == r