示例#1
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"])
示例#2
0
def test_bip340_vectors() -> None:
    """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, aux_rand, m, sig, result, comment) = row
            err_msg = f"Test vector #{int(index)}"
            try:
                if seckey != "":
                    _, pubkey_actual = ssa.gen_keys(seckey)
                    assert pubkey == hex(pubkey_actual).upper()[2:], err_msg

                    k = ssa._det_nonce(m, seckey, aux_rand)
                    sig_actual = ssa._sign(m, seckey, k)
                    ssa._assert_as_valid(m, pubkey, sig_actual)
                    assert ssa.deserialize(sig) == sig_actual, err_msg

                if comment:
                    err_msg += ": " + comment
                # TODO what's wrong with xor-ing ?
                # assert (result == "TRUE") ^ ssa._verify(m, pubkey, sig), err_msg
                if result == "TRUE":
                    ssa._assert_as_valid(m, pubkey, sig)
                    assert ssa._verify(m, pubkey, sig), err_msg
                else:
                    assert not ssa._verify(m, pubkey, sig), err_msg
            except Exception as e:  # pragma: no cover # pylint: disable=broad-except
                print(err_msg)  # pragma: no cover
                raise e  # pragma: no cover
示例#3
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)
示例#4
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"])