def test_signature(self): ec = secp256k1 q, Q = dsa.gen_keys(0x1) msg = "Satoshi Nakamoto" sig = dsa.sign(msg, q) self.assertEqual(sig, dsa.deserialize(sig)) # https://bitcointalk.org/index.php?topic=285142.40 # Deterministic Usage of DSA and ECDSA (RFC 6979) exp_sig = ( 0x934B1EA10A4B3C1757E2B0C017D0B6143CE3C9A7E6A4A49860D7A6AB210EE3D8, 0x2442CE9D2B916064108014783E923EC36B49743E2FFA1C4496F01A512AAFD9E5, ) r, s = sig self.assertEqual(sig[0], exp_sig[0]) self.assertIn(sig[1], (exp_sig[1], secp256k1.n - exp_sig[1])) self.assertTrue(dsa.verify(msg, Q, sig)) # malleability malleated_sig = (r, secp256k1.n - s) self.assertTrue(dsa.verify(msg, Q, malleated_sig)) keys = dsa.recover_pubkeys(msg, sig) self.assertTrue(len(keys) == 2) self.assertIn(Q, keys) fmsg = "Craig Wright" self.assertFalse(dsa.verify(fmsg, Q, sig)) fdsasig = (sig[0], sig[1], sig[1]) self.assertFalse(dsa.verify(msg, Q, fdsasig)) self.assertRaises(ValueError, dsa._verify, msg, Q, fdsasig, ec, hf) _, fQ = dsa.gen_keys() self.assertFalse(dsa.verify(msg, fQ, sig)) # r not in [1, n-1] invalid_dassig = 0, sig[1] self.assertFalse(dsa.verify(msg, Q, invalid_dassig)) # s not in [1, n-1] invalid_dassig = sig[0], 0 self.assertFalse(dsa.verify(msg, Q, invalid_dassig)) # pubkey = INF self.assertRaises(ValueError, dsa._verify, msg, INF, sig, ec, hf) # dsa._verify(msg, INF, sig, ec, hf) # private key not in [1, n-1] self.assertRaises(ValueError, dsa.sign, msg, 0) # dsa.sign(msg, 0) # ephemeral key not in [1, n-1] self.assertRaises(ValueError, dsa.sign, msg, 1, 0)
def test_signature(self): q = 0x1 Q = mult(q) msg = 'Satoshi Nakamoto' sig = dsa.sign(msg, q) # https://bitcointalk.org/index.php?topic=285142.40 # Deterministic Usage of DSA and ECDSA (RFC 6979) exp_sig = ( 0x934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d8, 0x2442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5) r, s = sig self.assertEqual(sig[0], exp_sig[0]) self.assertIn(sig[1], (exp_sig[1], secp256k1.n - exp_sig[1])) self.assertTrue(dsa.verify(msg, Q, sig)) # malleability malleated_sig = (r, secp256k1.n - s) self.assertTrue(dsa.verify(msg, Q, malleated_sig)) keys = dsa.recover_pubkeys(msg, sig) self.assertTrue(len(keys) == 2) self.assertIn(Q, keys) fmsg = 'Craig Wright' self.assertFalse(dsa.verify(fmsg, Q, sig)) fdsasig = (sig[0], sig[1], sig[1]) self.assertFalse(dsa.verify(msg, Q, fdsasig)) self.assertRaises(ValueError, dsa._verify, msg, Q, fdsasig, ec, hf) fq = 0x4 fQ = mult(fq) self.assertFalse(dsa.verify(msg, fQ, sig)) # r not in [1, n-1] invalid_dassig = 0, sig[1] self.assertFalse(dsa.verify(msg, Q, invalid_dassig)) # s not in [1, n-1] invalid_dassig = sig[0], 0 self.assertFalse(dsa.verify(msg, Q, invalid_dassig)) # pubkey = INF self.assertRaises(ValueError, dsa._verify, msg, INF, sig, ec, hf) #dsa._verify(msg, INF, sig, ec, hf) # private key not in [1, n-1] self.assertRaises(ValueError, dsa.sign, msg, 0) #dsa.sign(msg, 0) # ephemeral key not in [1, n-1] self.assertRaises(ValueError, dsa.sign, msg, 1, 0)
def test_pubkey_recovery(self): ec = secp112r2 q = 0x10 Q = mult(q, ec.G, ec) msg = 'Satoshi Nakamoto' k = sighash = None sig = dsa.sign(msg, q, k, ec) self.assertTrue(dsa.verify(msg, Q, sig, ec)) dersig = der.serialize(*sig, sighash, ec) self.assertTrue(dsa.verify(msg, Q, dersig, ec)) r, s, _ = der.deserialize(dersig) self.assertEqual((r, s), sig) keys = dsa.recover_pubkeys(msg, dersig, ec) self.assertEqual(len(keys), 4) self.assertIn(Q, keys) for Q in keys: self.assertTrue(dsa.verify(msg, Q, sig, ec))
def test_pubkey_recovery() -> None: ec = CURVES["secp112r2"] q = 0x10 Q = mult(q, ec.G, ec) msg = "Satoshi Nakamoto" low_s = True sig = dsa.sign(msg, q, low_s, ec) assert dsa.verify(msg, Q, sig, ec) dersig = dsa.serialize(*sig, ec) assert dsa.verify(msg, Q, dersig, ec) r, s = dsa.deserialize(dersig) assert (r, s) == sig keys = dsa.recover_pubkeys(msg, sig, ec) assert len(keys) == 4 assert Q in keys for Q in keys: assert dsa.verify(msg, Q, sig, ec)
def test_pubkey_recovery(): ec = secp112r2 q = 0x10 Q = mult(q, ec.G, ec) msg = "Satoshi Nakamoto" k = None sig = dsa.sign(msg, q, k, ec) assert dsa.verify(msg, Q, sig, ec) dersig = dsa.serialize(*sig, ec) assert dsa.verify(msg, Q, dersig, ec) r, s = dsa.deserialize(dersig) assert (r, s) == sig keys = dsa.recover_pubkeys(msg, sig, ec) assert len(keys) == 4 assert Q in keys for Q in keys: assert dsa.verify(msg, Q, sig, ec)
def test_signature() -> None: ec = CURVES["secp256k1"] msg = "Satoshi Nakamoto" q, Q = dsa.gen_keys(0x1) sig = dsa.sign(msg, q) assert dsa.verify(msg, Q, sig) assert sig == dsa.deserialize(sig) # https://bitcointalk.org/index.php?topic=285142.40 # Deterministic Usage of DSA and ECDSA (RFC 6979) exp_sig = ( 0x934B1EA10A4B3C1757E2B0C017D0B6143CE3C9A7E6A4A49860D7A6AB210EE3D8, 0x2442CE9D2B916064108014783E923EC36B49743E2FFA1C4496F01A512AAFD9E5, ) r, s = sig assert sig[0] == exp_sig[0] assert sig[1] in (exp_sig[1], ec.n - exp_sig[1]) dsa.assert_as_valid(msg, Q, sig) dsa.assert_as_valid(msg, Q, dsa.serialize(*sig)) dsa.assert_as_valid(msg, Q, dsa.serialize(*sig).hex()) # malleability malleated_sig = (r, ec.n - s) assert dsa.verify(msg, Q, malleated_sig) keys = dsa.recover_pubkeys(msg, sig) assert len(keys) == 2 assert Q in keys msg_fake = "Craig Wright" assert not dsa.verify(msg_fake, Q, sig) err_msg = "signature verification failed" with pytest.raises(BTClibRuntimeError, match=err_msg): dsa.assert_as_valid(msg_fake, Q, sig) _, Q_fake = dsa.gen_keys() assert not dsa.verify(msg, Q_fake, sig) err_msg = "signature verification failed" with pytest.raises(BTClibRuntimeError, match=err_msg): dsa.assert_as_valid(msg, Q_fake, sig) err_msg = "not a valid public key: " with pytest.raises(BTClibValueError, match=err_msg): dsa.assert_as_valid(msg, INF, sig) sig_fake = (sig[0], sig[1], sig[1]) assert not dsa.verify(msg, Q, sig_fake) # type: ignore err_msg = "too many values to unpack " with pytest.raises(ValueError, match=err_msg): dsa.assert_as_valid(msg, Q, sig_fake) # type: ignore sig_invalid = ec.p, sig[1] assert not dsa.verify(msg, Q, sig_invalid) err_msg = "scalar r not in 1..n-1: " with pytest.raises(BTClibValueError, match=err_msg): dsa.assert_as_valid(msg, Q, sig_invalid) sig_invalid = sig[0], ec.p assert not dsa.verify(msg, Q, sig_invalid) err_msg = "scalar s not in 1..n-1: " with pytest.raises(BTClibValueError, match=err_msg): dsa.assert_as_valid(msg, Q, sig_invalid) err_msg = "private key not in 1..n-1: " with pytest.raises(BTClibValueError, match=err_msg): dsa.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): dsa._sign(reduce_to_hlen(msg), q, 0) with pytest.raises(BTClibValueError, match=err_msg): dsa._sign(reduce_to_hlen(msg), q, ec.n)
q = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 q %= ec.n Q = mult(q, ec.G) print(f"prvkey: {hex(q).upper()}") print(f"PubKey: {'02' if Q[1] % 2 == 0 else '03'} {hex(Q[0]).upper()}") print("2. Sign message") r1, s1 = sign(msg1, q) print(f" r1: {hex(r1).upper()}") print(f" s1: {hex(s1).upper()}") print("3. Verify signature") print(verify(msg1, Q, (r1, s1))) print("4. Recover keys") keys = recover_pubkeys(msg1, (r1, s1)) for i, key in enumerate(keys): print( f" key#{i}: {'02' if key[1] % 2 == 0 else '03'} {hex(key[0]).upper()}") print("\n** Malleated signature") sm = ec.n - s1 print(f" r1: {hex(r1).upper()}") print(f" sm: {hex(sm).upper()}") print("** Verify malleated signature") print(verify(msg1, Q, (r1, sm))) print("** Recover keys") keys = recover_pubkeys(msg1, (r1, sm)) for i, key in enumerate(keys):
def test_signature(): ec = secp256k1 q, Q = dsa.gen_keys(0x1) msg = "Satoshi Nakamoto" sig = dsa.sign(msg, q) dsa.assert_as_valid(msg, Q, sig, ec, hf) assert dsa.verify(msg, Q, sig) assert sig == dsa.deserialize(sig) # https://bitcointalk.org/index.php?topic=285142.40 # Deterministic Usage of DSA and ECDSA (RFC 6979) exp_sig = ( 0x934B1EA10A4B3C1757E2B0C017D0B6143CE3C9A7E6A4A49860D7A6AB210EE3D8, 0x2442CE9D2B916064108014783E923EC36B49743E2FFA1C4496F01A512AAFD9E5, ) r, s = sig assert sig[0] == exp_sig[0] assert sig[1] in (exp_sig[1], secp256k1.n - exp_sig[1]) # malleability malleated_sig = (r, secp256k1.n - s) assert dsa.verify(msg, Q, malleated_sig) keys = dsa.recover_pubkeys(msg, sig) assert len(keys) == 2 assert Q in keys fmsg = "Craig Wright" assert not dsa.verify(fmsg, Q, sig) err_msg = "signature verification failed" with pytest.raises(AssertionError, match=err_msg): dsa.assert_as_valid(fmsg, Q, sig, ec, hf) _, fQ = dsa.gen_keys() assert not dsa.verify(msg, fQ, sig) err_msg = "signature verification failed" with pytest.raises(AssertionError, match=err_msg): dsa.assert_as_valid(msg, fQ, sig, ec, hf) err_msg = "not a valid public key: " with pytest.raises(ValueError, match=err_msg): dsa.assert_as_valid(msg, INF, sig, ec, hf) fdsasig = (sig[0], sig[1], sig[1]) assert not dsa.verify(msg, Q, fdsasig) err_msg = "too many values to unpack " with pytest.raises(ValueError, match=err_msg): dsa.assert_as_valid(msg, Q, fdsasig, ec, hf) invalid_sig = ec.p, sig[1] assert not dsa.verify(msg, Q, invalid_sig) err_msg = "scalar r not in 1..n-1: " with pytest.raises(ValueError, match=err_msg): dsa.assert_as_valid(msg, Q, invalid_sig, ec, hf) invalid_sig = sig[0], ec.p assert not dsa.verify(msg, Q, invalid_sig) err_msg = "scalar s not in 1..n-1: " with pytest.raises(ValueError, match=err_msg): dsa.assert_as_valid(msg, Q, invalid_sig, ec, hf) err_msg = "private key not in 1..n-1: " with pytest.raises(ValueError, match=err_msg): dsa.sign(msg, 0) # ephemeral key not in 1..n-1 err_msg = "private key not in 1..n-1: " with pytest.raises(ValueError, match=err_msg): dsa.sign(msg, 1, 0)