def test_der_size() -> None: sig8 = 1, 1 sig72 = ec.n - 1, ec.n - 1 sig71 = 2**255 - 1, ec.n - 1 sig70 = 2**255 - 1, 2**255 - 1 sig70b = 2**255 - 1, 2**248 - 1 sig69 = 2**255 - 1, 2**247 - 1 sig68 = 2**247 - 1, 2**247 - 1 sigs = [sig8, sig72, sig71, sig70, sig70b, sig69, sig68] lenghts = [8, 72, 71, 70, 70, 69, 68] # not including script.SIGHASHES for lenght, sig in zip(lenghts, sigs): for sighash in script.SIGHASHES: der_sig = _serialize(*sig, sighash) r, s, sighash2 = _deserialize(der_sig) assert sig == (r, s) assert sighash == sighash2 assert len(der_sig) == lenght + 1 # with the last one only... assert (r, s, sighash) == _deserialize((r, s, sighash))
def test_der_size(): sig8 = 1, 1 sig72 = ec.n - 1, ec.n - 1 sig71 = 2**255 - 1, ec.n - 1 sig70 = 2**255 - 1, 2**255 - 1 sig70b = 2**255 - 1, 2**248 - 1 sig69 = 2**255 - 1, 2**247 - 1 sig68 = 2**247 - 1, 2**247 - 1 sigs = [sig8, sig72, sig71, sig70, sig70b, sig69, sig68] lenghts = [8, 72, 71, 70, 70, 69, 68] for lenght, sig in zip(lenghts, sigs): for sighash in SIGHASHES + [None]: der_sig = _serialize(*sig, sighash) r, s, sighash2 = _deserialize(der_sig) assert sig == (r, s) assert sighash == sighash2 assert len(der_sig) == lenght + 0 if sighash is None else 1 # with the last one only... assert (r, s, sighash) == _deserialize((r, s, sighash))
def test_der_serialize() -> None: sig = 2**247 - 1, 2**247 - 1 err_msg = "invalid sighash: 0x" with pytest.raises(ValueError, match=err_msg): _serialize(*sig, 0x85) for sighash in script.SIGHASHES: err_msg = "scalar r not in 1..n-1: " for r in (0, ec.n): bad_sig = r, sig[1] with pytest.raises(ValueError, match=err_msg): _serialize(*bad_sig, sighash) for s in (0, ec.n): bad_sig = sig[0], s err_msg = "scalar s not in 1..n-1: " with pytest.raises(ValueError, match=err_msg): _serialize(*bad_sig, sighash)
def test_der(self): sighash_all = b"\x01" sig9 = 1, 1 sig73 = ec.n - 1, ec.n - 1 sig72 = 2**255 - 1, ec.n - 1 sig71 = 2**255 - 1, 2**255 - 1 sig71b = 2**255 - 1, 2**248 - 1 sig70 = 2**255 - 1, 2**247 - 1 sig69 = 2**247 - 1, 2**247 - 1 sigs = [sig9, sig73, sig72, sig71, sig71b, sig70, sig69] lenghts = [9, 73, 72, 71, 71, 70, 69] for lenght, sig in zip(lenghts, sigs): dersig = _serialize(*sig, sighash_all) r, s, sighash = _deserialize(dersig) self.assertEqual(sig, (r, s)) self.assertEqual(sighash_all, sighash) self.assertEqual(len(dersig), lenght) # without sighash r, s, no_sighash = _deserialize(dersig[:-1]) self.assertEqual(sig, (r, s)) self.assertIsNone(no_sighash) # with the last one self.assertEqual((r, s, sighash), _deserialize((r, s, sighash))) # Invalid sighash (b'\x00') badsig = dersig[:-1] + b"\x00" self.assertRaises(ValueError, _deserialize, badsig) # _deserialize(badsig) # DER signature size should be in [8, 73] dersig2 = dersig + b"\x00" * 70 self.assertRaises(ValueError, _deserialize, dersig2) # DER signature must be of type 0x30 (compound) dersig2 = b"\x00" + dersig[1:] self.assertRaises(ValueError, _deserialize, dersig2) # Declared signature size does not match with size dersig2 = dersig[:1] + b"\x00" + dersig[2:] self.assertRaises(ValueError, _deserialize, dersig2) Rsize = dersig[3] # Zero-size integers are not allowed for r dersig2 = dersig[:3] + b"\x00" + dersig[4:] self.assertRaises(ValueError, _deserialize, dersig2) # Length of the s scalar must be inside the signature dersig2 = dersig[:3] + b"\x80" + dersig[4:] self.assertRaises(ValueError, _deserialize, dersig2) # Zero-size integers are not allowed for s dersig2 = dersig[:Rsize + 5] + b"\x00" + dersig[Rsize + 6:] self.assertRaises(ValueError, _deserialize, dersig2) # Signature size does not match with scalars dersig2 = dersig[:Rsize + 5] + b"\x4f" + dersig[Rsize + 6:] self.assertRaises(ValueError, _deserialize, dersig2) # r scalar must be an integer dersig2 = dersig[:2] + b"\x00" + dersig[3:] self.assertRaises(ValueError, _deserialize, dersig2) # Negative numbers are not allowed for r dersig2 = dersig[:4] + b"\x80" + dersig[5:] self.assertRaises(ValueError, _deserialize, dersig2) # Invalid null bytes at the start of r dersig2 = dersig[:4] + b"\x00\x00" + dersig[6:] self.assertRaises(ValueError, _deserialize, dersig2) # deserialize(dersig2) # s scalar must be an integer dersig2 = dersig[:Rsize + 4] + b"\x00" + dersig[Rsize + 5:] self.assertRaises(ValueError, _deserialize, dersig2) # Negative numbers are not allowed for s dersig2 = dersig[:Rsize + 6] + b"\x80" + dersig[Rsize + 7:] self.assertRaises(ValueError, _deserialize, dersig2) # Invalid null bytes at the start of s dersig2 = dersig[:Rsize + 6] + b"\x00\x00" + dersig[Rsize + 8:] self.assertRaises(ValueError, _deserialize, dersig2) # sighash size > 1 self.assertRaises(ValueError, _serialize, *sig, sighash_all + b"\x01") # negative signature scalar sig2 = -1, sig[1] self.assertRaises(ValueError, _serialize, *sig2, sighash_all) # Invalid sighash type b'\x00' self.assertRaises(ValueError, _deserialize, dersig[:-1] + b"\x00")
def test_der_deserialize() -> None: err_msg = "non-hexadecimal number found " with pytest.raises(ValueError, match=err_msg): _deserialize("not a sig") sig = 2**255 - 1, 2**247 - 1 for sighash in script.SIGHASHES: der_sig = _serialize(*sig, sighash) r_size = der_sig[3] bad_der_sig = b"\x00" * 74 err_msg = "invalid DER size: " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = b"\x31" + der_sig[1:] err_msg = "DER type must be 0x30 " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:1] + b"\x41" + der_sig[2:] err_msg = "Declared size incompatible with actual size: " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig + b"\x01" err_msg = "Declared size incompatible with actual size: " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:-1] + b"\x00" err_msg = "invalid sighash: 0x" with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) # r and s scalars for offset in (4, 6 + r_size): bad_der_sig = der_sig[:offset - 2] + b"\x00" + der_sig[offset - 1:] err_msg = "scalar must be an integer" with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:offset - 1] + b"\x00" + der_sig[offset:] err_msg = "scalar has size zero" with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:offset - 1] + b"\x80" + der_sig[offset:] err_msg = "Size of scalar is too large: " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:offset] + b"\x80" + der_sig[offset + 1:] err_msg = "Negative number not allowed for scalar" with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) bad_der_sig = der_sig[:offset] + b"\x00\x7f" + der_sig[offset + 2:] err_msg = "invalid null bytes at the start of scalar" with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig) data_size = der_sig[1] malleated_size = (data_size + 1).to_bytes(1, byteorder="big") bad_der_sig = der_sig[:1] + malleated_size + der_sig[2:] + b"\x01" err_msg = "Too big DER size for " with pytest.raises(ValueError, match=err_msg): _deserialize(bad_der_sig)