def test_encoding(self): raw_sig = hex_to_bytes( '304402206878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c022018610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f' ) sig = Signature.decode(raw_sig) self.assertEqual( sig.r, 47253809947851177065887724633329625063088643784040492056218945870752194997548 ) self.assertEqual( sig.s, 11026965355983493404719379810734327200902731292741433431270495068542334764399 ) self.assertEqual(sig.encode(), raw_sig) r = hex_to_int( '316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d') s = hex_to_int( 'bf46d26cef45d998a2cb5d2d0b8342d70973fa7c3c37ae72234696524b2bc812') sig_high_s = hex_to_bytes( '30450220316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d022100bf46d26cef45d998a2cb5d2d0b8342d70973fa7c3c37ae72234696524b2bc812' ) sig_low_s = hex_to_bytes( '30440220316eb3cad8b66fcf1494a6e6f9542c3555addbf337f04b62bf4758483fdc881d022040b92d9310ba26675d34a2d2f47cbd27b13ae26a7310f1c99c8bc83a850a792f' ) sig_high = Signature(r, s, force_low_s=False) sig_low = Signature(r, s, force_low_s=True) self.assertEqual(sig_low.encode(), sig_low_s) self.assertEqual(sig_high.encode(), sig_high_s) self.assertEqual(sig_low, Signature.decode(sig_high_s)) self.assertEqual(sig_low, Signature.decode(sig_low_s)) sig = Signature(secrets.randbelow(CURVE.N), secrets.randbelow(CURVE.N)) self.assertEqual(sig, Signature.decode(sig.encode())) # Test padding sig = Signature(secrets.randbelow(10**8), secrets.randbelow(10**8)) self.assertEqual(sig, Signature.decode(sig.encode()))
def sign_hash(self, hash): e = hex_to_int(hash) if isinstance(hash, str) else bytes_to_int(hash) r, s = 0, 0 while r == 0 or s == 0: k = secrets.randbelow(N) point = CURVE.G * k r = point.x % N inv_k = mulinv(k, N) s = (inv_k * (e + r * self.int())) % N return Signature(r=r, s=s)
def _verify_ecdsa(self, signature: Signature, public: PublicKey) -> bool: r, s = signature.r, signature.s if not (1 <= r < N and 1 <= s < N): return False e = hex_to_int(self.hash()) w = mulinv(s, N) u1 = (e * w) % N u2 = (r * w) % N point = CURVE.G * u1 + public.point * u2 return r % N == point.x % N
def sign(self, private: PrivateKey) -> Signature: e = hex_to_int(self.hash()) r, s = 0, 0 while r == 0 or s == 0: k = secrets.randbelow(N) point = CURVE.G * k r = point.x % N inv_k = mulinv(k, N) s = (inv_k * (e + r * private.int())) % N return Signature(r=r, s=s)