1import unittest 2import hmac 3import hashlib 4from util import * 5 6CA_PREFIX_LIQUID = 0x0c 7CA_PREFIX_LIQUID_REGTEST = 0x04 8EC_PUBLIC_KEY_LEN = 33 9 10class CATests(unittest.TestCase): 11 12 def test_master_blinding_key(self): 13 14 # from Trezor firmware code 15 class Slip21Node: 16 def __init__(self, seed = None): 17 if seed is not None: 18 self.data = hmac.HMAC(b"Symmetric key seed", seed, hashlib.sha512).digest() 19 else: 20 self.data = None 21 22 def derive_path(self, path): 23 for label in path: 24 h = hmac.HMAC(self.data[0:32], b"\x00", hashlib.sha512) 25 h.update(label) 26 self.data = h.digest() 27 28 def key(self): 29 return self.data[32:64] 30 31 seed = create_string_buffer(64) 32 bip39_mnemonic_to_seed(b' '.join([b'all'] * 12), b'', seed, 64) 33 root = Slip21Node(seed = seed) 34 self.assertEqual(root.key(), unhexlify('dbf12b44133eaab506a740f6565cc117228cbf1dd70635cfa8ddfdc9af734756')) 35 root.derive_path([b'SLIP-0077']) 36 master_blinding_key = root.key() 37 38 out = create_string_buffer(64) 39 ret = wally_asset_blinding_key_from_seed(seed, 64, out, 64) 40 self.assertEqual(ret, WALLY_OK) 41 _, out_hex = wally_hex_from_bytes(out[32:], 32) 42 self.assertEqual(hexlify(master_blinding_key), utf8(out_hex)) 43 44 unconfidential_addr = '2dpWh6jbhAowNsQ5agtFzi7j6nKscj6UnEr' 45 script, _ = make_cbuffer('76a914a579388225827d9f2fe9014add644487808c695d88ac') 46 private_blinding_key, _ = make_cbuffer('00' * 32) 47 ret = wally_asset_blinding_key_to_ec_private_key(root.data, len(root.data), script, len(script), private_blinding_key, len(private_blinding_key)) 48 self.assertEqual(ret, WALLY_OK) 49 public_blinding_key, _ = make_cbuffer('00' * 33) 50 ret = wally_ec_public_key_from_private_key(private_blinding_key, len(private_blinding_key), public_blinding_key, len(public_blinding_key)) 51 self.assertEqual(ret, WALLY_OK) 52 53 ret, address = wally_confidential_addr_from_addr(utf8(unconfidential_addr), CA_PREFIX_LIQUID_REGTEST, public_blinding_key, len(public_blinding_key)) 54 self.assertEqual(address, "CTEkf75DFff5ReB7juTg2oehrj41aMj21kvvJaQdWsEAQohz1EDhu7Ayh6goxpz3GZRVKidTtaXaXYEJ") 55 56 57 def test_confidential_addr(self): 58 """Tests for confidential addresses""" 59 60 # The (Liquid) address that is to be blinded 61 addr = 'Q7qcjTLsYGoMA7TjUp97R6E6AM5VKqBik6' 62 # The blinding pubkey 63 pubkey_hex = '02dce16018bbbb8e36de7b394df5b5166e9adb7498be7d881a85a09aeecf76b623' 64 # The resulting confidential address 65 addr_c = utf8('VTpz1bNuCALgavJKgbAw9Lpp9A72rJy64XPqgqfnaLpMjRcPh5UHBqyRUE4WMZ3asjqu7YEPVAnWw2EK') 66 67 # Test we can extract the original address 68 ret, result = wally_confidential_addr_to_addr(addr_c, CA_PREFIX_LIQUID) 69 self.assertEqual((ret, result), (WALLY_OK, addr)) 70 71 # Test we can extract the blinding pubkey 72 out, out_len = make_cbuffer('00' * EC_PUBLIC_KEY_LEN) 73 ret = wally_confidential_addr_to_ec_public_key(addr_c, CA_PREFIX_LIQUID, out, out_len) 74 self.assertEqual(ret, WALLY_OK) 75 _, out_hex = wally_hex_from_bytes(out, out_len) 76 self.assertEqual(utf8(pubkey_hex), utf8(out_hex)) 77 78 # Test we can re-generate the confidential address from its inputs 79 ret, new_addr_c = wally_confidential_addr_from_addr(utf8(addr), CA_PREFIX_LIQUID, out, out_len) 80 self.assertEqual(ret, WALLY_OK) 81 self.assertEqual(utf8(new_addr_c), addr_c) 82 83 84if __name__ == '__main__': 85 unittest.main() 86