コード例 #1
0
    def test_ecssa(self):
        prv = 0x1
        pub = ec.pointMultiply(prv, ec.G)
        msg = 'Satoshi Nakamoto'

        ssasig = ecssa_sign(msg, prv)
        self.assertTrue(ecssa_verify(msg, ssasig, pub))
        # malleability
        malleated_sig = (ssasig[0], ec.order - ssasig[1])
        self.assertFalse(ecssa_verify(msg, malleated_sig, pub))

        self.assertEqual(ecssa_pubkey_recovery(msg, ssasig), pub)
コード例 #2
0
    def test_ecssa_4(self):
        pub = tuple_from_Point(ec, "03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34")
        msg = bytes.fromhex("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703")
        sig = (0x00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C63,
               0x02A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D)

        self.assertTrue(ecssa_verify(msg, sig, pub))
        # malleability
        self.assertFalse(ecssa_verify(msg, (sig[0], ec.n - sig[1]), pub))
        e = sha256(sig[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, pub, True) +
                   msg).digest()
        self.assertEqual(ecssa_pubkey_recovery(e, sig), pub)
コード例 #3
0
    def test_ecssa_7(self):
        """Incorrect sig: negated s value"""
        pub = tuple_from_Point(ec, "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")
        msg = b'\x00' * 32
        sig = (0x787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF6,
               0x8FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C)

        self.assertFalse(ecssa_verify(msg, sig, pub))
コード例 #4
0
    def test_ecssa_6(self):
        """Incorrect sig: negated message hash"""
        pub = tuple_from_Point(ec, "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B")
        msg = bytes.fromhex("5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C")
        sig = (0x00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE,
               0xD092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC)

        self.assertFalse(ecssa_verify(msg, sig, pub))
コード例 #5
0
    def test_ecssa_5(self):
        """Incorrect sig: incorrect R residuosity"""
        pub = tuple_from_Point(ec, "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
        msg = bytes.fromhex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
        sig = (0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D,
               0xFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7)

        self.assertFalse(ecssa_verify(msg, sig, pub))
コード例 #6
0
    def test_ecssa_3(self):
        prv = 0xC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7
        pub = ec.pointMultiply(prv, ec.G)
        msg = bytes.fromhex("5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C")
        expected_sig = (0x00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE,
                        0x00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380)
        eph_prv = int.from_bytes(sha256(prv.to_bytes(32, byteorder="big") + msg).digest(), byteorder="big")

        sig = ecssa_sign(msg, prv, eph_prv)
        self.assertTrue(ecssa_verify(msg, sig, pub))
        # malleability
        self.assertFalse(ecssa_verify(msg, (sig[0], ec.n - sig[1]), pub))
        self.assertEqual(sig, expected_sig)
        e = sha256(sig[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, pub, True) +
                   msg).digest()
        self.assertEqual(ecssa_pubkey_recovery(e, sig), pub)
コード例 #7
0
    def test_ecssa_2(self):
        prv = 0xB7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF
        pub = ec.pointMultiply(prv, ec.G)
        msg = bytes.fromhex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
        expected_sig = (0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D,
                        0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD)
        eph_prv = int.from_bytes(sha256(prv.to_bytes(32, byteorder="big") + msg).digest(), byteorder="big")

        sig = ecssa_sign(msg, prv, eph_prv)
        self.assertTrue(ecssa_verify(msg, sig, pub))
        # malleability
        self.assertFalse(ecssa_verify(msg, (sig[0], ec.n - sig[1]), pub))
        self.assertEqual(sig, expected_sig)
        e = sha256(sig[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, pub, True) +
                   msg).digest()
        self.assertEqual(ecssa_pubkey_recovery(e, sig), pub)
コード例 #8
0
    def test_ecssa_8(self):
        """Incorrect sig: negated public key"""
        pub = tuple_from_Point(ec, "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
        msg = bytes.fromhex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
        sig = (0x2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D,
               0x1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD)

        self.assertFalse(ecssa_verify(msg, sig, pub))
コード例 #9
0
    def test_ecssa_1(self):
        prv = 0x1
        pub = ec.pointMultiply(prv, ec.G)
        msg = b'\x00' * 32
        expected_sig = (0x787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF6,
                        0x7031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05)
        eph_prv = int.from_bytes(sha256(prv.to_bytes(32, byteorder="big") + msg).digest(), byteorder="big")

        sig = ecssa_sign(msg, prv, eph_prv)
        self.assertTrue(ecssa_verify(msg, sig, pub))
        # malleability
        self.assertFalse(ecssa_verify(msg, (sig[0], ec.n - sig[1]), pub))
        self.assertEqual(sig, expected_sig)
        e = sha256(sig[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, pub, True) +
                   msg).digest()
        self.assertEqual(ecssa_pubkey_recovery(e, sig), pub)
コード例 #10
0
    def test_ecssamusig(self):
        msg = 'message to sign'
        m = sha256(msg.encode()).digest()

        # first signer (is the message needed here? maybe for rfc6979?)
        prv1 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d92ad1d')
        Q1 = ec.pointMultiply(prv1, ec.G)
        HQ1 = int_from_hash(
            sha256(bytes_from_Point(ec, Q1, False)).digest(), ec.order)
        prv1 = HQ1 * prv1

        eph_prv1 = 0x012a2a833eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbb
        R1 = ec.pointMultiply(eph_prv1, ec.G)
        if R1[1] % 2 == 1:  #must be even
            eph_prv1 = ec.order - eph_prv1
            R1 = ec.pointMultiply(eph_prv1, ec.G)
        R1_x = R1[0]

        # second signer (is the message needed here? maybe for rfc6979?)
        prv2 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')
        Q2 = ec.pointMultiply(prv2, ec.G)
        HQ2 = int_from_hash(
            sha256(bytes_from_Point(ec, Q2, False)).digest(), ec.order)
        prv2 = HQ2 * prv2

        eph_prv2 = 0x01a2a0d3eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbdb
        R2 = ec.pointMultiply(eph_prv2, ec.G)
        if R2[1] % 2 == 1:  #must be even
            eph_prv2 = ec.order - eph_prv2
            R2 = ec.pointMultiply(eph_prv2, ec.G)
        R2_x = R2[0]

        ######################
        # exchange Rx, compute s
        ######################

        # first signer use R2_x
        R2_y_recovered = ec.y(R2_x, 0)
        R2_recovered = (R2_x, R2_y_recovered)
        R1_All = ec.pointAdd(R1, R2_recovered)
        if R1_All[1] % 2 == 1:  # must be even
            eph_prv1 = ec.order - eph_prv1
        R1_All_x = R1_All[0].to_bytes(32, 'big')
        e1 = int_from_hash(sha256(R1_All_x + m).digest(), ec.order)
        assert e1 != 0 and e1 < ec.order, "sign fail"
        s1 = (eph_prv1 - e1 * prv1) % ec.order

        # second signer use R1_x
        R1_y_recovered = ec.y(R1_x, 0)
        R1_recovered = (R1_x, R1_y_recovered)
        R2_All = ec.pointAdd(R2, R1_recovered)
        if R2_All[1] % 2 == 1:
            eph_prv2 = ec.order - eph_prv2
        R2_All_x = R2_All[0].to_bytes(32, 'big')
        e2 = int_from_hash(sha256(R2_All_x + m).digest(), ec.order)
        assert e2 != 0 and e2 < ec.order, "sign fail"
        s2 = (eph_prv2 - e2 * prv2) % ec.order

        ######################
        # combine signatures into a single signature
        ######################

        # anyone can do the following
        assert R1_All_x == R2_All_x, "sign fail"
        R_All_x = R1_All[0]
        s_All = (s1 + s2) % ec.order
        ssasig = (R_All_x, s_All)
        Q_All = ec.pointAdd(ec.pointMultiply(HQ1, Q1),
                            ec.pointMultiply(HQ2, Q2))

        self.assertTrue(ecssa_verify(msg, ssasig, Q_All, sha256))
コード例 #11
0
    def test_ecssamusig(self):
        msg = 'message to sign'
        m = sha256(msg.encode()).digest()

        # first signer (is the message needed here? maybe for rfc6979?)
        prv1 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d92ad1d')
        Q1 = ec.pointMultiply(prv1, ec.G)
        HQ1 = int_from_hash(
            sha256(bytes_from_Point(ec, Q1, False)).digest(), ec.n)
        prv1 = HQ1 * prv1

        eph_prv1 = 0x012a2a833eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbb
        R1 = ec.pointMultiply(eph_prv1, ec.G)
        R1_x = R1[0]
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R1[1]) != 1:
            eph_prv1 = ec.n - eph_prv1
            R1 = R1_x, ec.yQuadraticResidue(R1_x, True)
            #R1 = ec.pointMultiply(eph_prv1, ec.G)

        # second signer (is the message needed here? maybe for rfc6979?)
        prv2 = int_from_Scalar(
            ec,
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')
        Q2 = ec.pointMultiply(prv2, ec.G)
        HQ2 = int_from_hash(
            sha256(bytes_from_Point(ec, Q2, False)).digest(), ec.n)
        prv2 = HQ2 * prv2

        eph_prv2 = 0x01a2a0d3eac4e67e06611aba01345b85cdd4f5ad44f72e369ef0dd640424dbdb
        R2 = ec.pointMultiply(eph_prv2, ec.G)
        R2_x = R2[0]
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R2[1]) != 1:
            eph_prv2 = ec.n - eph_prv2
            R2 = R2_x, ec.yQuadraticResidue(R2_x, True)
            #R2 = ec.pointMultiply(eph_prv2, ec.G)

        Q_All = ec.pointAdd(ec.pointMultiply(HQ1, Q1),
                            ec.pointMultiply(HQ2, Q2))  # joint public key

        ########################
        # exchange Rx, compute s

        # first signer use R2_x
        # break the simmetry: any criteria could be used, jacobi is standard
        y = ec.yQuadraticResidue(R2_x, True)
        R2_recovered = (R2_x, y)
        R1_All = ec.pointAdd(R1, R2_recovered)
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R1_All[1]) != 1:
            # no need to actually change R1_All[1], as it is not used anymore
            # let's fix eph_prv1 instead, as it is used later
            eph_prv1 = ec.n - eph_prv1
        e1 = int_from_hash(
            sha256(R1_All[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, Q_All, True) + m).digest(), ec.n)
        assert e1 != 0 and e1 < ec.n, "sign fail"
        s1 = (eph_prv1 + e1 * prv1) % ec.n

        # second signer use R1_x
        # break the simmetry: any criteria could be used, jacobi is standard
        y = ec.yQuadraticResidue(R1_x, True)
        R1_recovered = (R1_x, y)
        R2_All = ec.pointAdd(R2, R1_recovered)
        # break the simmetry: any criteria could be used, jacobi is standard
        if ec.jacobi(R2_All[1]) != 1:
            # no need to actually change R2_All[1], as it is not used anymore
            # let's fix eph_prv2 instead, as it is used later
            eph_prv2 = ec.n - eph_prv2
        e2 = int_from_hash(
            sha256(R2_All[0].to_bytes(32, byteorder="big") +
                   bytes_from_Point(ec, Q_All, True) + m).digest(), ec.n)
        assert e2 != 0 and e2 < ec.n, "sign fail"
        s2 = (eph_prv2 + e2 * prv2) % ec.n

        ############################################
        # combine signatures into a single signature

        # anyone can do the following
        assert R1_All[0] == R2_All[0], "sign fail"
        s_All = (s1 + s2) % ec.n
        ssasig = (R1_All[0], s_All)

        self.assertTrue(ecssa_verify(msg, ssasig, Q_All, sha256))