def test_and_dlrne_does_not_fail_on_same_dl_when_not_binding(): """ Prove (H0 = h0*x, H1 != h1*x), H2 = h2*x with same secret name x. Should not be detected as binding is off by default. """ secrets, secret_values, secret_dict = get_secrets(4) generators = make_generators(4) lhs_values = [x * g for x, g in zip(secret_values, generators)] y3 = secret_values[2] * generators[3] s0 = secrets[0] p1 = DLNotEqual([lhs_values[0], generators[0]], [lhs_values[1], generators[1]], s0) p2 = DLRep(lhs_values[2], s0 * generators[2]) andp = p1 & p2 s0_prime = Secret(name=secrets[0].name) p1_prime = DLNotEqual([lhs_values[0], generators[0]], [lhs_values[1], generators[1]], s0_prime) p2_prime = DLRep(lhs_values[2], s0_prime * generators[2]) andp_prime = p1_prime & p2_prime prov = andp.get_prover(secret_dict) prov.subs[1].secret_values[s0] = secret_values[2] protocol = SigmaProtocol(andp_prime.get_verifier(), prov) assert protocol.verify()
def test_and_dlrep_partial_binding(): """ Claim to use (H0 = h0*x, H1 != h1*x) , (H1 = h1*x, H3 != h3*x) with the same x (not only cheating, a contradiction). Should be undetected as binding is off in at least one proof """ secrets = get_secrets_new(4) generators = make_generators(4) lhs_values = [x.value * g for x, g in zip(secrets, generators)] y3 = secrets[2].value * generators[3] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=False, ) p2 = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], secrets[1], bind=True) andp = p1 & p2 sprime = Secret() p1_prime = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], sprime, bind=False, ) p2_prime = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], sprime, bind=True) andp_prime = p1_prime & p2_prime protocol = SigmaProtocol(andp_prime.get_verifier(), andp.get_prover()) assert protocol.verify()
def test_and_dlrne_binding_1(): secrets, secret_values, secret_dict = get_secrets(4) generators = make_generators(4) lhs_values = [x * g for x, g in zip(secret_values, generators)] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2 = DLRep(lhs_values[0], secrets[0] * generators[0]) andp = p1 & p2 p1_prime = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2_prime = DLRep(lhs_values[0], Secret(name=secrets[0].name) * generators[0]) andp_prime = p1_prime & p2_prime protocol = SigmaProtocol(andp_prime.get_verifier(), andp.get_prover(secret_dict)) assert protocol.verify()
def test_and_dlrne_fails_on_same_dl(): """ Second subproof is not correct as the two members have the same DL """ secrets, secret_values, secret_dict = get_secrets(4) generators = make_generators(4) lhs_values = [x * g for x, g in zip(secret_values, generators)] y3 = secret_values[1] * generators[3] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2 = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], secrets[1]) andp = p1 & p2 p1_prime = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2_prime = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], secrets[1]) andp_prime = p1_prime & p2_prime protocol = SigmaProtocol(andp_prime.get_verifier(), andp.get_prover(secret_dict)) with pytest.raises(ValidationError): protocol.verify()
def test_dlrep_interactive_2(group): g, h = make_generators(2, group) x, y = Secret(), Secret() p = DLRep(10 * g + 15 * h, x * g + y * h) prover = p.get_prover({x: 10, y: 15}) verifier = p.get_verifier() protocol = SigmaProtocol(verifier, prover) assert protocol.verify()
def test_multiple_and_dlrep_fails_on_bad_secret_when_binding(): secrets, secret_values, secret_dict = get_secrets(4) generators = make_generators(4) lhs_values = [x * g for x, g in zip(secret_values, generators)] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2 = DLRep(lhs_values[0], secrets[0] * generators[0]) p3 = DLNotEqual( [lhs_values[2], generators[2]], [lhs_values[1], generators[1]], secrets[2], bind=True, ) p4 = DLNotEqual( [lhs_values[1], generators[1]], [lhs_values[3], generators[3]], secrets[0], bind=True, ) andp = p1 & p2 & p3 & p4 p11 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p21 = DLRep(lhs_values[0], secrets[0] * generators[0]) p31 = DLNotEqual( [lhs_values[2], generators[2]], [lhs_values[1], generators[1]], secrets[2], bind=True, ) p41 = DLNotEqual( [lhs_values[1], generators[1]], [lhs_values[3], generators[3]], secrets[0], bind=True, ) andp1 = p11 & p21 & p31 & p41 prov = andp.get_prover(secret_dict) prov.subs[1].secret_values[secrets[0]] = secret_values[1] protocol = SigmaProtocol(andp1.get_verifier(), prov) with pytest.raises(ValidationError): protocol.verify()
def test_dlrep_interactive_1(group): sk, g = group.order().random(), group.generator() pk = sk * g x = Secret() p = DLRep(pk, x * g) prover = p.get_prover({x: sk}) verifier = p.get_verifier() protocol = SigmaProtocol(verifier, prover) assert protocol.verify()
def test_dlrep_wrong_secrets(group): g = group.generator() g1 = 2 * g g2 = 5 * g x1 = Secret() x2 = Secret() p = DLRep(g, x1 * g1 + x2 * g2) prover = p.get_prover({x1: 10, x2: 15}) verifier = p.get_verifier() protocol = SigmaProtocol(verifier, prover) assert not protocol.verify()
def test_dlrep_wrong_public_elements(group): g, h = make_generators(2, group=group) x, y = Secret(value=3), Secret(value=4) expr = x * g + y * h public_wrong = get_random_point() p = DLRep(public_wrong, expr) prover = p.get_prover() verifier = p.get_verifier() protocol = SigmaProtocol(verifier, prover) assert not protocol.verify()
def test_multiple_and_dlrep_binding(): secrets = get_secrets_new(4) generators = make_generators(4) lhs_values = [x.value * g for x, g in zip(secrets, generators)] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=False, ) p2 = DLRep(lhs_values[2], secrets[2] * generators[2]) p3 = DLNotEqual( [lhs_values[2], generators[2]], [lhs_values[1], generators[1]], secrets[2], bind=True, ) p4 = DLNotEqual( [lhs_values[1], generators[1]], [lhs_values[3], generators[3]], secrets[1], bind=True, ) andp = p1 & p2 & p3 & p4 s0 = Secret() s2 = Secret() p1prime = DLNotEqual([lhs_values[0], generators[0]], [lhs_values[1], generators[1]], s0, bind=False) p2prime = DLRep(lhs_values[2], s2 * generators[2]) p3prime = DLNotEqual([lhs_values[2], generators[2]], [lhs_values[1], generators[1]], s2, bind=True) # Note difference: p4prime binds s0 instead of secrets[1] in the original proof p4prime = DLNotEqual([lhs_values[1], generators[1]], [lhs_values[3], generators[3]], s0, bind=True) andp1 = p1prime & p2prime & p3prime & p4prime protocol = SigmaProtocol(andp1.get_verifier(), andp.get_prover()) assert protocol.verify()
def test_dlrep_interactive_3(group): """Emulate actual workflow with independent provers and verifiers.""" sk, g = group.order().random(), group.generator() pk = sk * g x = Secret() p1 = DLRep(pk, x * g) prover = p1.get_prover({x: sk}) x = Secret() p2 = DLRep(pk, x * g) verifier = p2.get_verifier() protocol = SigmaProtocol(verifier, prover) assert protocol.verify()
def test_bbsplus_and_proof(): mG = BilinearGroupPair() keypair = BBSPlusKeypair.generate(mG, 9) messages = [Bn(30), Bn(31), Bn(32)] pk, sk = keypair.pk, keypair.sk generators, h0 = keypair.generators, keypair.h0 creator = BBSPlusSignatureCreator(pk) lhs = creator.commit(messages) presignature = sk.sign(lhs.com_message) signature = creator.obtain_signature(presignature) e, s, m1, m2, m3 = (Secret() for _ in range(5)) secret_dict = { e: signature.e, s: signature.s, m1: messages[0], m2: messages[1], m3: messages[2], } sigproof = BBSPlusSignatureStmt([e, s, m1, m2, m3], pk, signature) creator = BBSPlusSignatureCreator(pk) lhs = creator.commit(messages) presignature2 = sk.sign(lhs.com_message) signature2 = creator.obtain_signature(presignature2) e1, s1, m1, m2, m3 = (Secret() for _ in range(5)) secret_dict2 = { e1: signature2.e, s1: signature2.s, m1: messages[0], m2: messages[1], m3: messages[2], } sigproof1 = BBSPlusSignatureStmt([e1, s1, m1, m2, m3], pk, signature2) secret_dict.update(secret_dict2) andp = sigproof & sigproof1 prov = andp.get_prover(secret_dict) ver = andp.get_verifier() protocol = SigmaProtocol(ver, prov) assert protocol.verify()
def test_power_two_range_stmt_interactive(): group_pair = BilinearGroupPair() group = group_pair.G1 value = Secret(value=Bn(10)) randomizer = Secret(value=group.order().random()) g, h = make_generators(2, group) limit = 20 com = value * g + randomizer * h p1 = PowerTwoRangeStmt(com.eval(), g, h, limit, value, randomizer) p2 = PowerTwoRangeStmt(com.eval(), g, h, limit, Secret(), Secret()) (p1 & p2).get_prover() prover = p1.get_prover() verifier = p2.get_verifier() protocol = SigmaProtocol(verifier, prover) assert protocol.verify() verifier.stmt.full_validate()
def test_and_dlrne_fails_on_contradiction_when_binding(): """ Claim to use (H0 = h0*x, H1 != h1*x), (H1 = h1*x, H3 != h3*x) with the same x (not only cheating, a contradiction). Should be detected as binding is on. """ secrets, secret_values, secret_dict = get_secrets(4) generators = make_generators(4) lhs_values = [x * g for x, g in zip(secret_values, generators)] y3 = secret_values[2] * generators[3] p1 = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2 = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], secrets[0], bind=True) andp = p1 & p2 p1_prime = DLNotEqual( [lhs_values[0], generators[0]], [lhs_values[1], generators[1]], secrets[0], bind=True, ) p2_prime = DLNotEqual([lhs_values[1], generators[1]], [y3, generators[3]], secrets[0], bind=True) andp_prime = p1_prime & p2_prime prov = andp.get_prover(secret_dict) prov.subs[1].secret_values[secrets[0]] = secret_values[1] protocol = SigmaProtocol(andp_prime.get_verifier(), prov) with pytest.raises(ValidationError): protocol.verify()