Last active
August 24, 2018 06:31
-
-
Save hdevalence/4ef3f3e4c2e9f434adba1b738411b66e to your computer and use it in GitHub Desktop.
example of zkp-expanded dleq with merlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create_nipk!{dleq, (x), (A, B, G, H) : A = (G * x), B = (H * x) } | |
mod dleq { | |
use curve25519_dalek::ristretto::RistrettoPoint; | |
use curve25519_dalek::scalar::Scalar; | |
use curve25519_dalek::traits::{MultiscalarMul, VartimeMultiscalarMul}; | |
use merlin::Transcript; | |
use rand::thread_rng; | |
use std::iter; | |
pub struct Secrets<'a> { | |
// Create a parameter for each secret value | |
pub x: &'a Scalar, | |
} | |
pub struct Publics<'a> { | |
// Create a parameter for each public value | |
pub A: &'a RistrettoPoint, | |
pub B: &'a RistrettoPoint, | |
pub G: &'a RistrettoPoint, | |
pub H: &'a RistrettoPoint, | |
} | |
struct Commitments { | |
A: RistrettoPoint, | |
B: RistrettoPoint, | |
} | |
struct Randomnesses { | |
x: Scalar, | |
} | |
struct Responses { | |
x: Scalar, | |
} | |
impl Proof { | |
/// Create a `Proof` from the given `Publics` and `Secrets`. | |
pub fn create(transcript: &mut Transcript, publics: Publics, secrets: Secrets) -> Proof { | |
transcript.commit_bytes(b"domain-sep", "dleq".as_bytes()); | |
transcript.commit_bytes("A".as_bytes(), publics.A.compress().as_bytes()); | |
transcript.commit_bytes("B".as_bytes(), publics.B.compress().as_bytes()); | |
transcript.commit_bytes("G".as_bytes(), publics.G.compress().as_bytes()); | |
transcript.commit_bytes("H".as_bytes(), publics.H.compress().as_bytes()); | |
let rng_ctor = transcript.fork_transcript(); | |
let rng_ctor = rng_ctor.commit_witness_bytes("x".as_bytes(), secrets.x.as_bytes()); | |
let mut transcript_rng = rng_ctor.reseed_from_rng(&mut thread_rng()); | |
let rand = Randomnesses { | |
x: Scalar::random(&mut transcript_rng), | |
}; | |
let commitments = Commitments { | |
A: RistrettoPoint::multiscalar_mul(&[rand.x], &[*(publics.G)]), | |
B: RistrettoPoint::multiscalar_mul(&[rand.x], &[*(publics.H)]), | |
}; | |
transcript.commit_bytes("com A".as_bytes(), commitments.A.compress().as_bytes()); | |
transcript.commit_bytes("com B".as_bytes(), commitments.B.compress().as_bytes()); | |
let challenge = { | |
let mut bytes = [0; 64]; | |
transcript.challenge_bytes(b"chal", &mut bytes); | |
Scalar::from_bytes_mod_order_wide(&bytes) | |
}; | |
let responses = Responses { | |
x: &(&challenge * secrets.x) + &rand.x, | |
}; | |
Proof { | |
challenge: challenge, | |
responses: responses, | |
} | |
} | |
/// Verify the `Proof` using the public parameters `Publics`. | |
pub fn verify(&self, transcript: &mut Transcript, publics: Publics) -> Result<(), ()> { | |
let responses = &self.responses; | |
let minus_c = -&self.challenge; | |
let commitments = Commitments { | |
A: RistrettoPoint::vartime_multiscalar_mul( | |
(&[responses.x]).into_iter().chain(iter::once(&(minus_c))), | |
(&[*(publics.G)]).into_iter().chain(iter::once(publics.A)), | |
), | |
B: RistrettoPoint::vartime_multiscalar_mul( | |
(&[responses.x]).into_iter().chain(iter::once(&(minus_c))), | |
(&[*(publics.H)]).into_iter().chain(iter::once(publics.B)), | |
), | |
}; | |
transcript.commit_bytes(b"domain-sep", "dleq".as_bytes()); | |
transcript.commit_bytes("A".as_bytes(), publics.A.compress().as_bytes()); | |
transcript.commit_bytes("B".as_bytes(), publics.B.compress().as_bytes()); | |
transcript.commit_bytes("G".as_bytes(), publics.G.compress().as_bytes()); | |
transcript.commit_bytes("H".as_bytes(), publics.H.compress().as_bytes()); | |
transcript.commit_bytes("com A".as_bytes(), commitments.A.compress().as_bytes()); | |
transcript.commit_bytes("com B".as_bytes(), commitments.B.compress().as_bytes()); | |
let challenge = { | |
let mut bytes = [0; 64]; | |
transcript.challenge_bytes(b"chal", &mut bytes); | |
Scalar::from_bytes_mod_order_wide(&bytes) | |
}; | |
if challenge == self.challenge { | |
Ok(()) | |
} else { | |
Err(()) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment