From 4c13088cf6b6e0c078c8d53c3eaaf779f1e46439 Mon Sep 17 00:00:00 2001 From: Ariel Gabizon Date: Mon, 19 Sep 2016 18:48:01 -0600 Subject: [PATCH] Schnorr NIZKs. --- src/protocol/mod.rs | 1 + src/protocol/nizk.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/protocol/nizk.rs diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index b928332..fd284a4 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -36,6 +36,7 @@ use snark::*; mod secrets; mod spair; +mod nizk; mod multicore; pub use self::secrets::*; use self::spair::*; diff --git a/src/protocol/nizk.rs b/src/protocol/nizk.rs new file mode 100644 index 0000000..7d6fc71 --- /dev/null +++ b/src/protocol/nizk.rs @@ -0,0 +1,64 @@ +use bn::*; +use rand::Rng; + +/// Hash a group element with BLAKE2b and interpret it as an +/// element of Fr. +fn hash_group_to_fr(r: &G) -> Fr { + use bincode::SizeLimit::Infinite; + use bincode::rustc_serialize::encode; + use blake2_rfc::blake2b::blake2b; + + let serialized = encode(r, Infinite).unwrap(); + + let mut hash = [0; 64]; + hash.copy_from_slice(blake2b(64, &[], &serialized).as_bytes()); + + Fr::interpret(&hash) +} + +#[derive(Clone, RustcEncodable, RustcDecodable)] +pub struct Nizk { + r: G, + u: Fr +} + +impl Nizk { + /// Constructing the non-interactive schnorr proof for knowledge of log + /// of s*f in base f, i.e., knowledge of s + fn new(f: G, s: Fr, rng: &mut R) -> Nizk { + let a = Fr::random(rng); + let r = f * a; + let c = hash_group_to_fr(&r); + Nizk { + r: r, + u: a + c * s + } + } + + /// Verify the Nizk + fn verify(&self, f: G, fs: G) -> bool { + let c = hash_group_to_fr(&self.r); + + (f * self.u) == (self.r + fs * c) + } +} + +#[test] +fn nizk_test() { + fn nizk_test_group() { + let rng = &mut ::rand::thread_rng(); + for _ in 0..50 { + let f = G::random(rng); + let s = Fr::random(rng); + let fs = f * s; + + let proof = Nizk::new(f, s, rng); + assert!(proof.verify(f, fs)); + assert!(!proof.verify(f, f * Fr::random(rng))); + assert!(!proof.verify(f * Fr::random(rng), fs)); + } + } + + nizk_test_group::(); + nizk_test_group::(); +}