def safe_public_child_key(extended_public_key, chain_code, i, return_as_hex=True): if not extended_public_key or not chain_code: return None AP = extended_public_key cP = chain_code assert 0 <= i < 2**31 i_bytes = i.to_bytes(4, 'little') if i < 2**31: # regular, non-hardened child Z = Fk(b'\x02' + AP + i_bytes, cP) c = Fk(b'\x03' + AP + i_bytes, cP)[32:] else: raise Exception("Can't create hardened keys from public key") ZL, ZR = Z[:28], Z[32:] A = ed25519.encodepoint( ed25519.edwards( ed25519.decodepoint(AP), ed25519.scalarmultbase(8 * int.from_bytes(ZL, 'little')))) # VERY IMPORTANT. DO NOT USE A CHILD KEY THAT IS EQUIVALENT TO THE IDENTITY POINT # "If Ai is the identity point (0, 1), discard the child." # - "BIP32-Ed25519 Hierarchical Deterministic Keys over a Non-linear Keyspace" (https://drive.google.com/file/d/0ByMtMw2hul0EMFJuNnZORDR2NDA/view) if A == ed25519.encodepoint([0, 1]): return -1 if return_as_hex: return (A.hex(), c.hex()) else: return (A, c)
def generate_stealth_address(publicViewKey, privateTxKey, publicSpendKey, index): ## multiply r*A derivation = utils.generate_key_derivation(publicViewKey, privateTxKey) ## concatenate index to derivation then hash and reduce ## Hs(rA|i) scalar = utils.derivation_to_scalar(derivation, index) ## multiply by base point ## Hs(rA|i)G sG = ed25519.scalarmultbase(utils.hex2int(scalar)) ## interpret the public spend key as a point on the curve pubPoint = ed25519.decodepoint(unhexlify(publicSpendKey)) ## add the public spend key to the previously calculated point ## Hs(rA|i)G + B output = ed25519.edwards(pubPoint, sG) ## convert the point to a hex encoded public key return hexlify(ed25519.encodepoint(output))
def addKeys(P1, P2): return binascii.hexlify( ed25519.encodepoint(ed25519.edwards(toPoint(P1), toPoint(P2))))
def addKeys(P1, P2): return binascii.hexlify(ed25519.encodepoint(ed25519.edwards(toPoint(P1), toPoint(P2))))