def test_batch_validation() -> None: ec = CURVES["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]) 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): m = secrets.randbits(hlen).to_bytes(hsize, "big") ms.append(m) q = 1 + secrets.randbelow(ec.n - 1) # Point version Qs.append(mult(q, ec.G, ec)[0]) sigs.append(ssa._sign(m, 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, CURVES["secp224k1"], hf)
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)
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)
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))
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)
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 print(n, elapsed2 / elapsed1)
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 print(n, elapsed2 / elapsed1)