def sign(self, keypairs): """ :param keypairs: pubkey:secret dict :return: """ for i, txin in enumerate(self._input_list): num = txin.in_dict['num_sig'] pubkeys, x_pubkeys = txin.get_sorted_pubkeys() for j, x_pubkey in enumerate(x_pubkeys): signatures = filter(None, txin.in_dict['signatures']) if len(signatures) == num: # txin is complete break if x_pubkey in keypairs.keys(): print_error("adding signature for", x_pubkey) secret = keypairs.get(x_pubkey) key = EC_KEY.init_from_secret(secret) msg = double_sha256(self.serialize_preimage(i).decode('hex')) sig = key.sign(msg) assert key.verify_sign(sig, msg) txin.in_dict['signatures'][j] = sig.encode('hex') txin.in_dict['x_pubkeys'][j] = x_pubkeys self._input_list[i] = txin # print_error("is_complete", self.is_complete()) self.raw = self.serialize()
def sign(secret, msg): priv_key = SigningKey.from_secret_exponent(secret, curve=secp256k1, hashfunc=sha256) msg_hash = double_sha256(msg.decode('hex')) 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 pw_decode(s, password): if password is not None: secret = double_sha256(password) try: d = DecodeAES(secret, s).decode("utf8") except Exception: raise InvalidPassword() return d else: return s
def sign_message(self, message, is_compressed): signature = self.sign_hash(double_sha256(msg_magic(message))) for i in range(4): sig = chr(27 + i + (4 if is_compressed else 0)) + signature try: self.verify_message2(sig, message) return sig except Exception: continue else: raise Exception("error: cannot sign message")
def header_dict_to_block_item(header): block = BlockItem() block.block_ver = header['version'] block.block_prev = header['prev_block_hash'] block.block_root = header['merkle_root'] block.block_ver = header['timestamp'] block.block_bits = header['bits'] block.block_nonce = header['nonce'] block.block_no = header['block_height'] block.block_hash = double_sha256(block.serialize())[::-1].encode('hex') return block
def verify_message2(self, sig, message): public_key, compressed = pubkey_from_signature(sig, message) # check public key if point_to_ser(public_key.pubkey.point, compressed) != point_to_ser( self.pubkey.point, compressed): raise Exception("Bad signature") # check message h = double_sha256(msg_magic(message)) public_key.verify_digest(sig[1:], h, sigdecode=ecdsa.util.sigdecode_string)
def sign_bitcoin_message(private_key, message, compressed=False): public_key = private_key.get_verifying_key() signature = private_key.sign_digest(double_sha256( bitcoin_message(message)), sigencode=util.sigencode_string) address = public_key_to_bc_address(encode_point(public_key, compressed)) assert public_key.verify_digest(signature, double_sha256(bitcoin_message(message)), 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_bitcoin_message(address, sig, message): return sig except: continue else: raise BaseException("error: cannot sign message")
def test_sign(self): secret = '5HvofFG7K1e2aeWESm5pbCzRHtCSiZNbfLYXBvxyA57DhKHV4U3' private_key = '0ecd20654c2e2be708495853e8da35c664247040c00bd10b9b13e5e86e6a808d' public_key = '042daa93315eebbe2cb9b5c3505df4c6fb6caca8b756786098567550d4820c09db988fe9997d049d687292f815ccd6e7fb5c1b1a91137999818d17c73d0f80aef9' msg = '0100000001be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396000000001976a914dd6cce9f255a8cc17bda8ba0373df8e861cb866e88acffffffff0123ce0100000000001976a9142bc89c2702e0e618db7d59eb5ce2f0f147b4075488ac0000000001000000' msg = double_sha256(msg.decode('hex')) sig = '30440220587ce0cf0252e2db3a7c3c91b355aa8f3385e128227cd8727c5f7777877ad7720220123af7483eb76e12ea54c73978fe627fffb91bbda6797e938147790e43ee57e5' key = EC_KEY.init_from_secret(secret) sign_result = key.sign(msg) self.assertEqual(sign_result.encode('hex'), sig) self.assertTrue(key.verify_sign(sign_result, msg))
def serialize_preimage(self, i): """ get to be sign content :param i: :return: """ version = write_uint32(self.tx_ver).encode('hex') hash_type = write_uint32(1).encode('hex') locktime = write_uint32(self.tx_locktime).encode('hex') input_list = self._input_list output_list = self._output_list txin = input_list[i] if txin.is_segwit_input(): hash_prevouts = double_sha256( ''.join(txin.serialize_outpoint() for txin in input_list).decode('hex')).encode( 'hex') hash_sequence = double_sha256( ''.join(write_uint32(txin.in_sequence) for txin in input_list).decode( 'hex')).encode('hex') hash_outputs = double_sha256( ''.join(o.serialize_output() for o in output_list).decode('hex')).encode('hex') outpoint = txin.serialize_outpoint() pubkey = txin.in_dict['pubkeys'][0] pkh = hash_160(pubkey.decode('hex')).encode('hex') # redeem_script = '00' + push_script(pkh) script_code = push_script('76a9' + push_script(pkh) + '88ac') # script_hash = hash_160(redeem_script.decode('hex')).encode('hex') # script_pub_key = 'a9' + push_script(script_hash) + '87' amount = write_uint64(txin.in_value) sequence = write_uint32(txin.in_sequence) preimage = version + hash_prevouts + hash_sequence + outpoint + script_code + amount + sequence + hash_outputs + locktime + hash_type else: txins = int_to_hex(len(input_list)) + ''.join( txin.serialize_input_preimage(k) for k, txin in enumerate(input_list)) txouts = int_to_hex(len(output_list)) + ''.join( o.serialize_output() for o in output_list) preimage = version + txins + txouts + locktime + hash_type return preimage
def __init__(self, raw=None, offset=0): if raw is not None: self.block_ver, self.block_prev_raw, self.block_root_raw, self.block_time, self.block_bits, \ self.block_nonce = struct.unpack_from('<I32s32sIII', raw, offset) self.block_prev = self.block_prev_raw[::-1].encode('hex') self.block_root = self.block_root_raw[::-1].encode('hex') self.block_hash = double_sha256_2(raw[offset:offset + 80])[::-1].encode('hex') elif raw is not None and offset is None: self.block_ver = read_uint32(raw[0:4]) self.block_prev = raw[4:36][::-1].encode('hex') self.block_root = raw[36:68][::-1].encode('hex') self.block_time = read_uint32(raw[68:72]) self.block_bits = read_uint32(raw[72:76]) self.block_nonce = read_uint32(raw[76:80]) self.block_hash = double_sha256(raw)[::-1].encode('hex')
def pubkey_from_signature(sig, message): if len(sig) != 65: raise Exception("Wrong encoding") nV = ord(sig[0]) if nV < 27 or nV >= 35: raise Exception("Bad encoding") if nV >= 31: compressed = True nV -= 4 else: compressed = False recid = nV - 27 h = double_sha256(msg_magic(message)) return MyVerifyingKey.from_signature(sig[1:], recid, h, curve=SECP256k1), compressed
def verify_message(address, sig, message): try: public_key, compressed = pubkey_from_signature(sig, message) # check public key using the address pubkey = point_to_ser(public_key.pubkey.point, compressed) addr = public_key_to_p2pkh(pubkey) if address != addr: raise Exception("Bad signature") # check message h = double_sha256(msg_magic(message)) public_key.verify_digest(sig[1:], h, sigdecode=ecdsa.util.sigdecode_string) return True except Exception as e: # print_error("Verification error: {0}".format(e)) return False
def verify_message(address, signature, message): curve = curve_secp256k1 G = generator_secp256k1 order = G.order() # extract r,s from signature sig = base64.b64decode(signature) if len(sig) != 65: raise BaseException("Wrong encoding") r, s = util.sigdecode_string(sig[1:], order) nV = ord(sig[0]) if nV < 27 or nV >= 35: return False if nV >= 31: compressed = True nV -= 4 else: compressed = False recid = nV - 27 # 1.1 x = r + (recid / 2) * order # 1.3 alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p() beta = modular_sqrt(alpha, curve.p()) y = beta if (beta - recid) % 2 == 0 else curve.p() - beta # 1.4 the constructor checks that nR is at infinity R = Point(curve, x, y, order) # 1.5 compute e from message: h = double_sha256(message) e = int(h.encode('hex'), 16) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) public_key = VerifyingKey.from_public_point(Q, curve=secp256k1) # check that Q is the public key public_key.verify_digest(sig[1:], h, sigdecode=util.sigdecode_string) # check that we get the original signing address addr = public_key_to_bc_address(encode_point(public_key, compressed)) if address == addr: return True else: # print addr return False
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 txid(self): all_segwit = all(x.is_segwit_input() for x in self.input_list()) if not all_segwit and not self.is_complete(): return None ser = self.serialize(witness=False) return double_sha256(ser.decode('hex'))[::-1].encode('hex')
def pw_encode(s, password): if password: secret = double_sha256(password) return EncodeAES(secret, s.encode("utf8")) else: return s
def verify_sign(pub_key, sign, msg): key = VerifyingKey.from_string(pub_key.decode('hex')[1:], curve=secp256k1) return key.verify_digest(sign.decode('hex'), double_sha256(msg.decode('hex')), sigdecode=util.sigdecode_der)
def wtxid(self): ser = self.serialize(witness=True) return double_sha256(ser.decode('hex'))[::-1].encode('hex')