def sign_hash(secret, msg_hash): priv_key = SigningKey.from_secret_exponent(secret, curve=secp256k1, hashfunc=sha256) k = rfc6979.generate_k(generator_secp256k1.order(), secret, sha256, msg_hash) % generator_secp256k1.order() return priv_key.sign_digest(msg_hash, sigencode=util.sigencode_der, k=k).encode('hex')
def test_deterministic_k(self): k = rfc6979.generate_k(SECP256k1.generator, self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data)) self.assertEqual( hexlify( util.number_to_string(k, self.key.private_key.privkey.order)), b'ab56733dc6b9cf8fbecd9af7ba64ee5b658b8a1def2f4c4c510a2996d2761d6f' )
def make_signature(self, msg_hash): msg_hash = binascii.unhexlify(msg_hash) k = generate_k(order=CURVE.n, secexp=bytes_to_int(self._ephem_keystore.to_string()), hash_func=hashlib.sha3_256, data=sha3_bytes(msg_hash + struct.pack('d', time.time()))) sig = sign(msg_hash, self._ephem_keystore.to_string(), k) return sig.encode()
def test_deterministic_k_extra_entropy_256(self): extra_entropy = bytearray.fromhex( hex(256).split("x")[1].rjust(64, "0"))[::-1] k = rfc6979.generate_k(SECP256k1.generator.order(), self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data), 0, extra_entropy) self.assertEqual( hexlify( util.number_to_string(k, self.key.private_key.privkey.order)), b'39c9dc355f042b24fe44184119c31b62ff9d8a3d0c5a26bada674d9595e6988d' )
def test_deterministic_k_extra_entropy_255(self): extra_entropy = bytearray.fromhex( hex(255).split("x")[1].rjust(64, "0"))[::-1] k = rfc6979.generate_k(SECP256k1.generator.order(), self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data), 0, extra_entropy) self.assertEqual( hexlify( util.number_to_string(k, self.key.private_key.privkey.order)), b'a2c913d48ca5d18c62126a90059a552f4cafeab85b55e9acdc6848473910f150' )
def test_deterministic_k_extra_entropy_16(self): extra_entropy = bytearray.fromhex( hex(16).split("x")[1].rjust(64, "0"))[::-1] k = rfc6979.generate_k(SECP256k1.generator.order(), self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data), 0, extra_entropy) self.assertEqual( hexlify( util.number_to_string(k, self.key.private_key.privkey.order)), b'f42eeee9d30ec008d58ce23b2ff08fac85127e87390bccccbecc68a537da3d47' )
def test_deterministic_k_extra_entropy_1(self): extra_entropy = bytearray.fromhex(hex(1).split("x")[1].rjust( 64, "0"))[::-1] k = rfc6979.generate_k(SECP256k1.generator.order(), self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data), 0, extra_entropy) self.assertEqual( hexlify( util.number_to_string(k, self.key.private_key.privkey.order)), b'f24f24e2e6510071c86da612ef04ccc21664a3801e0e06a227023b9c513a8290' )
def generate_k_rfc6979(msg_hash: int, priv_key: int, seed: Optional[int] = None) -> int: # Pad the message hash, for consistency with the elliptic.js library. if 1 <= msg_hash.bit_length() % 8 <= 4 and msg_hash.bit_length() >= 248: # Only if we are one-nibble short: msg_hash *= 16 if seed is None: extra_entropy = b'' else: extra_entropy = seed.to_bytes(math.ceil(seed.bit_length() / 8), 'big') return generate_k( EC_ORDER, priv_key, hashlib.sha256, msg_hash.to_bytes(math.ceil(msg_hash.bit_length() / 8), 'big'), extra_entropy=extra_entropy)
def sign(self, message): """ Sign a message - https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm :param message: message used to compute signature (bytes) :return: (dict) containing message, public key, private key and signature """ G = SECP256k1.generator n = G.order() #Skip step 1, e is provided by :param message #Step 2 L_n = n.bit_length() z = int(hexlify(message[:L_n]), base=16) #Step3 d_a = int(self._private_key, base=16) k = generate_k(n, d_a, hashlib.sha256, message) assert 1 <= k <= n - 1 #Step 4 p1 = k * G #Step 5 r = p1.x() % n assert r != 0 #Step 6 s = (inverse_mod(k, n) * ((z + (r * d_a)) % n)) % n assert s != 0 #Step 7 signature = hexlify(sigencode_der_canonize(r, s, n)) return { "public_key": self._public_key, "private_key": self._private_key, "message": message, "signature": signature }
def sign_message(secret, message, compressed=True): private_key = SigningKey.from_secret_exponent(secret, curve=secp256k1) public_key = private_key.get_verifying_key() msg_hash = double_sha256(message) k = rfc6979.generate_k(generator_secp256k1, secret, sha256, msg_hash) % generator_secp256k1.order() signature = private_key.sign_digest( msg_hash, sigencode=util.sigencode_string_canonize, k=k) address = public_key_to_bc_address(encode_point(public_key, compressed)) assert public_key.verify_digest(signature, msg_hash, sigdecode=util.sigdecode_string) for i in range(4): nV = 27 + i if compressed: nV += 4 sig = base64.b64encode(chr(nV) + signature) try: if verify_message(address, sig, message): return sig except: continue else: raise BaseException("error: cannot sign message")
def test_deterministic_k(self): k = rfc6979.generate_k(SECP256k1.generator.order(), self.key.private_key.privkey.secret_multiplier, sha256, unhexlify(self.hex_data)) self.assertEqual(hexlify(util.number_to_string(k, self.key.private_key.privkey.order)), b'ab56733dc6b9cf8fbecd9af7ba64ee5b658b8a1def2f4c4c510a2996d2761d6f')