def generate_btc_address(): # secp256k1, not included in stock ecdsa _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L _b = 0x0000000000000000000000000000000000000000000000000000000000000007L _a = 0x0000000000000000000000000000000000000000000000000000000000000000L _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L curve_256 = CurveFp(_p, _a, _b) generator = Point(curve_256, _Gx, _Gy, _r) secret = randrange(1, generator.order()) pubkey = Public_key(generator, generator * secret) step1 = '\x04' + int_to_string(pubkey.point.x()) + \ int_to_string(pubkey.point.y()) step2 = hashlib.sha256(step1).digest() ripehash.update(step2) step4 = '\x30' + ripehash.digest() #3f step5 = hashlib.sha256(step4).digest() step6 = hashlib.sha256(step5).digest() chksum = step6[:4] addr = step4 + chksum addr_58 = b58encode(addr) return ( hex(secret)[2:-1], hexlify(step1), hexlify(addr), addr_58 )
def PublicKey(self): "Return compressed public key encoding" if self.K.pubkey.point.y() & 1: ck = b'\3'+int_to_string(self.K.pubkey.point.x()) else: ck = b'\2'+int_to_string(self.K.pubkey.point.x()) return ck
def generate_pub_address_from_secret(secret): # secp256k1, not included in stock ecdsa _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L _b = 0x0000000000000000000000000000000000000000000000000000000000000007L _a = 0x0000000000000000000000000000000000000000000000000000000000000000L _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L curve_256 = CurveFp(_p, _a, _b) generator = Point(curve_256, _Gx, _Gy, _r) # secret = randrange(1, generator.order()) pubkey = Public_key(generator, generator * secret) step1 = '\x04' + int_to_string(pubkey.point.x()) + int_to_string( pubkey.point.y()) step2 = hashlib.sha256(step1).digest() ripehash.update(step2) step4 = '\x3f' + ripehash.digest() step5 = hashlib.sha256(step4).digest() step6 = hashlib.sha256(step5).digest() chksum = step6[:4] addr = step4 + chksum addr_58 = b58encode(addr) return (secret, hex(secret)[2:-1], binascii.hexlify(step1), binascii.hexlify(addr), addr_58)
def PublicKey(self): "Return compressed public key encoding" if self.K.pubkey.point.y() & 1: ck = b'\3' + int_to_string(self.K.pubkey.point.x()) else: ck = b'\2' + int_to_string(self.K.pubkey.point.x()) return ck
def public_key(self, private_key: str = None) -> str: """ Get Public Key. :returns: str -- Public key. >>> from pyxdc import HTTP_PROVIDER >>> from pyxdc.wallet import Wallet >>> wallet: Wallet = Wallet(provider=HTTP_PROVIDER) >>> wallet.from_entropy(entropy="b64dc1c3c3d5b876a94006d49c1e4ed2f106b86e") >>> wallet.from_path(path="m/44'/550'/0'/0/0") >>> wallet.public_key() "03d8799336beacc6b2e7f86f46bce4ad5cabf1ec7a0d6241416985e3b29fe1cc85" """ if private_key: key = ecdsa.SigningKey.from_string(unhexlify(private_key), curve=SECP256k1) verified_key = key.get_verifying_key() padx = (b"\0" * 32 + int_to_string(verified_key.pubkey.point.x()))[-32:] if verified_key.pubkey.point.y() & 1: ck = b"\3" + padx else: ck = b"\2" + padx return hexlify(ck).decode() return self.compressed()
def CKDpriv(self, i): """ Create a child key of index 'i'. If the most significant bit of 'i' is set, then select from the hardened key set, otherwise, select a regular child key. Returns a BIP32Key constructed with the child key parameters, or None if i index would result in an invalid key. """ # Index as bytes, BE i_str = struct.pack(">L", i) # Data to HMAC if i & BIP32_HARDEN: data = b'\0' + self.k.to_string() + i_str else: data = self.PublicKey() + i_str # Get HMAC of data (Il, Ir) = self.hmac(data) # Construct new key material from Il and current private key Il_int = string_to_int(Il) if Il_int > CURVE_ORDER: return None pvt_int = string_to_int(self.k.to_string()) k_int = (Il_int + pvt_int) % CURVE_ORDER if (k_int == 0): return None secret = (b'\0'*32 + int_to_string(k_int))[-32:] # Construct and return a new BIP32Key return BIP32Key(secret=secret, chain=Ir, depth=self.depth+1, index=i, fpr=self.Fingerprint(), public=False)
def CKDpriv(self, i): """ Create a child key of index 'i'. If the most significant bit of 'i' is set, then select from the hardened key set, otherwise, select a regular child key. Returns a BIP32Key constructed with the child key parameters, or None if i index would result in an invalid key. """ # Index as bytes, BE i_str = struct.pack(">L", i) # Data to HMAC if i & BIP32_HARDEN: data = b'\0' + self.k.to_string() + i_str else: data = self.PublicKey() + i_str # Get HMAC of data (Il, Ir) = self.hmac(data) # Construct new key material from Il and current private key Il_int = string_to_int(Il) if Il_int > CURVE_ORDER: return None pvt_int = string_to_int(self.k.to_string()) k_int = (Il_int + pvt_int) % CURVE_ORDER if (k_int == 0): return None secret = (b'\0'*32 + int_to_string(k_int))[-32:] # Construct and return a new BIP32Key return BIP32Key(secret=secret, chain=Ir, depth=self.depth+1, index=i, fpr=self.Fingerprint(), public=False, testnet=self.testnet)
def _derive_key_by_index(self, index) -> Optional["Wallet"]: i_str = struct.pack(">L", index) if index & config["hardened"]: data = b"\0" + self._key.to_string() + i_str else: data = unhexlify(self.public_key()) + i_str if not self._chain_code: raise PermissionError( "You can't drive xprivate_key and private_key.") i = hmac.new(self._chain_code, data, hashlib.sha512).digest() il, ir = i[:32], i[32:] il_int = string_to_int(il) if il_int > CURVE_ORDER: return None pvt_int = string_to_int(self._key.to_string()) k_int = (il_int + pvt_int) % CURVE_ORDER if k_int == 0: return None secret = (b"\0" * 32 + int_to_string(k_int))[-32:] self._private_key, self._chain_code, self._depth, self._index, self._parent_fingerprint = ( secret, ir, (self._depth + 1), index, unhexlify(self.finger_print())) self._key = ecdsa.SigningKey.from_string(self._private_key, curve=SECP256k1) self._verified_key = self._key.get_verifying_key() return self
def child_priv(self, index): if index >= 0x80000000: data = b'\0' + self.k.to_string() + index.to_bytes(4, 'big') else: k_int = string_to_int(self.k.to_string()) point = k_int * generator_secp256k1 compressed = self.sec(point) data = compressed + index.to_bytes(4, 'big') left, right = self.hmac(data) left_int = string_to_int(left) k_int = string_to_int(self.k.to_string()) child_k_int = (left_int + k_int) % generator_secp256k1.order() if (child_k_int == 0) or left_int >= generator_secp256k1.order(): return None child_key = int_to_string(child_k_int) child_key = zero_padding(32, child_key) assert (len(child_key) == 32) key = Key(secret=child_key, chain=right, level=self.level + 1, index=index.to_bytes(4, 'big'), fingerprint=self.fingerprint(), public=False) self.children.append(key) return key
def PublicKey(self): "Return compressed public key encoding" padx = (b'\0'*32 + int_to_string(self.K.pubkey.point.x()))[-32:] if self.K.pubkey.point.y() & 1: ck = b'\3'+padx else: ck = b'\2'+padx return ck
def compressed(self): padx = (b"\0" * 32 + int_to_string(self.verified_key.pubkey.point.x()))[-32:] if self.verified_key.pubkey.point.y() & 1: ck = b"\3" + padx else: ck = b"\2" + padx return hexlify(ck).decode()
def PublicKey(self, private=None): if private: private = binascii.unhexlify(private) key = ecdsa.SigningKey.from_string(bytes(private), curve=SECP256k1) verifiedKey = key.get_verifying_key() padx = (b'\0' * 32 + int_to_string(verifiedKey.pubkey.point.x()))[-32:] if self.verifiedKey.pubkey.point.y() & 1: ck = b'\3' + padx else: ck = b'\2' + padx return ck padx = (b'\0' * 32 + int_to_string(self.verifiedKey.pubkey.point.x()))[-32:] if self.verifiedKey.pubkey.point.y() & 1: ck = b'\3' + padx else: ck = b'\2' + padx return ck
def check_recovery(self, pub): padx = (b'\0' * 32 + int_to_string(pub.pubkey.point.x()))[-32:] if pub.pubkey.point.y() & 1: ck = b'\3' + padx else: ck = b'\2' + padx return hexlify(ck)
def public_key(self, private_key=None): if private_key: key = ecdsa.SigningKey.from_string( unhexlify(private_key), curve=SECP256k1) verified_key = key.get_verifying_key() padx = (b"\0" * 32 + int_to_string( verified_key.pubkey.point.x()))[-32:] if verified_key.pubkey.point.y() & 1: ck = b"\3" + padx else: ck = b"\2" + padx return hexlify(ck).decode() padx = (b"\0" * 32 + int_to_string( self.verified_key.pubkey.point.x()))[-32:] if self.verified_key.pubkey.point.y() & 1: ck = b"\3" + padx else: ck = b"\2" + padx return hexlify(ck).decode()
def to_pubkey(privkey_obj: ecdsa.SigningKey) -> bytes: # pragma: nocover """ Return compressed public key encoding Adapted from prusnak's bip32utils https://github.com/prusnak/bip32utils/ https://github.com/prusnak/bip32utils/blob/master/LICENSE """ pubkey_obj = privkey_obj.get_verifying_key() padx = (b'\0' * 32 + int_to_string(pubkey_obj.pubkey.point.x()))[-32:] if pubkey_obj.pubkey.point.y() & 1: ck = b'\3' + padx else: ck = b'\2' + padx return ck
def bip32_key(secret, chain, depth, index, fpr): # Serialization format can be found at: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Serialization_format xprv = binascii.unhexlify( "0488ade4") # Version string for mainnet extended private keys xpub = binascii.unhexlify( "0488b21e") # Version string for mainnet extended public keys child = struct.pack( '>L', index ) # >L -> big endian -> the way of storing values starting from most significant value in sequence k_priv = ecdsa.SigningKey.from_string(secret, curve=SECP256k1) K_priv = k_priv.get_verifying_key() data_priv = b'\x00' + (k_priv.to_string()) if K_priv.pubkey.point.y() & 1: data_pub = b'\3' + int_to_string(K_priv.pubkey.point.x()) else: data_pub = b'\2' + int_to_string(K_priv.pubkey.point.x()) raw_priv = xprv + depth + fpr + child + chain + data_priv raw_pub = xpub + depth + fpr + child + chain + data_pub # Double hash using SHA256 hashed_xprv = hashlib.sha256(raw_priv).digest() hashed_xprv = hashlib.sha256(hashed_xprv).digest() hashed_xpub = hashlib.sha256(raw_pub).digest() hashed_xpub = hashlib.sha256(hashed_xpub).digest() # Append 4 bytes of checksum raw_priv += hashed_xprv[:4] raw_pub += hashed_xpub[:4] # Return base58 print(B58.b58encode(raw_priv)) print(B58.b58encode(raw_pub)) return [data_pub, chain, k_priv, K_priv]
def CKDpriv(self): if self.hardened: i= 2147483648+self.index i_str=struct.pack('>L',i) child_L_MPK=b'\x00'+self.priv_key+i_str else: i= self.index i_str=struct.pack('>L',i) child_L_MPK=self.pub_key+i_str child_L_MPKhmac=hmac.new(key=self.chaincode, msg=child_L_MPK , digestmod=hashlib.sha512).digest() child_LPhml, output_chaincode = child_L_MPKhmac[:32], child_L_MPKhmac[32:] child_LPhml_int=(string_to_int(child_LPhml)) master_pk_int=(string_to_int(self.priv_key)) presecret=child_LPhml_int+master_pk_int return (b'\x00'*32 + int_to_string(presecret% CURVE_ORDER))[-32:]
def __CkdPriv(self, index): """ Create a child key of the specified index. Args: index (int): Index Returns: Bip32 object: Bip32 object constructed with the child parameters Raises: Bip32KeyError: If the index results in an invalid key """ # Index as bytes index_bytes = index.to_bytes(4, "big") # Data for HMAC if Bip32Utils.IsHardenedIndex(index): data = b"\x00" + self.m_key.to_string() + index_bytes else: data = self.PublicKey().RawCompressed().ToBytes() + index_bytes # Compute HMAC halves i_l, i_r = self.__HmacHalves(data) # Construct new key secret from i_l and current private key i_l_int = string_to_int(i_l) key_int = string_to_int(self.m_key.to_string()) new_key_int = (i_l_int + key_int) % Bip32Const.CURVE_ORDER # Convert to string and left pad with zeros secret = int_to_string(new_key_int) secret = b"\x00" * (32 - len(secret)) + secret # Construct and return a new Bip32 object return Bip32(secret=secret, chain=i_r, depth=self.m_depth + 1, index=index, fprint=self.FingerPrint(), is_public=False, key_net_ver=self.m_key_net_ver)
def compressed(self) -> str: """ Get Commpresed Public Key. :returns: str -- Commpresed public key. >>> from pyxdc import HTTP_PROVIDER >>> from pyxdc.wallet import Wallet >>> wallet: Wallet = Wallet(provider=HTTP_PROVIDER) >>> wallet.from_entropy(entropy="b64dc1c3c3d5b876a94006d49c1e4ed2f106b86e") >>> wallet.from_path(path="m/44'/550'/0'/0/0") >>> wallet.compressed() "03d8799336beacc6b2e7f86f46bce4ad5cabf1ec7a0d6241416985e3b29fe1cc85" """ padx = (b"\0" * 32 + int_to_string(self._verified_key.pubkey.point.x()))[-32:] if self._verified_key.pubkey.point.y() & 1: ck = b"\3" + padx else: ck = b"\2" + padx return hexlify(ck).decode()
def DerivePrivateKey(self, index): i_str = struct.pack(">L", index) if index & BIP32_HARDEN: data = b'\0' + self.key.to_string() + i_str else: data = self.PublicKey() + i_str Il, Ir = self.hmac(data) Il_int = string_to_int(Il) if Il_int > CURVE_ORDER: return None pvt_int = string_to_int(self.key.to_string()) k_int = (Il_int + pvt_int) % CURVE_ORDER if k_int == 0: return None secret = (b'\0' * 32 + int_to_string(k_int))[-32:] return CobraHDWallet( secret=secret, chain=Ir, depth=self.depth + 1, index=index, fingerprint=self.Fingerprint())
def child_key_derivation_from_private(master_private_key, master_chaincode, index): i_str = ser32(index) if index & BIP32_HARDEN: data = bytes.fromhex("00") + master_private_key + bytes(i_str) else: data = private_to_public(master_private_key) + bytes(i_str) (Il, Ir) = hmacsha512(data, master_chaincode) ilInt = string_to_int(Il) if ilInt > CURVE_ORDER: return None privateInt = string_to_int(master_private_key) priavte_key_int = (ilInt + privateInt) % CURVE_ORDER if (priavte_key_int == 0): return None secret = (b'\0'*32 + int_to_string(priavte_key_int))[-32:] print("child key:" + str(index)) print("private key:" + secret.hex()) print("wif priavte key:" + privatekey_to_wif(secret)) publicKey = private_to_public(secret) print("public key:" + publicKey.hex()) print("address:" + publickey_to_address(publicKey)) print("") return secret, Ir
def derive_private_key(self, index): i_str = struct.pack(">L", index) if index & BIP32KEY_HARDEN: data = b"\0" + self.key.to_string() + i_str else: data = unhexlify(self.public_key()) + i_str il, ir = self.hmac(data) il_int = string_to_int(il) if il_int > CURVE_ORDER: return None pvt_int = string_to_int(self.key.to_string()) k_int = (il_int + pvt_int) % CURVE_ORDER if k_int == 0: return None secret = (b"\0" * 32 + int_to_string(k_int))[-32:] self.secret, self.chain, self.depth, self.index, self.parent_fingerprint = \ secret, ir, (self.depth + 1), index, unhexlify(self.finger_print()) self.key = ecdsa.SigningKey.from_string(self.secret, curve=SECP256k1) self.verified_key = self.key.get_verifying_key() return self
fpr = b'\0\0\0\0' # Parent fingerprint, index = 0 # Child index child = struct.pack( '>L', index ) # >L -> big endian -> the way of storing values starting from most significant value in sequence k_priv = ecdsa.SigningKey.from_string(secret, curve=SECP256k1) K_priv = k_priv.get_verifying_key() data_priv = b'\x00' + ( k_priv.to_string() ) # ser256(p): serializes integer p as a 32-byte sequence # serialization the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form if K_priv.pubkey.point.y() & 1: data_pub = b'\3' + int_to_string(K_priv.pubkey.point.x()) else: data_pub = b'\2' + int_to_string(K_priv.pubkey.point.x()) raw_priv = xprv + depth + fpr + child + chain + data_priv raw_pub = xpub + depth + fpr + child + chain + data_pub # Double hash using SHA256 hashed_xprv = hashlib.sha256(raw_priv).digest() hashed_xprv = hashlib.sha256(hashed_xprv).digest() hashed_xpub = hashlib.sha256(raw_pub).digest() hashed_xpub = hashlib.sha256(hashed_xpub).digest() # Append 4 bytes of checksum raw_priv += hashed_xprv[:4] raw_pub += hashed_xpub[:4]
def generatePublicKey(secret): publicKeyPoint = Public_key(generator_secp256k1, generator_secp256k1 * secret).point return '\x04' + int_to_string(publicKeyPoint.x()) + int_to_string(publicKeyPoint.y())
def generatePublicKey(secret): publicKeyPoint = Public_key(generator_secp256k1, generator_secp256k1 * secret).point return '\x04' + int_to_string(publicKeyPoint.x()) + int_to_string( publicKeyPoint.y())
def sec(self, point): if point.y() & 1: return b'\3' + zero_padding(32, int_to_string(point.x())) else: return b'\2' + zero_padding(32, int_to_string(point.x()))
def decode_base58(addr, length): n = 0 for char in addr: n = n * 58 + _b58chars.index(char) return (b'\0'*length + int_to_string(n))[-length:] #n.to_bytes(length, 'big')
data_pub, chain, k_priv, K_priv = bip32_key(Il, Ir, b'\x00', 0, b'\0\0\0\0') # chain m/0 ITERATE = 0 + BIP32_HARDEN # because chain m/0 i_str = struct.pack(">L", ITERATE) # for non-hardened derivation # data = data_pub + i_str # for hardened derivation data = b'\0' + k_priv.to_string() + i_str I = hmac.new(chain, data, hashlib.sha512).digest() Il, Ir = I[:32], I[32:] Il_int = string_to_int(Il) pvt_int = string_to_int(k_priv.to_string()) k_int = (Il_int + pvt_int) % CURVE_ORDER secret = (b'\0' * 32 + int_to_string(k_int))[-32:] depth = bytes([1]) #fingrprint: padx = (b'\0' * 32 + int_to_string(K_priv.pubkey.point.x()))[-32:] if K_priv.pubkey.point.y() & 1: ck = b'\3' + padx else: ck = b'\2' + padx fingerprint = hashlib.new('ripemd160', sha256(ck).digest()).digest()[:4] new_data_pub, new_chain, new_k_priv, new_K_priv = bip32_key( secret, Ir, depth, ITERATE, fingerprint)
def decode_base58(addr, length): n = 0 for char in addr: n = n * 58 + _b58chars.index(char) return (b'\0' * length + int_to_string(n))[-length:] #n.to_bytes(length, 'big')
def int_to_private_key(input_int: int) -> NumberAsHexBytes: return (b'\0' * 32 + int_to_string(input_int))[-32:]