def _verhlp(ec: Curve, c: int, P: Point, sig: ECDS) -> bool: # Private function for test/dev purposes # Fail if r is not [1, n-1] # Fail if s is not [1, n-1] r, s = _to_sig(ec, sig) # 1 # Let P = point(pk); fail if point(pk) fails. ec.require_on_curve(P) if P[1] == 0: raise ValueError("public key is infinite") w = mod_inv(s, ec.n) u = c * w v = r * w # 4 # Let R = u*G + v*P. RJ = _double_mult(ec, u, ec.GJ, v, (P[0], P[1], 1)) # 5 # Fail if infinite(R). assert RJ[2] != 0, "how did you do that?!?" # 5 Rx = (RJ[0] * mod_inv(RJ[2] * RJ[2], ec._p)) % ec._p x = Rx % ec.n # 6, 7 # Fail if r ≠ x(R) %n. return r == x # 8
def _verify(ec: Curve, hf: Callable[[Any], Any], mhd: bytes, P: Point, sig: ECSS) -> bool: # This raises Exceptions, while verify should always return True or False # the bitcoin proposed standard is only valid for curves # whose prime p = 3 % 4 if not ec.pIsThreeModFour: errmsg = 'curve prime p must be equal to 3 (mod 4)' raise ValueError(errmsg) # Let r = int(sig[ 0:32]). # Let s = int(sig[32:64]); fail if s is not [0, n-1]. r, s = _to_sig(ec, sig) # The message mhd: a 32-byte array _ensure_msg_size(hf, mhd) # Let P = point(pk); fail if point(pk) fails. ec.require_on_curve(P) if P[1] == 0: raise ValueError("public key is infinite") # Let e = int(hf(bytes(r) || bytes(P) || mhd)) mod n. e = _e(ec, hf, r, P, mhd) # Let R = sG - eP. # in Jacobian coordinates R = _double_mult(ec, s, ec.GJ, -e, (P[0], P[1], 1)) # Fail if infinite(R). if R[2] == 0: raise ValueError("sG - eP is infinite") # Fail if jacobi(R.y) ≠ 1. if legendre_symbol(R[1] * R[2] % ec._p, ec._p) != 1: raise ValueError("(sG - eP).y is not a quadratic residue") # Fail if R.x ≠ r. return R[0] == (R[2] * R[2] * r % ec._p)
def _verhlp(ec: Curve, e: int, P: Point, sig: ECDS) -> bool: """Private function provided for testing purposes only.""" # Fail if r is not [1, n-1] # Fail if s is not [1, n-1] r, s = _to_sig(ec, sig) # 1 # Let P = point(pk); fail if point(pk) fails. ec.require_on_curve(P) if P[1] == 0: raise ValueError("public key is infinite") s1 = mod_inv(s, ec.n) u1 = e*s1 u2 = r*s1 # 4 # Let R = u*G + v*P. RJ = _double_mult(ec, u1, ec.GJ, u2, (P[0], P[1], 1)) # 5 # Fail if infinite(R). assert RJ[2] != 0, "how did you do that?!?" # 5 Rx = (RJ[0]*mod_inv(RJ[2]*RJ[2], ec._p)) % ec._p v = Rx % ec.n # 6, 7 # Fail if r ≠ x(R) %n. return r == v # 8