Пример #1
0
    def test_crack_prvkey(self):
        q = 0x6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725DEADBEEF
        x_Q = mult(q)[0]
        k = 1010101010101010101

        msg1 = "Paolo is afraid of ephemeral random numbers"
        msg1 = hf(msg1.encode()).digest()
        sig1 = ssa.sign(msg1, q, k)
        # print(f'\nmsg1: {msg1.hex().upper()}')
        # print(f'  r1: {hex(sig1[0]).upper()}')
        # print(f'  s1: {hex(sig1[1]).upper()}')

        msg2 = "and Paolo is right to be afraid"
        msg2 = hf(msg2.encode()).digest()
        sig2 = ssa.sign(msg2, q, k)
        # print(f'\nmsg2: {msg2.hex().upper()}')
        # print(f'  r2: {hex(sig2[0]).upper()}')
        # print(f'  s2: {hex(sig2[1]).upper()}')

        qc, kc = ssa.crack_prvkey(msg1, sig1, msg2, sig2, x_Q)
        self.assertIn(q, (qc, ec.n - qc))
        self.assertIn(k, (kc, ec.n - kc))

        self.assertRaises(ValueError, ssa.crack_prvkey, msg1, sig1, msg2,
                          (16, sig1[1]), x_Q)
        self.assertRaises(ValueError, ssa.crack_prvkey, msg1, sig1, msg1, sig1,
                          x_Q)
Пример #2
0
def test_crack_prvkey():

    ec = secp256k1

    q = 0x19E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
    x_Q = mult(q)[0]

    msg1 = "Paolo is afraid of ephemeral random numbers"
    msg1 = hf(msg1.encode()).digest()
    k = ssa.k(msg1, q)
    sig1 = ssa.sign(msg1, q, k)

    msg2 = "and Paolo is right to be afraid"
    msg2 = hf(msg2.encode()).digest()
    # reuse same k
    sig2 = ssa.sign(msg2, q, k)

    qc, kc = ssa.crack_prvkey(msg1, sig1, msg2, sig2, x_Q)
    assert q in (qc, ec.n - qc)
    assert k in (kc, ec.n - kc)

    with pytest.raises(ValueError, match="not the same r in signatures"):
        ssa.crack_prvkey(msg1, sig1, msg2, (16, sig1[1]), x_Q)

    with pytest.raises(ValueError, match="identical signatures"):
        ssa.crack_prvkey(msg1, sig1, msg1, sig1, x_Q)
Пример #3
0
def test_batch_validation() -> None:

    ms: List[String] = []
    Qs: List[int] = []
    sigs: List[ssa.SSASig] = []
    err_msg = "no signatures provided"
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert not ssa.batch_verify(ms, Qs, sigs)

    # valid size for String input to sign, not for Octets input to _sign
    msg_size = 16
    ms.append(secrets.token_bytes(msg_size))
    q, Q = ssa.gen_keys()
    Qs.append(Q)
    sigs.append(ssa.sign(ms[0], q))
    # test with only 1 sig
    ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert ssa.batch_verify(ms, Qs, sigs)
    for _ in range(3):
        m = secrets.token_bytes(msg_size)
        ms.append(m)
        q, Q = ssa.gen_keys()
        Qs.append(Q)
        sigs.append(ssa.sign(m, q))
    ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert ssa.batch_verify(ms, Qs, sigs)

    ms.append(ms[0])
    sigs.append(sigs[1])
    Qs.append(Qs[0])
    err_msg = "signature verification failed"
    with pytest.raises(BTClibRuntimeError, match=err_msg):
        ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert not ssa.batch_verify(ms, Qs, sigs)
    sigs[-1] = sigs[0]  # valid again

    ms.append(ms[0])  # add extra message
    err_msg = "mismatch between number of pubkeys "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert not ssa.batch_verify(ms, Qs, sigs)
    ms.pop()  # valid again

    sigs.append(sigs[0])  # add extra sig
    err_msg = "mismatch between number of pubkeys "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_batch_as_valid(ms, Qs, sigs)
    assert not ssa.batch_verify(ms, Qs, sigs)
    sigs.pop()  # valid again

    ms = [reduce_to_hlen(m, hf) for m in ms]
    ms[0] = ms[0][:-1]
    err_msg = "invalid size: 31 bytes instead of 32"
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa._assert_batch_as_valid(ms, Qs, sigs)
    assert not ssa._batch_verify(ms, Qs, sigs)
Пример #4
0
def test_batch_validation():

    ec = secp256k1

    hsize = hf().digest_size
    hlen = hsize * 8

    ms = []
    Qs = []
    sigs = []
    ms.append(secrets.randbits(hlen).to_bytes(hsize, "big"))
    q = 1 + secrets.randbelow(ec.n - 1)
    # bytes version
    Qs.append(mult(q, ec.G, ec)[0].to_bytes(ec.psize, "big"))
    sigs.append(ssa.sign(ms[0], q, None, ec, hf))
    # test with only 1 sig
    ssa._batch_verify(ms, Qs, sigs, ec, hf)
    for _ in range(3):
        mhd = secrets.randbits(hlen).to_bytes(hsize, "big")
        ms.append(mhd)
        q = 1 + secrets.randbelow(ec.n - 1)
        # Point version
        Qs.append(mult(q, ec.G, ec))
        sigs.append(ssa.sign(mhd, q, None, ec, hf))
    ssa._batch_verify(ms, Qs, sigs, ec, hf)
    assert ssa.batch_verify(ms, Qs, sigs, ec, hf)

    ms.append(ms[0])
    sigs.append(sigs[1])
    Qs.append(Qs[0])
    assert not ssa.batch_verify(ms, Qs, sigs, ec, hf)
    err_msg = "signature verification precondition failed"
    with pytest.raises(ValueError, match=err_msg):
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
    sigs[-1] = sigs[0]  # valid again

    ms[-1] = ms[0][:-1]
    err_msg = "invalid size: 31 bytes instead of 32"
    with pytest.raises(ValueError, match=err_msg):
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
    ms[-1] = ms[0]  # valid again

    ms.append(ms[0])  # add extra message
    err_msg = "mismatch between number of pubkeys "
    with pytest.raises(ValueError, match=err_msg):
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
    ms.pop()  # valid again

    sigs.append(sigs[0])  # add extra sig
    err_msg = "mismatch between number of pubkeys "
    with pytest.raises(ValueError, match=err_msg):
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
    sigs.pop()  # valid again

    err_msg = "field prime is not equal to 3 mod 4: "
    with pytest.raises(ValueError, match=err_msg):
        ssa._batch_verify(ms, Qs, sigs, secp224k1, hf)
Пример #5
0
    def test_batch_validation(self):
        hsize = hf().digest_size
        hlen = hsize * 8

        ms = []
        Qs = []
        sigs = []
        ms.append(secrets.randbits(hlen).to_bytes(hsize, 'big'))
        q = 1 + secrets.randbelow(ec.n - 1)
        # bytes version
        Qs.append(mult(q, ec.G, ec)[0].to_bytes(ec.psize, 'big'))
        sigs.append(ssa.sign(ms[0], q, None, ec, hf))
        # test with only 1 sig
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
        for _ in range(3):
            mhd = secrets.randbits(hlen).to_bytes(hsize, 'big')
            ms.append(mhd)
            q = 1 + secrets.randbelow(ec.n - 1)
            # Point version
            Qs.append(mult(q, ec.G, ec))
            sigs.append(ssa.sign(mhd, q, None, ec, hf))
        ssa._batch_verify(ms, Qs, sigs, ec, hf)
        self.assertTrue(ssa.batch_verify(ms, Qs, sigs, ec, hf))

        # invalid sig
        ms.append(ms[0])
        sigs.append(sigs[1])
        Qs.append(Qs[0])
        self.assertFalse(ssa.batch_verify(ms, Qs, sigs, ec, hf))
        self.assertRaises(AssertionError, ssa._batch_verify, ms, Qs, sigs, ec,
                          hf)
        # ssa._batch_verify(ms, Qs, sigs, ec, hf)
        sigs[-1] = sigs[0]  # valid again

        # Invalid size: 31 bytes instead of 32
        ms[-1] = ms[0][:-1]
        self.assertRaises(ValueError, ssa._batch_verify, ms, Qs, sigs, ec, hf)
        # ssa._batch_verify(ms, Qs, sigs, ec, hf)
        ms[-1] = ms[0]  # valid again

        # mismatch between number of pubkeys (5) and number of messages (6)
        ms.append(ms[0])  # add extra message
        self.assertRaises(ValueError, ssa._batch_verify, ms, Qs, sigs, ec, hf)
        # ssa._batch_verify(ms, Qs, sigs, ec, hf)
        ms.pop()  # valid again

        # mismatch between number of pubkeys (5) and number of signatures (6)
        sigs.append(sigs[0])  # add extra sig
        self.assertRaises(ValueError, ssa._batch_verify, ms, Qs, sigs, ec, hf)
        # ssa._batch_verify(ms, Qs, sigs, ec, hf)
        sigs.pop()  # valid again

        # field prime p is not equal to 3 (mod 4)
        self.assertRaises(ValueError, ssa._batch_verify, ms, Qs, sigs,
                          secp224k1, hf)
Пример #6
0
    def test_batch_validation(self):
        ec = secp256k1
        hf = sha256
        m = []
        sig = []
        Q = []

        hsize = hf().digest_size
        hlen = hsize * 8
        m.append(random.getrandbits(hlen).to_bytes(hsize, byteorder='big'))
        q = (1 + random.getrandbits(ec.nlen)) % ec.n
        sig.append(ssa.sign(m[0], q, None, ec, hf))
        Q.append(mult(q, ec.G, ec))
        # test with only 1 sig
        self.assertTrue(ssa.batch_verify(m, Q, sig, ec, hf))
        for i in range(1, 4):
            m.append(random.getrandbits(hlen).to_bytes(hsize, byteorder='big'))
            q = (1 + random.getrandbits(ec.nlen)) % ec.n
            sig.append(ssa.sign(m[i], q, None, ec, hf))
            Q.append(mult(q, ec.G, ec))
        self.assertTrue(ssa.batch_verify(m, Q, sig, ec, hf))

        # invalid sig
        m.append(m[0])
        sig.append(sig[1])
        Q.append(Q[0])
        self.assertFalse(ssa.batch_verify(m, Q, sig, ec, hf))
        #ssa._batch_verify(m, Q, sig, ec, hf)
        sig[-1] = sig[0]  # valid again

        # invalid 31 bytes message
        m[-1] = m[0][:-1]
        self.assertFalse(ssa.batch_verify(m, Q, sig, ec, hf))
        #ssa._batch_verify(m, Q, sig, ec, hf)
        m[-1] = m[0]  # valid again

        # mismatch between number of pubkeys and number of messages
        m.append(m[0])  # add extra message
        self.assertRaises(ValueError, ssa._batch_verify, m, Q, sig, ec, hf)
        #ssa._batch_verify(m, Q, sig, ec, hf)
        m.pop()  # valid again

        # mismatch between number of pubkeys and number of signatures
        sig.append(sig[0])  # add extra sig
        self.assertRaises(ValueError, ssa._batch_verify, m, Q, sig, ec, hf)
        #ssa._batch_verify(m, Q, sig, ec, hf)
        sig.pop()  # valid again

        # curve prime p must be equal to 3 (mod 4)
        ec = secp224k1
        self.assertRaises(ValueError, ssa._batch_verify, m, Q, sig, ec, hf)
Пример #7
0
def test_low_cardinality():
    """test low-cardinality curves for all msg/key pairs."""

    # ec.n has to be prime to sign
    test_curves = [
        low_card_curves["ec13_11"],
        low_card_curves["ec13_19"],
        low_card_curves["ec17_13"],
        low_card_curves["ec17_23"],
        low_card_curves["ec19_13"],
        low_card_curves["ec19_23"],
        low_card_curves["ec23_19"],
        low_card_curves["ec23_31"],
    ]

    # only low cardinality test curves or it would take forever
    for ec in test_curves:
        # BIP340 Schnorr only applies to curve whose prime p = 3 %4
        if not ec.pIsThreeModFour:
            err_msg = "field prime is not equal to 3 mod 4: "
            with pytest.raises(ValueError, match=err_msg):
                ssa.sign(32 * b"\x00", 1, None, ec)
            continue
        for q in range(1, ec.n // 2):  # all possible private keys
            QJ = _mult_jac(q, ec.GJ, ec)  # public key
            x_Q = ec._x_aff_from_jac(QJ)
            if not ec.has_square_y(QJ):
                q = ec.n - q
                QJ = ec.negate(QJ)
            for k in range(1, ec.n // 2):  # all possible ephemeral keys
                RJ = _mult_jac(k, ec.GJ, ec)
                r = ec._x_aff_from_jac(RJ)
                if not ec.has_square_y(RJ):
                    k = ec.n - k
                for e in range(ec.n):  # all possible challenges
                    s = (k + e * q) % ec.n

                    sig = ssa._sign(r, e, q, k, ec)
                    assert (r, s) == sig
                    # valid signature must validate
                    ssa._assert_as_valid(e, QJ, r, s, ec)

                    # if e == 0 then the sig is valid for all {q, Q}
                    # no public key can be recovered
                    if e == 0:
                        err_msg = "invalid zero challenge"
                        with pytest.raises(ValueError, match=err_msg):
                            ssa._recover_pubkey(e, r, s, ec)
                    else:
                        assert x_Q == ssa._recover_pubkey(e, r, s, ec)
Пример #8
0
    def test_bip340_vectors(self):
        """BIP340 (Schnorr) test vectors

        https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv
        """
        fname = "bip340_test_vectors.csv"
        filename = path.join(path.dirname(__file__), "test_data", fname)
        with open(filename, newline='') as csvfile:
            reader = csv.reader(csvfile)
            # skip column headers while checking that there are 7 columns
            _, _, _, _, _, _, _ = reader.__next__()
            for row in reader:
                (index, seckey, pubkey, mhd, sig, result, comment) = row
                errmsg = f"Test vector #{int(index)}"
                if seckey != '':
                    seckey = bytes.fromhex(seckey)
                    _, pubkey_actual = ssa.gen_keys(seckey)
                    self.assertEqual(pubkey,
                                     hex(pubkey_actual).upper()[2:], errmsg)

                    sig_actual = ssa.serialize(*ssa.sign(mhd, seckey))
                    self.assertEqual(sig, sig_actual.hex().upper(), errmsg)

                result = result == 'TRUE'
                if comment:
                    errmsg += ": " + comment
                result_actual = ssa.verify(mhd, pubkey, sig)
                self.assertEqual(result, result_actual, errmsg)
Пример #9
0
    def test_ecssa(self):
        """Basic tests"""
        ec = secp256k1
        q = 0x1
        Q = mult(ec, q, ec.G)
        msg = hf('Satoshi Nakamoto'.encode()).digest()
        sig = ssa.sign(ec, hf, msg, q, None)
        # no source for the following... but
        # https://bitcointalk.org/index.php?topic=285142.40
        # same r because of rfc6979
        exp_sig = (
            0x934B1EA10A4B3C1757E2B0C017D0B6143CE3C9A7E6A4A49860D7A6AB210EE3D8,
            0x2DF2423F70563E3C4BD0E00BDEF658081613858F110ECF937A2ED9190BF4A01A)
        self.assertEqual(sig[0], exp_sig[0])
        self.assertEqual(sig[1], exp_sig[1])

        ssa._verify(ec, hf, msg, Q, sig)
        self.assertTrue(ssa.verify(ec, hf, msg, Q, sig))
        self.assertTrue(ssa._verify(ec, hf, msg, Q, sig))

        fmsg = hf('Craig Wright'.encode()).digest()
        self.assertFalse(ssa.verify(ec, hf, fmsg, Q, sig))
        self.assertFalse(ssa._verify(ec, hf, fmsg, Q, sig))

        fssasig = (sig[0], sig[1], sig[1])
        self.assertFalse(ssa.verify(ec, hf, msg, Q, fssasig))
        self.assertRaises(TypeError, ssa._verify, ec, hf, msg, Q, fssasig)

        # y(sG - eP) is not a quadratic residue
        fq = 0x2
        fQ = mult(ec, fq, ec.G)
        self.assertFalse(ssa.verify(ec, hf, msg, fQ, sig))
        self.assertRaises(ValueError, ssa._verify, ec, hf, msg, fQ, sig)

        fq = 0x4
        fQ = mult(ec, fq, ec.G)
        self.assertFalse(ssa.verify(ec, hf, msg, fQ, sig))
        self.assertFalse(ssa._verify(ec, hf, msg, fQ, sig))

        # not ec.pIsThreeModFour
        self.assertFalse(ssa.verify(secp224k1, hf, msg, Q, sig))
        self.assertRaises(ValueError, ssa._verify, secp224k1, hf, msg, Q, sig)

        # verify: message of wrong size
        wrongmsg = msg[:-1]
        self.assertFalse(ssa.verify(ec, hf, wrongmsg, Q, sig))
        self.assertRaises(ValueError, ssa._verify, ec, hf, wrongmsg, Q, sig)
        #ssa._verify(ec, hf, wrongmsg, Q, sig)

        # sign: message of wrong size
        self.assertRaises(ValueError, ssa.sign, ec, hf, wrongmsg, q, None)
        #ssa.sign(ec, hf, wrongmsg, q, None)

        # invalid (zero) challenge e
        self.assertRaises(ValueError, ssa._pubkey_recovery, ec, hf, 0, sig)
Пример #10
0
def ecssa_commit_sign(c: bytes,
                      ec: Curve,
                      hf: Callable[[Any], Any],
                      m: bytes,
                      prvkey: int,
                      k: Optional[int] = None) -> Tuple[ssa.ECSS, Receipt]:
    if k is None:
        k = rfc6979(ec, hf, m, prvkey)

    ch = hf(c).digest()

    # commit
    R, new_k = _tweak(ch, ec, hf, k)
    # sign
    sig = ssa.sign(ec, hf, m, prvkey, new_k)
    # commit receipt
    receipt = sig[0], R
    return sig, receipt
Пример #11
0
    def test_ecssa(self):
        """Basic tests"""
        q = 0x1
        Q = mult(q)
        mhd = hf(b'Satoshi Nakamoto').digest()
        sig = ssa.sign(mhd, q, None)
        ssa._verify(mhd, Q, sig, ec, hf)
        self.assertTrue(ssa.verify(mhd, Q, sig))

        fmhd = hf(b'Craig Wright').digest()
        self.assertRaises(AssertionError, ssa._verify, fmhd, Q, sig, ec, hf)

        fssasig = (sig[0], sig[1], sig[1])
        self.assertRaises(ValueError, ssa._verify, mhd, Q, fssasig, ec, hf)

        # y(sG - eP) is not a quadratic residue
        fq = 0x2
        fQ = mult(fq)
        self.assertRaises(ValueError, ssa._verify, mhd, fQ, sig, ec, hf)

        fq = 0x4
        fQ = mult(fq)
        self.assertRaises(AssertionError, ssa._verify, mhd, fQ, sig, ec, hf)

        # not ec.pIsThreeModFour
        self.assertRaises(ValueError, ssa._verify, mhd, Q, sig, secp224k1, hf)

        # verify: message of wrong size
        wrongmhd = mhd[:-1]
        self.assertRaises(ValueError, ssa._verify, wrongmhd, Q, sig, ec, hf)
        #ssa._verify(wrongmhd, Q, sig)

        # sign: message of wrong size
        self.assertRaises(ValueError, ssa.sign, wrongmhd, q, None)
        #ssa.sign(wrongmhd, q, None)

        # invalid (zero) challenge e
        self.assertRaises(ValueError, ssa._recover_pubkeys, 0, sig[0], sig[1],
                          ec)
        #ssa._recover_pubkeys(0, sig)

        # not a BIP340 public key
        self.assertRaises(ValueError, ssa.to_bip340_pubkey_tuple,
                          ["not", "a BIP340", "public key"])
Пример #12
0
    def test_signature(self):
        """Basic tests"""

        q, x_Q = ssa.gen_keys()
        mhd = hf(b'Satoshi Nakamoto').digest()
        sig = ssa.sign(mhd, q, None)
        self.assertEqual(sig, ssa.deserialize(sig))
        ssa._verify(mhd, x_Q, sig, ec, hf)
        self.assertTrue(ssa.verify(mhd, x_Q, sig))

        fmhd = hf(b'Craig Wright').digest()
        self.assertRaises(AssertionError, ssa._verify, fmhd, x_Q, sig, ec, hf)

        fssasig = (sig[0], sig[1], sig[1])
        self.assertRaises(ValueError, ssa._verify, mhd, x_Q, fssasig, ec, hf)

        # y(sG - eP) is not a quadratic residue
        _, fQ = ssa.gen_keys(0x2)
        self.assertRaises(AssertionError, ssa._verify, mhd, fQ, sig, ec, hf)

        _, fQ = ssa.gen_keys(0x4)
        self.assertRaises(AssertionError, ssa._verify, mhd, fQ, sig, ec, hf)

        # not ec.pIsThreeModFour
        self.assertRaises(ValueError, ssa._verify, mhd, x_Q, sig, secp224k1,
                          hf)

        # verify: message of wrong size
        wrongmhd = mhd[:-1]
        self.assertRaises(ValueError, ssa._verify, wrongmhd, x_Q, sig, ec, hf)
        # ssa._verify(wrongmhd, x_Q, sig)

        # sign: message of wrong size
        self.assertRaises(ValueError, ssa.sign, wrongmhd, q, None)
        # ssa.sign(wrongmhd, q, None)

        # invalid (zero) challenge e
        self.assertRaises(ValueError, ssa._recover_pubkeys, 0, sig[0], sig[1],
                          ec)
        # ssa._recover_pubkeys(0, sig)

        # not a BIP340 public key
        self.assertRaises(ValueError, ssa._to_bip340_point,
                          ["not", "a BIP340", "public key"])
Пример #13
0
    def test_low_cardinality(self):
        """test low-cardinality curves for all msg/key pairs."""
        # ec.n has to be prime to sign
        prime = [11, 13, 17, 19]

        # for dsa it is possible to directy iterate on all
        # possible values for e;
        # for ssa we have to iterate over all possible hash values
        hsize = hf().digest_size
        H = [i.to_bytes(hsize, 'big') for i in range(max(prime) * 4)]
        # only low card curves or it would take forever
        for ec in low_card_curves:
            if ec._p in prime:  # only few curves or it would take too long
                # BIP340 Schnorr only applies to curve whose prime p = 3 %4
                if not ec.pIsThreeModFour:
                    self.assertRaises(ValueError, ssa.sign, H[0], 1, None, ec)
                    continue
                for q in range(1, ec.n):  # all possible private keys
                    Q = mult(q, ec.G, ec)  # public key
                    if not ec.has_square_y(Q):
                        q = ec.n - q
                    for h in H:  # all possible hashed messages
                        k = ssa.k(h, q, ec, hf)
                        K = mult(k, ec.G, ec)
                        if not ec.has_square_y(K):
                            k = ec.n - k
                        x_K = K[0]

                        try:
                            c = ssa._challenge(x_K, Q[0], h, ec, hf)
                        except Exception:
                            pass
                        else:
                            s = (k + c * q) % ec.n
                            sig = ssa.sign(h, q, None, ec)
                            self.assertEqual((x_K, s), sig)
                            # valid signature must validate
                            self.assertIsNone(ssa._verify(h, Q, sig, ec, hf))

                            if c != 0:  # FIXME
                                x_Q = ssa._recover_pubkeys(c, x_K, s, ec)
                                self.assertEqual(Q[0], x_Q)
Пример #14
0
    def test_low_cardinality(self):
        """test all msg/key pairs of low cardinality elliptic curves"""

        # ec.n has to be prime to sign
        prime = [11, 13, 17, 19]

        # all possible hashed messages
        hsize = 32
        H = [i.to_bytes(hsize, 'big') for i in range(max(prime) * 2)]

        # only low card curves or it would take forever
        for ec in low_card_curves:
            if ec._p in prime:  # only few curves or it would take too long
                # Schnorr-bip only applies to curve whose prime p = 3 %4
                if not ec.pIsThreeModFour:
                    self.assertRaises(ValueError, ssa.sign, ec, hf, H[0], 1,
                                      None)
                    continue
                for q in range(ec.n):  # all possible private keys
                    if q == 0:  # invalid prvkey=0
                        self.assertRaises(ValueError, ssa.sign, ec, hf, H[0],
                                          q, None)
                        self.assertRaises(ValueError, rfc6979, ec, hf, H[0], q)
                        continue
                    Q = mult(ec, q, ec.G)  # public key
                    for h in H:  # all possible hashed messages
                        # k = 0
                        self.assertRaises(ValueError, ssa.sign, ec, hf, h, q,
                                          0)
                        k = rfc6979(ec, hf, h, q)
                        K = mult(ec, k, ec.G)
                        if legendre_symbol(K[1], ec._p) != 1:
                            k = ec.n - k

                        e = ssa._e(ec, hf, K[0], Q, h)
                        s = (k + e * q) % ec.n
                        # valid signature
                        sig = ssa.sign(ec, hf, h, q, k)
                        self.assertEqual((K[0], s), sig)
                        # valid signature must validate
                        self.assertTrue(ssa._verify(ec, hf, h, Q, sig))
Пример #15
0
    def test_batch_validation(self):
        ec = secp256k1
        m = []
        sig = []
        Q = []

        hsize = hf().digest_size
        hlen = hsize * 8
        for i in range(10):
            m.append(random.getrandbits(hlen).to_bytes(hsize, 'big'))
            q = random.getrandbits(ec.nlen) % ec.n
            sig.append(ssa.sign(ec, hf, m[i], q))
            Q.append(mult(ec, q, ec.G))
        self.assertTrue(ssa.batch_verify(ec, hf, m, Q, sig))

        m.append(m[0])
        sig.append(sig[1])  # invalid
        Q.append(Q[0])
        self.assertFalse(ssa.batch_verify(ec, hf, m, Q, sig))

        sig[-1] = sig[0]  # valid
        m[-1] = m[0][:-1]  # invalid 31 bytes message
        self.assertFalse(ssa.batch_verify(ec, hf, m, Q, sig))
Пример #16
0
dsa_sig = dsa.sign(msg, dsa_prv)
print("r:", hex(dsa_sig[0]))
print("s:", hex(dsa_sig[1]))

dsa_valid = dsa.verify(msg, dsa_pub, dsa_sig)
print("valid ECDSA sig:", dsa_valid)

# ECSSA
print("\n ECSSA")

ssa_prv, ssa_pub = ssa.gen_keys()
print("prv", hex(ssa_prv))
print("pub", hex(ssa_pub))

ssa_sig = ssa.sign(msg, ssa_prv)
print("r:", hex(ssa_sig[0]))
print("s:", hex(ssa_sig[1]))

ssa_valid = ssa.verify(msg, ssa_pub, ssa_sig)
print("valid ECSSA sig:", ssa_valid)

# ECBMS
print("\n ECBMS")

bms_prv, bms_pub = bms.gen_keys()
print("prv", bms_prv)
print("pub", bms_pub)

bms_sig = bms.sign(msg, bms_prv)
print("rf:", hex(bms_sig[0]))
Пример #17
0
def test_signature():
    """Basic tests"""

    ec = secp256k1
    q, x_Q = ssa.gen_keys(0x1)
    mhd = hf(b"Satoshi Nakamoto").digest()
    sig = ssa.sign(mhd, q, None)
    ssa.assert_as_valid(mhd, x_Q, sig, ec, hf)
    assert ssa.verify(mhd, x_Q, sig)
    assert sig == ssa.deserialize(sig)

    fmhd = hf(b"Craig Wright").digest()
    assert not ssa.verify(fmhd, x_Q, sig, ec, hf)
    err_msg = "signature verification failed"
    with pytest.raises(AssertionError, match=err_msg):
        ssa.assert_as_valid(fmhd, x_Q, sig, ec, hf)

    _, x_fQ = ssa.gen_keys(0x2)
    assert not ssa.verify(mhd, x_fQ, sig, ec, hf)
    err_msg = "y_K is not a quadratic residue"
    with pytest.raises(RuntimeError, match=err_msg):
        ssa.assert_as_valid(mhd, x_fQ, sig, ec, hf)

    _, x_fQ = ssa.gen_keys(0x4)
    assert not ssa.verify(mhd, x_fQ, sig, ec, hf)
    err_msg = "signature verification failed"
    with pytest.raises(AssertionError, match=err_msg):
        ssa.assert_as_valid(mhd, x_fQ, sig, ec, hf)

    err_msg = "not a BIP340 public key"
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(mhd, INF, sig, ec, hf)

    assert not ssa.verify(mhd, x_Q, sig, secp224k1, hf)
    err_msg = "field prime is not equal to 3 mod 4: "
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(mhd, x_Q, sig, secp224k1, hf)

    wrongmhd = mhd[:-1]
    assert not ssa.verify(wrongmhd, x_Q, sig, ec, hf)
    err_msg = "invalid size: 31 bytes instead of 32"
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(wrongmhd, x_Q, sig, ec, hf)

    fssasig = (sig[0], sig[1], sig[1])
    assert not ssa.verify(mhd, x_fQ, fssasig, ec, hf)
    err_msg = "too many values to unpack "
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(mhd, x_Q, fssasig, ec, hf)

    invalid_sig = ec.p, sig[1]
    assert not ssa.verify(mhd, x_Q, invalid_sig)
    err_msg = "x-coordinate not in 0..p-1: "
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(mhd, x_Q, invalid_sig, ec, hf)

    invalid_sig = sig[0], ec.p
    assert not ssa.verify(mhd, x_Q, invalid_sig)
    err_msg = "scalar s not in 0..n-1: "
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(mhd, x_Q, invalid_sig, ec, hf)

    err_msg = "invalid size: 31 bytes instead of 32"
    with pytest.raises(ValueError, match=err_msg):
        ssa.sign(wrongmhd, q, None)

    err_msg = "private key not in 1..n-1: "
    with pytest.raises(ValueError, match=err_msg):
        ssa.sign(mhd, 0)

    # ephemeral key not in 1..n-1
    err_msg = "private key not in 1..n-1: "
    with pytest.raises(ValueError, match=err_msg):
        ssa.sign(mhd, 1, 0)

    err_msg = "invalid zero challenge"
    with pytest.raises(ValueError, match=err_msg):
        ssa._recover_pubkey(0, sig[0], sig[1], ec)

    err_msg = "not a BIP340 public key"
    with pytest.raises(ValueError, match=err_msg):
        ssa._to_bip340_point(["not", "a BIP340", "public key"])
Пример #18
0
def test_signature() -> None:
    ec = CURVES["secp256k1"]
    msg = "Satoshi Nakamoto"

    q, x_Q = ssa.gen_keys(0x01)
    sig = ssa.sign(msg, q)
    ssa.assert_as_valid(msg, x_Q, sig)
    assert ssa.verify(msg, x_Q, sig)

    assert sig == ssa.deserialize(sig)

    ssa.assert_as_valid(msg, x_Q, sig)
    ssa.assert_as_valid(msg, x_Q, ssa.serialize(*sig))
    ssa.assert_as_valid(msg, x_Q, ssa.serialize(*sig).hex())

    msg_fake = "Craig Wright"
    assert not ssa.verify(msg_fake, x_Q, sig)
    err_msg = r"y_K is odd|signature verification failed"
    with pytest.raises(BTClibRuntimeError, match=err_msg):
        ssa.assert_as_valid(msg_fake, x_Q, sig)

    _, x_Q_fake = ssa.gen_keys(0x02)
    assert not ssa.verify(msg, x_Q_fake, sig)
    with pytest.raises(BTClibRuntimeError, match=err_msg):
        ssa.assert_as_valid(msg, x_Q_fake, sig)

    _, x_Q_fake = ssa.gen_keys(0x4)
    assert not ssa.verify(msg, x_Q_fake, sig)
    with pytest.raises(BTClibRuntimeError, match=err_msg):
        ssa.assert_as_valid(msg, x_Q_fake, sig)

    err_msg = "not a BIP340 public key"
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_as_valid(msg, INF, sig)  # type: ignore
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.point_from_bip340pubkey(INF)  # type: ignore

    sig_fake = (sig[0], sig[1], sig[1])
    assert not ssa.verify(msg, x_Q, sig_fake)  # type: ignore
    err_msg = "too many values to unpack "
    with pytest.raises(ValueError, match=err_msg):
        ssa.assert_as_valid(msg, x_Q, sig_fake)  # type: ignore

    sig_invalid = ec.p, sig[1]
    assert not ssa.verify(msg, x_Q, sig_invalid)
    err_msg = "x-coordinate not in 0..p-1: "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_as_valid(msg, x_Q, sig_invalid)

    sig_invalid = sig[0], ec.p
    assert not ssa.verify(msg, x_Q, sig_invalid)
    err_msg = "scalar s not in 0..n-1: "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.assert_as_valid(msg, x_Q, sig_invalid)

    m_fake = b"\x00" * 31
    err_msg = "invalid size: 31 bytes instead of 32"
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa._assert_as_valid(m_fake, x_Q, sig)

    with pytest.raises(BTClibValueError, match=err_msg):
        ssa._sign(m_fake, q)

    err_msg = "private key not in 1..n-1: "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.sign(msg, 0)

    # ephemeral key not in 1..n-1
    err_msg = "private key not in 1..n-1: "
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa._sign(reduce_to_hlen(msg, hf), q, 0)
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa._sign(reduce_to_hlen(msg, hf), q, ec.n)

    err_msg = "invalid zero challenge"
    with pytest.raises(BTClibValueError, match=err_msg):
        ssa.__recover_pubkey(0, sig[0], sig[1], ec)
Пример #19
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)
Пример #20
0
print("\n0. Message to be signed")
orig_msg = "Paolo is afraid of ephemeral random numbers"
msg = sha256(orig_msg.encode()).digest()
print(f"        {msg.hex().upper()}")

q = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
q %= ec.n
print("1. Key generation")
print(f"prvkey: {hex(q).upper()}")

Q = mult(q, ec.G)[0]
print(f"PubKey: {hex(Q).upper()}")

print("2. Sign message")
r, s = sign(msg, q)
print(f"    r: {hex(r).upper()}")
print(f"    s: {hex(s).upper()}")

print("3. Verify signature")
print(verify(msg, Q, (r, s)))

print("\n** Malleated signature")
sm = ec.n - s
print(f"    r: {hex(r).upper()}")
print(f"   sm: {hex(sm).upper()}")

print("** Verify malleated signature")
print(verify(msg, Q, (r, sm)))

print("\n0. Another message to sign")
Пример #21
0
random.seed(42)

ec = secp256k1
hf = sha256
hsize = hf().digest_size
hlen = hsize * 8

# n = 1 loops forever and does not really test batch verify
n_sig = [2, 4, 8, 16, 32, 64, 128]
m = []
sig = []
Q = []
for j in range(max(n_sig)):
    m.append(random.getrandbits(hlen).to_bytes(hsize, 'big'))
    q = random.getrandbits(ec.nlen) % ec.n
    sig.append(sign(ec, hf, m[j], q))
    Q.append(mult(ec, q, ec.G))

for n in n_sig:

    # no batch
    start = time.time()
    for j in range(n):
        assert verify(ec, hf, m[j], Q[j], sig[j])
    elapsed1 = time.time() - start

    # batch
    start = time.time()
    assert batch_verify(ec, hf, m[:n], Q[:n], sig[:n])
    elapsed2 = time.time() - start
Пример #22
0
from btclib.ssa import batch_verify, sign, verify

random.seed(42)

hsize = hf().digest_size
hlen = hsize * 8

# n = 1 loops forever and does not really test batch verify
n_sig = [2, 4, 8, 16, 32, 64, 128]
m = []
sig = []
Q = []
for j in range(max(n_sig)):
    m.append(random.getrandbits(hlen).to_bytes(hsize, 'big'))
    q = random.getrandbits(ec.nlen) % ec.n
    sig.append(sign(m[j], q))
    Q.append(mult(q, ec.G))

for n in n_sig:

    # no batch
    start = time.time()
    for j in range(n):
        assert verify(m[j], Q[j], sig[j])
    elapsed1 = time.time() - start

    # batch
    start = time.time()
    assert batch_verify(m[:n], Q[:n], sig[:n])
    elapsed2 = time.time() - start