def generateNonceK(privkey, msg): data = msg.encode('utf-8') hashed = sha256(data).digest() d = int(privkey, 16) k = rfc6979.generate_k(n, d, sha256, hashed) kHex = format(k, 'x') return kHex
def sign(hash, priv, k=0): ''' Returns a DER-encoded signature from a input of a hash and private key, and optionally a K value. Hash and private key inputs must be 64-char hex strings, k input is an int/long. >>> h = 'f7011e94125b5bba7f62eb25efe23339eb1637539206c87df3ee61b5ec6b023e' >>> p = 'c05694a7af0e01dceb63e5912a415c28d3fc823ca1fd3fa34d41afde03740466' >>> k = 4 # chosen by fair dice roll, guaranteed to be random >>> sign(h,p,k) '3045022100e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd130220598e37e2e66277ef4d0caf0e32d095debb3c744219508cd394b9747e548662b7' ''' if k == 0: k = generate_k(priv, hash) hash = int(hash, 16) priv = int(priv, 16) r = int(privtopub(dechex(k, 32), True)[2:], 16) % N s = ((hash + (r * priv)) * modinv(k, N)) % N # High S value is non-standard (soon to be invalid) if s > (N / 2): s = N - s r, s = inttoDER(r), inttoDER(s) olen = dechex(len(r + s) // 2, 1) return '30' + olen + r + s
def sign_digest_deterministic(self, digest, hashfunc=None, sigencode=sigencode_string): """ Calculates 'k' from data itself, removing the need for strong random generator and producing deterministic (reproducible) signatures. See RFC 6979 for more details. """ secexp = self.privkey.secret_multiplier k = rfc6979.generate_k(self.curve.generator.order(), secexp, hashfunc, digest) return self.sign_digest(digest, sigencode=sigencode, k=k)
def test_deterministic(self): data = b("blahblah") secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16) priv = SigningKey.from_secret_exponent(secexp, SECP256k1, sha256) pub = priv.get_verifying_key() k = rfc6979.generate_k(SECP256k1.generator.order(), secexp, sha256, sha256(data).digest()) sig1 = priv.sign(data, k=k) self.assertTrue(pub.verify(sig1, data)) sig2 = priv.sign(data, k=k) self.assertTrue(pub.verify(sig2, data)) sig3 = priv.sign_deterministic(data, sha256) self.assertTrue(pub.verify(sig3, data)) self.assertEqual(sig1, sig2) self.assertEqual(sig1, sig3)
def sign_digest_deterministic(self, digest, hashfunc=None, sigencode=sigencode_string, ensure_low_s_according_to_bip62=False): """ Calculates 'k' from data itself, removing the need for strong random generator and producing deterministic (reproducible) signatures. See RFC 6979 for more details. """ secexp = self.privkey.secret_multiplier k = rfc6979.generate_k(self.curve.generator.order(), secexp, hashfunc, digest) # print("RFC6979 'k' = `{}`".format(hex(k))) return ( k, self.sign_digest( digest, sigencode=sigencode, k=k, ensure_low_s_according_to_bip62=ensure_low_s_according_to_bip62 ))
def _do(self, generator, secexp, hsh, hash_func, expected): actual = rfc6979.generate_k(generator.order(), secexp, hash_func, hsh) self.assertEqual(expected, actual)