def test_forge_hash_sig(self): """forging valid hash signatures""" ec = secp256k1 # see https://twitter.com/pwuille/status/1063582706288586752 # Satoshi's key P = point_from_octets( secp256k1, "0311db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c" ) u1 = 1 u2 = 2 # pick them at will R = double_mult(ec, u1, ec.G, u2, P) r = R[0] % ec.n u2inv = mod_inv(u2, ec.n) s = r * u2inv % ec.n sig = r, s e = s * u1 % ec.n dsa._verhlp(ec, e, P, sig) u1 = 1234567890 u2 = 987654321 # pick them at will R = double_mult(ec, u1, ec.G, u2, P) r = R[0] % ec.n u2inv = mod_inv(u2, ec.n) s = r * u2inv % ec.n sig = r, s e = s * u1 % ec.n dsa._verhlp(ec, e, P, sig)
def test_p2wpkh_address(self): # https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki # leading/trailing spaces should be tolerated pub = " 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" addr = b'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4' self.assertEqual(addr, p2wpkh_address(pub)) addr = b'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx' self.assertEqual(addr, p2wpkh_address(pub, 'testnet')) # http://bitcoinscri.pt/pages/segwit_native_p2wpkh_address pub = "02530c548d402670b13ad8887ff99c294e67fc18097d236d57880c69261b42def7" addr = b'bc1qg9stkxrszkdqsuj92lm4c7akvk36zvhqw7p6ck' self.assertEqual(addr, p2wpkh_address(pub)) _, _, wp = _decode(addr) self.assertEqual(bytes(wp), hash160(pub)) # Uncompressed pubkey uncompr_pub = octets_from_point(point_from_octets(pub, ec), False, ec) self.assertRaises(ValueError, p2wpkh_address, uncompr_pub) # p2wpkh_address(uncompr_pub) # Wrong pubkey size: 34 instead of 33 self.assertRaises(ValueError, p2wpkh_address, pub + '00') # p2wpkh_address(pub + '00') # Witness program length (21) is not 20 self.assertRaises(ValueError, _p2wpkh_address, hash160(pub) + b'\x00', True, "mainnet")
def test_p2pkh_address_from_pubkey(self): # https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses pub = '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352' addr = p2pkh_address(pub) self.assertEqual(addr, b'1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs') _, _, hash2 = h160_from_base58_address(addr) self.assertEqual(hash2, hash160(pub)) uncompressed_pub = octets_from_point(point_from_octets(pub, ec), False, ec) addr = p2pkh_address(uncompressed_pub) self.assertEqual(addr, b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM') _, _, hash2 = h160_from_base58_address(addr) self.assertEqual(hash2, hash160(uncompressed_pub)) # trailing/leading spaces in string pub = ' 0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352' addr = p2pkh_address(pub) self.assertEqual(addr, b'1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs') _, _, hash2 = h160_from_base58_address(addr) self.assertEqual(hash2, hash160(pub)) pub = '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352 ' addr = p2pkh_address(pub) self.assertEqual(addr, b'1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs')
def test_all_curves(self): for ec in all_curves: self.assertEqual(mult(ec, 0, ec.G), Inf) self.assertEqual(mult(ec, 0, ec.G), Inf) self.assertEqual(mult(ec, 1, ec.G), ec.G) self.assertEqual(mult(ec, 1, ec.G), ec.G) Gy_odd = ec.y_odd(ec.G[0], True) self.assertEqual(Gy_odd % 2, 1) Gy_even = ec.y_odd(ec.G[0], False) self.assertEqual(Gy_even % 2, 0) self.assertTrue(ec.G[1] in (Gy_odd, Gy_even)) Gbytes = octets_from_point(ec, ec.G, True) G2 = point_from_octets(ec, Gbytes) self.assertEqual(ec.G, G2) Gbytes = octets_from_point(ec, ec.G, False) G2 = point_from_octets(ec, Gbytes) self.assertEqual(ec.G, G2) P = ec.add(Inf, ec.G) self.assertEqual(P, ec.G) P = ec.add(ec.G, Inf) self.assertEqual(P, ec.G) P = ec.add(Inf, Inf) self.assertEqual(P, Inf) P = ec.add(ec.G, ec.G) self.assertEqual(P, mult(ec, 2, ec.G)) P = mult(ec, ec.n-1, ec.G) self.assertEqual(ec.add(P, ec.G), Inf) self.assertEqual(mult(ec, ec.n, ec.G), Inf) self.assertEqual(mult(ec, 0, Inf), Inf) self.assertEqual(mult(ec, 1, Inf), Inf) self.assertEqual(mult(ec, 25, Inf), Inf) ec_repr = repr(ec) if ec in low_card_curves or ec.psize < 24: ec_repr = ec_repr[:-1] + ", False)" ec2 = eval(ec_repr) self.assertEqual(str(ec), str(ec2))
def address_from_xpub(xpub: octets, version: Optional[octets] = None) -> bytes: xpub = base58.decode_check(xpub, 78) if xpub[45] not in (2, 3): raise ValueError("extended key is not a public one") # bitcoin: address version can be derived from xkey version # altcoin: address version cannot be derived from xkey version # if xkey version bytes have not been specialized # FIXME use BIP44 here if version is None: xversion = xpub[:4] i = PUB.index(xversion) version = ADDRESS[i] P = point_from_octets(ec, xpub[45:]) return address_from_pubkey(P, True, version)
def test_address_from_pubkey(self): # https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses prv = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 pub = mult(ec, prv) self.assertEqual( pub, point_from_octets( ec, '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352' )) addr = p2pkh_address(pub, True) self.assertEqual(addr, b'1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs') _h160_from_address(addr) addr = p2pkh_address(pub, False) self.assertEqual(addr, b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM') _h160_from_address(addr) # not a mainnet address addr = p2pkh_address(pub, False, b'\x80') self.assertRaises(ValueError, _h160_from_address, addr)
def test_octets2point(self): for ec in all_curves: Q = mult(ec, ec._p, ec.G) # just a random point, not Inf Q_bytes = b'\x03' if Q[1] & 1 else b'\x02' Q_bytes += Q[0].to_bytes(ec.psize, "big") R = point_from_octets(ec, Q_bytes) self.assertEqual(R, Q) self.assertEqual(octets_from_point(ec, R, True), Q_bytes) Q_hex_str = Q_bytes.hex() R = point_from_octets(ec, Q_hex_str) self.assertEqual(R, Q) Q_bytes = b'\x04' + Q[0].to_bytes(ec.psize, "big") Q_bytes += Q[1].to_bytes(ec.psize, "big") R = point_from_octets(ec, Q_bytes) self.assertEqual(R, Q) self.assertEqual(octets_from_point(ec, R, False), Q_bytes) Q_hex_str = Q_bytes.hex() R = point_from_octets(ec, Q_hex_str) self.assertEqual(R, Q) # infinity point self.assertEqual(point_from_octets(ec, b'\x00'), Inf) self.assertEqual(octets_from_point(ec, Inf, True), b'\x00') self.assertEqual(octets_from_point(ec, Inf, False), b'\x00') Inf_hex_str = b'\x00'.hex() self.assertEqual(point_from_octets(ec, Inf_hex_str), Inf) # scalar in point multiplication can be int, str, or bytes t = tuple() self.assertRaises(TypeError, mult, ec, t, ec.G) # not a compressed point Q_bytes = b'\x01' * (ec.psize+1) self.assertRaises(ValueError, point_from_octets, ec, Q_bytes) # not a point Q_bytes += b'\x01' self.assertRaises(ValueError, point_from_octets, ec, Q_bytes) # not an uncompressed point Q_bytes = b'\x01' * 2 * (ec.psize+1) self.assertRaises(ValueError, point_from_octets, ec, Q_bytes) # invalid x coordinate ec = secp256k1 x = 0xEEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34 xstr = format(x, '32X') self.assertRaises(ValueError, point_from_octets, ec, "03" + xstr) self.assertRaises(ValueError, point_from_octets, ec, "04" + xstr + xstr) self.assertRaises(ValueError, octets_from_point, ec, (x, x), True) self.assertRaises(ValueError, octets_from_point, ec, (x, x), False) # Point must be a tuple[int, int] P = x, x, x self.assertRaises(ValueError, ec.is_on_curve, P) # y-coordinate not in (0, p) P = x, ec._p+1 self.assertRaises(ValueError, ec.is_on_curve, P)
def ckd(xparentkey: octets, index: Union[octets, int]) -> bytes: """Child Key Derivation (CDK) Key derivation is normal if the extended parent key is public or child_index is less than 0x80000000. Key derivation is hardened if the extended parent key is private and child_index is not less than 0x80000000. """ if isinstance(index, int): index = index.to_bytes(4, 'big') elif isinstance(index, str): # hex string index = bytes.fromhex(index) if len(index) != 4: raise ValueError(f"a 4 bytes int is required, not {len(index)}") xparent = base58.decode_check(xparentkey, 78) version = xparent[:4] # serialization data xkey = version # version xkey += (xparent[4] + 1).to_bytes(1, 'big') # (increased) depth if (version in PUB): if xparent[45] not in (2, 3): # not a compressed public key raise ValueError("version/key mismatch in extended parent key") Parent_bytes = xparent[45:] Parent = point_from_octets(ec, Parent_bytes) xkey += _h160(Parent_bytes)[:4] # parent pubkey fingerprint if index[0] >= 0x80: raise ValueError("no private/hardened derivation from pubkey") xkey += index # child index parent_chain_code = xparent[13:45] # normal derivation # actual extended key (key + chain code) derivation h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest() offset = int.from_bytes(h[:32], 'big') Offset = mult(ec, offset, ec.G) Child = ec.add(Parent, Offset) Child_bytes = octets_from_point(ec, Child, True) xkey += h[32:] # chain code xkey += Child_bytes # public key elif (version in PRV): if xparent[45] != 0: # not a private key raise ValueError("version/key mismatch in extended parent key") parent = int.from_bytes(xparent[46:], 'big') Parent = mult(ec, parent, ec.G) Parent_bytes = octets_from_point(ec, Parent, True) xkey += _h160(Parent_bytes)[:4] # parent pubkey fingerprint xkey += index # child index # actual extended key (key + chain code) derivation parent_chain_code = xparent[13:45] if (index[0] < 0x80): # normal derivation h = HMAC(parent_chain_code, Parent_bytes + index, sha512).digest() else: # hardened derivation h = HMAC(parent_chain_code, xparent[45:] + index, sha512).digest() offset = int.from_bytes(h[:32], 'big') child = (parent + offset) % ec.n child_bytes = b'\x00' + child.to_bytes(32, 'big') xkey += h[32:] # chain code xkey += child_bytes # private key else: raise ValueError("invalid extended key version") return base58.encode_check(xkey)
def test_second_generator(self): """ important remark on secp256-zkp prefix for compressed encoding of the second generator: https://github.com/garyyu/rust-secp256k1-zkp/wiki/Pedersen-Commitment """ ec = secp256k1 hf = sha256 H = pedersen.second_generator(ec, hf) self.assertEqual( H, point_from_octets( '0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', ec)) # 0*G + 1*H T = double_mult(1, H, 0, ec.G, ec) self.assertEqual( T, point_from_octets( '0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', ec)) # 0*G + 2*H T = double_mult(2, H, 0, ec.G, ec) self.assertEqual( T, point_from_octets( '03fad265e0a0178418d006e247204bcf42edb6b92188074c9134704c8686eed37a', ec)) T = mult(2, H, ec) self.assertEqual( T, point_from_octets( '03fad265e0a0178418d006e247204bcf42edb6b92188074c9134704c8686eed37a', ec)) # 0*G + 3*H T = double_mult(3, H, 0, ec.G, ec) self.assertEqual( T, point_from_octets( '025ef47fcde840a435e831bbb711d466fc1ee160da3e15437c6c469a3a40daacaa', ec)) T = mult(3, H, ec) self.assertEqual( T, point_from_octets( '025ef47fcde840a435e831bbb711d466fc1ee160da3e15437c6c469a3a40daacaa', ec)) # 1*G+0*H T = double_mult(0, H, 1, ec.G, ec) self.assertEqual( T, point_from_octets( '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', ec)) T = ec.G self.assertEqual( T, point_from_octets( '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', ec)) # 2*G+0*H T = double_mult(0, H, 2, ec.G, ec) self.assertEqual( T, point_from_octets( '02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5', ec)) T = mult(2, ec.G, ec) self.assertEqual( T, point_from_octets( '02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5', ec)) # 3*G+0*H T = double_mult(0, H, 3, ec.G, ec) self.assertEqual( T, point_from_octets( '02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', ec)) T = mult(3, ec.G, ec) self.assertEqual( T, point_from_octets( '02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', ec)) # 0*G+5*H T = double_mult(5, H, 0, ec.G, ec) self.assertEqual( T, point_from_octets( '039e431be0851721f9ce35cc0f718fce7d6d970e3ddd796643d71294d7a09b554e', ec)) T = mult(5, H, ec) self.assertEqual( T, point_from_octets( '039e431be0851721f9ce35cc0f718fce7d6d970e3ddd796643d71294d7a09b554e', ec)) # 0*G-5*H T = double_mult(-5, H, 0, ec.G, ec) self.assertEqual( T, point_from_octets( '029e431be0851721f9ce35cc0f718fce7d6d970e3ddd796643d71294d7a09b554e', ec)) T = mult(-5, H, ec) self.assertEqual( T, point_from_octets( '029e431be0851721f9ce35cc0f718fce7d6d970e3ddd796643d71294d7a09b554e', ec)) # 1*G-5*H U = double_mult(-5, H, 1, ec.G, ec) self.assertEqual( U, point_from_octets( '02b218ddacb34d827c71760e601b41d309bc888cf7e3ab7cc09ec082b645f77e5a', ec)) U = ec.add(ec.G, T) # reusing previous T value self.assertEqual( U, point_from_octets( '02b218ddacb34d827c71760e601b41d309bc888cf7e3ab7cc09ec082b645f77e5a', ec)) H = pedersen.second_generator(secp256r1, hf) H = pedersen.second_generator(secp384r1, sha384)
def test_schnorr_bip_tv(self): """Bip-Schnorr Test Vectors https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki """ hf = sha256 # test vector 1 prv = int_from_bits(b'\x00' * 31 + b'\x01') pub = mult(prv) msg = b'\x00' * 32 expected_sig = ( 0x787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF6, 0x7031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05) eph_prv = int.from_bytes(hf(prv.to_bytes(32, byteorder='big') + msg).digest(), byteorder='big') sig = ssa.sign(msg, prv, eph_prv) self.assertTrue(ssa._verify(msg, pub, sig)) self.assertEqual(sig, expected_sig) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # test vector 2 prv = 0xB7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF pub = mult(prv) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") expected_sig = ( 0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D, 0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD) eph_prv = int.from_bytes(hf(prv.to_bytes(32, byteorder='big') + msg).digest(), byteorder='big') sig = ssa.sign(msg, prv, eph_prv) self.assertTrue(ssa._verify(msg, pub, sig)) self.assertEqual(sig, expected_sig) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # test vector 3 prv = 0xC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7 pub = mult(prv) msg = bytes.fromhex( "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C") expected_sig = ( 0x00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE, 0x00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380) eph_prv = int.from_bytes(hf(prv.to_bytes(32, byteorder='big') + msg).digest(), byteorder='big') sig = ssa.sign(msg, prv, eph_prv) self.assertTrue(ssa._verify(msg, pub, sig)) self.assertEqual(sig, expected_sig) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # test vector 4 pub = point_from_octets( "03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34" ) msg = bytes.fromhex( "4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703") sig = ( 0x00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C63, 0x02A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D) self.assertTrue(ssa._verify(msg, pub, sig)) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # test vector 5 # test would fail if jacobi symbol of x(R) instead of y(R) is used pub = point_from_octets( "031B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F" ) msg = bytes.fromhex( "0000000000000000000000000000000000000000000000000000000000000000") sig = ( 0x52818579ACA59767E3291D91B76B637BEF062083284992F2D95F564CA6CB4E35, 0x30B1DA849C8E8304ADC0CFE870660334B3CFC18E825EF1DB34CFAE3DFC5D8187) self.assertTrue(ssa._verify(msg, pub, sig)) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # test vector 6 # test would fail if msg is reduced pub = point_from_octets( "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B" ) msg = bytes.fromhex( "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") sig = ( 0x570DD4CA83D4E6317B8EE6BAE83467A1BF419D0767122DE409394414B05080DC, 0xE9EE5F237CBD108EABAE1E37759AE47F8E4203DA3532EB28DB860F33D62D49BD) self.assertTrue(ssa._verify(msg, pub, sig)) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # new proposed test: test would fail if msg is reduced pub = point_from_octets( "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B" ) msg = bytes.fromhex( "000008D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A5000000") sig = ( 0x3598678C6C661F02557E2F5614440B53156997936FE54A90961CFCC092EF789D, 0x41E4E4386E54C924251679ADD3D837367EECBFF248A3DE7C2DB4CE52A3D6192A) self.assertTrue(ssa._verify(msg, pub, sig)) e = ssa._e(sig[0], pub, msg) self.assertEqual(ssa._pubkey_recovery(e, sig), pub) # new proposed test: genuine failure pub = point_from_octets( "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B" ) msg = bytes.fromhex( "0000000000000000000000000000000000000000000000000000000000000000") sig = ( 0x3598678C6C661F02557E2F5614440B53156997936FE54A90961CFCC092EF789D, 0x41E4E4386E54C924251679ADD3D837367EECBFF248A3DE7C2DB4CE52A3D6192A) self.assertFalse(ssa._verify(msg, pub, sig)) # new proposed test: P = infinite pub = 1, 0 msg = bytes.fromhex( "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C") sig = ( 0x00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE, 0x00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 7 # public key not on the curve # impossible to verify with btclib analytics as it at Point conversion self.assertRaises( ValueError, point_from_octets, "03EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34" ) # msg = bytes.fromhex("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703") # sig = (0x00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C63, 0x02A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D) # self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 8 # Incorrect sig: incorrect R residuosity pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D, 0xFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 9 # Incorrect sig: negated message hash pub = point_from_octets( "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B" ) msg = bytes.fromhex( "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C") sig = ( 0x00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE, 0xD092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 10 # Incorrect sig: negated s value pub = point_from_octets( "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" ) msg = b'\x00' * 32 sig = ( 0x787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF6, 0x8FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 11 # Incorrect sig: negated public key pub = point_from_octets( "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D, 0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 12 # sG - eP is infinite. # Test fails in single verification if jacobi(y(inf)) is defined as 1 and x(inf) as 0 pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x0000000000000000000000000000000000000000000000000000000000000000, 0x9E9D01AF988B5CEDCE47221BFA9B222721F3FA408915444A4B489021DB55775F) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 13 # sG - eP is infinite. # Test fails in single verification if jacobi(y(inf)) is defined as 1 and x(inf) as 1""" pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x0000000000000000000000000000000000000000000000000000000000000001, 0xD37DDF0254351836D84B1BD6A795FD5D523048F298C4214D187FE4892947F728) self.assertRaises(ValueError, ssa._verify, msg, pub, sig) # test vector 14 # sig[0:32] is not an X coordinate on the curve pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D, 0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD) self.assertFalse(ssa._verify(msg, pub, sig)) # test vector 15 # sig[0:32] is equal to field size pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2F, 0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD) #self.assertRaises(ValueError, ssa._verify, msg, pub, sig) self.assertFalse(ssa._verify(msg, pub, sig)) # test vector 16 # sig[32:64] is equal to curve order pub = point_from_octets( "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" ) msg = bytes.fromhex( "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") sig = ( 0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141) self.assertRaises(ValueError, ssa._verify, msg, pub, sig)