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)
示例#2
0
    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")
示例#3
0
    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')
示例#4
0
    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)
示例#6
0
    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)
示例#7
0
    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)
示例#9
0
    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)
示例#10
0
    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)