def decrypt_message(self, encrypted, magic=b'BIE1'): encrypted = base64.b64decode(encrypted) if len(encrypted) < 85: raise Exception('invalid ciphertext: length') magic_found = encrypted[:4] ephemeral_pubkey_bytes = encrypted[4:37] ciphertext = encrypted[37:-32] mac = encrypted[-32:] if magic_found != magic: raise Exception('invalid ciphertext: invalid magic bytes') try: ecdsa_point = _ser_to_python_ecdsa_point(ephemeral_pubkey_bytes) except AssertionError as e: raise Exception( 'invalid ciphertext: invalid ephemeral pubkey') from e if not ecdsa.ecdsa.point_is_valid(generator_secp256k1, ecdsa_point.x(), ecdsa_point.y()): raise Exception('invalid ciphertext: invalid ephemeral pubkey') ephemeral_pubkey = ECPubkey.from_point(ecdsa_point) ecdh_key = (ephemeral_pubkey * self.secret_scalar).get_public_key_bytes(compressed=True) key = hashlib.sha512(ecdh_key).digest() iv, key_e, key_m = key[0:16], key[16:32], key[32:] if mac != hmac_oneshot(key_m, encrypted[:-32], hashlib.sha256): raise InvalidPassword() return aes_decrypt_with_iv(key_e, iv, ciphertext)
def _CKD_pub(cK, c, s): I = hmac_oneshot(c, cK + s, hashlib.sha512) pubkey = ecc.ECPrivkey(I[0:32]) + ecc.ECPubkey(cK) if pubkey.is_at_infinity(): raise ecc.InvalidECPointException() cK_n = pubkey.get_public_key_bytes(compressed=True) c_n = I[32:] return cK_n, c_n
def bip32_root(seed, xtype): I = hmac_oneshot(b"Bitcoin seed", seed, hashlib.sha512) master_k = I[0:32] master_c = I[32:] # create xprv first, as that will check if master_k is within curve order xprv = serialize_xprv(xtype, master_c, master_k) cK = ecc.ECPrivkey(master_k).get_public_key_bytes(compressed=True) xpub = serialize_xpub(xtype, master_c, cK) return xprv, xpub
def _CKD_priv(k, c, s, is_prime): try: keypair = ecc.ECPrivkey(k) except ecc.InvalidECPointException as e: raise BitcoinException( 'Impossible xprv (not within curve order)') from e cK = keypair.get_public_key_bytes(compressed=True) data = bytes([0]) + k + s if is_prime else cK + s I = hmac_oneshot(c, data, hashlib.sha512) I_left = ecc.string_to_number(I[0:32]) k_n = (I_left + ecc.string_to_number(k)) % ecc.CURVE_ORDER if I_left >= ecc.CURVE_ORDER or k_n == 0: raise ecc.InvalidECPointException() k_n = ecc.number_to_string(k_n, ecc.CURVE_ORDER) c_n = I[32:] return k_n, c_n
def encrypt_message(self, message: bytes, magic: bytes = b'BIE1'): """ ECIES encryption/decryption methods; AES-128-CBC with PKCS7 is used as the cipher; hmac-sha256 is used as the mac """ assert_bytes(message) randint = ecdsa.util.randrange(CURVE_ORDER) ephemeral_exponent = number_to_string(randint, CURVE_ORDER) ephemeral = ECPrivkey(ephemeral_exponent) ecdh_key = (self * ephemeral.secret_scalar).get_public_key_bytes( compressed=True) key = hashlib.sha512(ecdh_key).digest() iv, key_e, key_m = key[0:16], key[16:32], key[32:] ciphertext = aes_encrypt_with_iv(key_e, iv, message) ephemeral_pubkey = ephemeral.get_public_key_bytes(compressed=True) encrypted = magic + ephemeral_pubkey + ciphertext mac = hmac_oneshot(key_m, encrypted, hashlib.sha256) return base64.b64encode(encrypted + mac)
def is_new_seed(x: str, prefix=version.SEED_PREFIX) -> bool: x = normalize_text(x) s = bh2u(hmac_oneshot(b"Seed version", x.encode('utf8'), hashlib.sha512)) return s.startswith(prefix)
def get_secret_from_seed(seed): bip32_seed = mn.Mnemonic.mnemonic_to_seed(seed, '') I = crypto.hmac_oneshot(b"Harmony seed", bip32_seed, hashlib.sha512) master_k = I[0:32] secret = string_to_number(master_k) return secret
return bh2u(bytes([opcodes.OP_0])) elif data_len == 1 and data[0] <= 16: return bh2u(bytes([opcodes.OP_1 - 1 + data[0]])) elif data_len == 1 and data[0] == 0x81: return bh2u(bytes([opcodes.OP_1NEGATE])) return op_push(data_len) + bh2u(data) def add_number_to_script(i: int) -> bytes: return bfh(push_script(script_num_to_hex(i))) hash_encode = lambda x: bh2u(x[::-1]) hash_decode = lambda x: bfh(x)[::-1] hmac_sha_512 = lambda x, y: hmac_oneshot(x, y, hashlib.sha512) def is_new_seed(x, prefix=version.SEED_PREFIX): from . import mnemonic x = mnemonic.normalize_text(x) s = bh2u(hmac_sha_512(b"Seed version", x.encode('utf8'))) return s.startswith(prefix) def is_old_seed(seed): from . import old_mnemonic, mnemonic seed = mnemonic.normalize_text(seed) words = seed.split() try: # checks here are deliberately left weak for legacy reasons, see #3149