// -*- coding: utf-8; mode: rust; -*- // // To the extent possible under law, the authors have waived all // copyright and related or neighboring rights to zkp, // using the Creative Commons "CC0" public domain dedication. See // for full // details. // // Authors: // - Henry de Valence #![allow(non_snake_case)] extern crate bincode; extern crate curve25519_dalek; extern crate serde; extern crate sha2; extern crate zkp; use self::sha2::Sha512; use curve25519_dalek::constants as dalek_constants; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar; use zkp::toolbox::{batch_verifier::BatchVerifier, prover::Prover, verifier::Verifier, SchnorrCS}; use zkp::Transcript; fn dleq_statement( cs: &mut CS, x: CS::ScalarVar, A: CS::PointVar, G: CS::PointVar, B: CS::PointVar, H: CS::PointVar, ) { cs.constrain(A, vec![(x, B)]); cs.constrain(G, vec![(x, H)]); } #[test] fn create_and_verify_compact_dleq() { let B = dalek_constants::RISTRETTO_BASEPOINT_POINT; let H = RistrettoPoint::hash_from_bytes::(B.compress().as_bytes()); let (proof, cmpr_A, cmpr_G) = { let x = Scalar::from(89327492234u64); let A = B * x; let G = H * x; let mut transcript = Transcript::new(b"DLEQTest"); let mut prover = Prover::new(b"DLEQProof", &mut transcript); // XXX committing var names to transcript forces ordering (?) let var_x = prover.allocate_scalar(b"x", x); let (var_B, _) = prover.allocate_point(b"B", B); let (var_H, _) = prover.allocate_point(b"H", H); let (var_A, cmpr_A) = prover.allocate_point(b"A", A); let (var_G, cmpr_G) = prover.allocate_point(b"G", G); dleq_statement(&mut prover, var_x, var_A, var_G, var_B, var_H); (prover.prove_compact(), cmpr_A, cmpr_G) }; let mut transcript = Transcript::new(b"DLEQTest"); let mut verifier = Verifier::new(b"DLEQProof", &mut transcript); let var_x = verifier.allocate_scalar(b"x"); let var_B = verifier.allocate_point(b"B", B.compress()).unwrap(); let var_H = verifier.allocate_point(b"H", H.compress()).unwrap(); let var_A = verifier.allocate_point(b"A", cmpr_A).unwrap(); let var_G = verifier.allocate_point(b"G", cmpr_G).unwrap(); dleq_statement(&mut verifier, var_x, var_A, var_G, var_B, var_H); assert!(verifier.verify_compact(&proof).is_ok()); } #[test] fn create_and_verify_batchable_dleq() { let B = dalek_constants::RISTRETTO_BASEPOINT_POINT; let H = RistrettoPoint::hash_from_bytes::(B.compress().as_bytes()); let (proof, cmpr_A, cmpr_G) = { let x = Scalar::from(89327492234u64); let A = B * x; let G = H * x; let mut transcript = Transcript::new(b"DLEQTest"); let mut prover = Prover::new(b"DLEQProof", &mut transcript); // XXX committing var names to transcript forces ordering (?) let var_x = prover.allocate_scalar(b"x", x); let (var_B, _) = prover.allocate_point(b"B", B); let (var_H, _) = prover.allocate_point(b"H", H); let (var_A, cmpr_A) = prover.allocate_point(b"A", A); let (var_G, cmpr_G) = prover.allocate_point(b"G", G); dleq_statement(&mut prover, var_x, var_A, var_G, var_B, var_H); (prover.prove_batchable(), cmpr_A, cmpr_G) }; let mut transcript = Transcript::new(b"DLEQTest"); let mut verifier = Verifier::new(b"DLEQProof", &mut transcript); let var_x = verifier.allocate_scalar(b"x"); let var_B = verifier.allocate_point(b"B", B.compress()).unwrap(); let var_H = verifier.allocate_point(b"H", H.compress()).unwrap(); let var_A = verifier.allocate_point(b"A", cmpr_A).unwrap(); let var_G = verifier.allocate_point(b"G", cmpr_G).unwrap(); dleq_statement(&mut verifier, var_x, var_A, var_G, var_B, var_H); assert!(verifier.verify_batchable(&proof).is_ok()); } #[test] fn create_and_batch_verify_batchable_dleq() { let B = dalek_constants::RISTRETTO_BASEPOINT_POINT; let H = RistrettoPoint::hash_from_bytes::(B.compress().as_bytes()); let batch_size = 16; let mut proofs = Vec::new(); let mut cmpr_As = Vec::new(); let mut cmpr_Gs = Vec::new(); for j in 0..batch_size { let (proof, cmpr_A, cmpr_G) = { let x = Scalar::from((j as u64) + 89327492234u64); let A = B * x; let G = H * x; let mut transcript = Transcript::new(b"DLEQBatchTest"); let mut prover = Prover::new(b"DLEQProof", &mut transcript); // XXX committing var names to transcript forces ordering (?) let var_x = prover.allocate_scalar(b"x", x); let (var_B, _) = prover.allocate_point(b"B", B); let (var_H, _) = prover.allocate_point(b"H", H); let (var_A, cmpr_A) = prover.allocate_point(b"A", A); let (var_G, cmpr_G) = prover.allocate_point(b"G", G); dleq_statement(&mut prover, var_x, var_A, var_G, var_B, var_H); (prover.prove_batchable(), cmpr_A, cmpr_G) }; proofs.push(proof); cmpr_As.push(cmpr_A); cmpr_Gs.push(cmpr_G); } let mut transcripts = vec![Transcript::new(b"DLEQBatchTest"); batch_size]; let transcript_refs = transcripts.iter_mut().collect(); let mut verifier = BatchVerifier::new(b"DLEQProof", batch_size, transcript_refs).unwrap(); let var_x = verifier.allocate_scalar(b"x"); let var_B = verifier.allocate_static_point(b"B", B.compress()).unwrap(); let var_H = verifier.allocate_static_point(b"H", H.compress()).unwrap(); let var_A = verifier.allocate_instance_point(b"A", cmpr_As).unwrap(); let var_G = verifier.allocate_instance_point(b"G", cmpr_Gs).unwrap(); dleq_statement(&mut verifier, var_x, var_A, var_G, var_B, var_H); assert!(verifier.verify_batchable(&proofs).is_ok()); }