diff --git a/tfhe-zk-pok/src/proofs/binary.rs b/tfhe-zk-pok/src/proofs/binary.rs index 7c324acbc0..9ba8c3a867 100644 --- a/tfhe-zk-pok/src/proofs/binary.rs +++ b/tfhe-zk-pok/src/proofs/binary.rs @@ -3,15 +3,24 @@ use super::*; #[derive(Clone, Debug)] pub struct PublicParams { g_lists: GroupElements, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], } impl PublicParams { pub fn from_vec( g_list: Vec>, g_hat_list: Vec>, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], ) -> Self { Self { g_lists: GroupElements::from_vec(g_list, g_hat_list), + hash, + hash_t, + hash_agg, } } } @@ -43,6 +52,9 @@ pub fn crs_gen(message_len: usize, rng: &mut dyn RngCore) -> PublicPar let alpha = G::Zp::rand(rng); PublicParams { g_lists: GroupElements::new(message_len, alpha), + hash: core::array::from_fn(|_| rng.gen()), + hash_t: core::array::from_fn(|_| rng.gen()), + hash_agg: core::array::from_fn(|_| rng.gen()), } } @@ -90,7 +102,7 @@ pub fn prove( let g_list = &public.0.g_lists.g_list; let mut y = OneBased(vec![G::Zp::ZERO; n]); - G::Zp::hash(&mut y.0, &[c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y.0, &[&public.0.hash, c_hat.to_bytes().as_ref()]); let mut c_y = g.mul_scalar(gamma_y); for j in 1..n + 1 { @@ -103,13 +115,22 @@ pub fn prove( let mut t = OneBased(vec![G::Zp::ZERO; n]); G::Zp::hash( &mut t.0, - &[y_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + &public.0.hash_t, + y_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + &public.0.hash_agg, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; @@ -170,7 +191,7 @@ pub fn verify( let c_y = proof.c_y; let mut y = OneBased(vec![G::Zp::ZERO; n]); - G::Zp::hash(&mut y.0, &[c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y.0, &[&public.0.hash, c_hat.to_bytes().as_ref()]); let y_bytes = &*(1..n + 1) .flat_map(|i| y[i].to_bytes().as_ref().to_vec()) @@ -178,13 +199,22 @@ pub fn verify( let mut t = OneBased(vec![G::Zp::ZERO; n]); G::Zp::hash( &mut t.0, - &[y_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + &public.0.hash_t, + y_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + &public.0.hash_agg, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; diff --git a/tfhe-zk-pok/src/proofs/mod.rs b/tfhe-zk-pok/src/proofs/mod.rs index 2dd235f105..65537090a5 100644 --- a/tfhe-zk-pok/src/proofs/mod.rs +++ b/tfhe-zk-pok/src/proofs/mod.rs @@ -1,10 +1,9 @@ use crate::curve_api::{Curve, CurveGroupOps, FieldOps, PairingGroupOps}; - use ark_serialize::{ CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate, }; use core::ops::{Index, IndexMut}; -use rand::RngCore; +use rand::{Rng, RngCore}; #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize)] #[repr(transparent)] @@ -137,6 +136,8 @@ impl GroupElements { } } +pub const HASH_METADATA_LEN_BYTES: usize = 256; + pub mod binary; pub mod index; pub mod pke; diff --git a/tfhe-zk-pok/src/proofs/pke.rs b/tfhe-zk-pok/src/proofs/pke.rs index 231f05fe17..c2f3a3ddd7 100644 --- a/tfhe-zk-pok/src/proofs/pke.rs +++ b/tfhe-zk-pok/src/proofs/pke.rs @@ -1,5 +1,4 @@ // TODO: refactor copy-pasted code in proof/verify -// TODO: ask about metadata in hashing functions use super::*; use core::marker::PhantomData; @@ -20,6 +19,12 @@ pub struct PublicParams { pub b_r: u64, pub q: u64, pub t: u64, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], + hash_lmap: [u8; HASH_METADATA_LEN_BYTES], + hash_z: [u8; HASH_METADATA_LEN_BYTES], + hash_w: [u8; HASH_METADATA_LEN_BYTES], } impl PublicParams { @@ -35,6 +40,12 @@ impl PublicParams { b_r: u64, q: u64, t: u64, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], + hash_lmap: [u8; HASH_METADATA_LEN_BYTES], + hash_z: [u8; HASH_METADATA_LEN_BYTES], + hash_w: [u8; HASH_METADATA_LEN_BYTES], ) -> Self { Self { g_lists: GroupElements::::from_vec(g_list, g_hat_list), @@ -46,6 +57,12 @@ impl PublicParams { b_r, q, t, + hash, + hash_t, + hash_agg, + hash_lmap, + hash_z, + hash_w, } } @@ -133,6 +150,12 @@ pub fn crs_gen( b_r, q, t, + hash: core::array::from_fn(|_| rng.gen()), + hash_t: core::array::from_fn(|_| rng.gen()), + hash_agg: core::array::from_fn(|_| rng.gen()), + hash_lmap: core::array::from_fn(|_| rng.gen()), + hash_z: core::array::from_fn(|_| rng.gen()), + hash_w: core::array::from_fn(|_| rng.gen()), } } @@ -184,6 +207,12 @@ pub fn prove( q, t, k, + ref hash, + ref hash_t, + ref hash_agg, + ref hash_lmap, + ref hash_z, + ref hash_w, } = public.0; let g_list = &g_lists.g_list; let g_hat_list = &g_lists.g_hat_list; @@ -318,7 +347,7 @@ pub fn prove( .collect::>(); let mut y = vec![G::Zp::ZERO; n]; - G::Zp::hash(&mut y, &[x_bytes, c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y, &[hash, x_bytes, c_hat.to_bytes().as_ref()]); let y = OneBased(y); let scalars = (n + 1 - big_d..n + 1) @@ -329,7 +358,12 @@ pub fn prove( let mut theta = vec![G::Zp::ZERO; d + k + 1]; G::Zp::hash( &mut theta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_lmap, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let theta0 = &theta[..d + k]; @@ -344,6 +378,7 @@ pub fn prove( G::Zp::hash_128bit( &mut t, &[ + hash_t, &(1..n + 1) .flat_map(|i| y[i].to_bytes().as_ref().to_vec()) .collect::>(), @@ -357,7 +392,12 @@ pub fn prove( let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_agg, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; let delta = [delta_eq, delta_y, delta_theta]; @@ -431,6 +471,7 @@ pub fn prove( G::Zp::hash( core::array::from_mut(&mut z), &[ + hash_z, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -470,6 +511,7 @@ pub fn prove( G::Zp::hash( core::array::from_mut(&mut w), &[ + hash_w, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -677,6 +719,12 @@ pub fn verify( q, t, k, + ref hash, + ref hash_t, + ref hash_agg, + ref hash_lmap, + ref hash_z, + ref hash_w, } = public.0; let g_list = &g_lists.g_list; let g_hat_list = &g_lists.g_hat_list; @@ -712,13 +760,18 @@ pub fn verify( .collect::>(); let mut y = vec![G::Zp::ZERO; n]; - G::Zp::hash(&mut y, &[x_bytes, c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y, &[hash, x_bytes, c_hat.to_bytes().as_ref()]); let y = OneBased(y); let mut theta = vec![G::Zp::ZERO; d + k + 1]; G::Zp::hash( &mut theta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_lmap, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let theta0 = &theta[..d + k]; let delta_theta = theta[d + k]; @@ -738,6 +791,7 @@ pub fn verify( G::Zp::hash_128bit( &mut t, &[ + hash_t, &(1..n + 1) .flat_map(|i| y[i].to_bytes().as_ref().to_vec()) .collect::>(), @@ -751,7 +805,12 @@ pub fn verify( let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_agg, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; let delta = [delta_eq, delta_y, delta_theta]; @@ -761,6 +820,7 @@ pub fn verify( G::Zp::hash( core::array::from_mut(&mut z), &[ + hash_z, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -812,6 +872,7 @@ pub fn verify( G::Zp::hash( core::array::from_mut(&mut w), &[ + hash_w, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), diff --git a/tfhe-zk-pok/src/proofs/range.rs b/tfhe-zk-pok/src/proofs/range.rs index d26270bf38..565cf41a42 100644 --- a/tfhe-zk-pok/src/proofs/range.rs +++ b/tfhe-zk-pok/src/proofs/range.rs @@ -3,15 +3,27 @@ use super::*; #[derive(Clone, Debug)] pub struct PublicParams { g_lists: GroupElements, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_s: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], } impl PublicParams { pub fn from_vec( g_list: Vec>, g_hat_list: Vec>, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_s: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], ) -> Self { Self { g_lists: GroupElements::from_vec(g_list, g_hat_list), + hash, + hash_s, + hash_t, + hash_agg, } } } @@ -45,6 +57,10 @@ pub fn crs_gen(max_nbits: usize, rng: &mut dyn RngCore) -> PublicParam let alpha = G::Zp::rand(rng); PublicParams { g_lists: GroupElements::new(max_nbits, alpha), + hash: core::array::from_fn(|_| rng.gen()), + hash_s: core::array::from_fn(|_| rng.gen()), + hash_t: core::array::from_fn(|_| rng.gen()), + hash_agg: core::array::from_fn(|_| rng.gen()), } } @@ -70,7 +86,13 @@ pub fn prove( ) -> Proof { let &PrivateCommit { x, r } = private_commit; let &PublicCommit { l, v_hat } = public.1; - let PublicParams { g_lists } = public.0; + let PublicParams { + g_lists, + hash, + hash_s, + hash_t, + hash_agg, + } = public.0; let n = g_lists.message_len; let g_list = &g_lists.g_list; @@ -123,7 +145,7 @@ pub fn prove( let mut y = vec![G::Zp::ZERO; n]; G::Zp::hash( &mut y, - &[v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref()], + &[hash, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref()], ); let y = OneBased(y); let mut c_y = g.mul_scalar(gamma_y); @@ -139,6 +161,7 @@ pub fn prove( G::Zp::hash( &mut t, &[ + hash_t, y_bytes, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), @@ -197,6 +220,7 @@ pub fn prove( G::Zp::hash( core::slice::from_mut(s), &[ + hash_s, &i.to_le_bytes(), v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), @@ -219,6 +243,7 @@ pub fn prove( G::Zp::hash( &mut delta, &[ + hash_agg, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -245,7 +270,13 @@ pub fn verify( ) -> Result<(), ()> { let e = G::Gt::pairing; let &PublicCommit { l, v_hat } = public.1; - let PublicParams { g_lists } = public.0; + let PublicParams { + g_lists, + hash, + hash_s, + hash_t, + hash_agg, + } = public.0; let n = g_lists.message_len; let g_list = &g_lists.g_list; @@ -258,7 +289,7 @@ pub fn verify( let mut y = vec![G::Zp::ZERO; n]; G::Zp::hash( &mut y, - &[v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref()], + &[hash, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref()], ); let y = OneBased(y); @@ -270,6 +301,7 @@ pub fn verify( G::Zp::hash( &mut t, &[ + hash_t, y_bytes, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), @@ -282,6 +314,7 @@ pub fn verify( G::Zp::hash( &mut delta, &[ + hash_agg, v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -294,6 +327,7 @@ pub fn verify( G::Zp::hash( core::slice::from_mut(s), &[ + hash_s, &i.to_le_bytes(), v_hat.to_bytes().as_ref(), c_hat.to_bytes().as_ref(), diff --git a/tfhe-zk-pok/src/proofs/rlwe.rs b/tfhe-zk-pok/src/proofs/rlwe.rs index de7e8077f6..d81274c9f2 100644 --- a/tfhe-zk-pok/src/proofs/rlwe.rs +++ b/tfhe-zk-pok/src/proofs/rlwe.rs @@ -15,9 +15,16 @@ pub struct PublicParams { big_m: usize, b_i: u64, q: u64, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], + hash_lmap: [u8; HASH_METADATA_LEN_BYTES], + hash_z: [u8; HASH_METADATA_LEN_BYTES], + hash_w: [u8; HASH_METADATA_LEN_BYTES], } impl PublicParams { + #[allow(clippy::too_many_arguments)] pub fn from_vec( g_list: Vec>, g_hat_list: Vec>, @@ -26,6 +33,12 @@ impl PublicParams { big_m: usize, b_i: u64, q: u64, + hash: [u8; HASH_METADATA_LEN_BYTES], + hash_t: [u8; HASH_METADATA_LEN_BYTES], + hash_agg: [u8; HASH_METADATA_LEN_BYTES], + hash_lmap: [u8; HASH_METADATA_LEN_BYTES], + hash_z: [u8; HASH_METADATA_LEN_BYTES], + hash_w: [u8; HASH_METADATA_LEN_BYTES], ) -> Self { Self { g_lists: GroupElements::from_vec(g_list, g_hat_list), @@ -34,6 +47,12 @@ impl PublicParams { big_m, b_i, q, + hash, + hash_t, + hash_agg, + hash_lmap, + hash_z, + hash_w, } } } @@ -86,6 +105,12 @@ pub fn crs_gen( big_m, b_i, q, + hash: core::array::from_fn(|_| rng.gen()), + hash_t: core::array::from_fn(|_| rng.gen()), + hash_agg: core::array::from_fn(|_| rng.gen()), + hash_lmap: core::array::from_fn(|_| rng.gen()), + hash_z: core::array::from_fn(|_| rng.gen()), + hash_w: core::array::from_fn(|_| rng.gen()), } } @@ -189,6 +214,12 @@ pub fn prove( big_m, b_i, q, + ref hash, + ref hash_t, + ref hash_agg, + ref hash_lmap, + ref hash_z, + ref hash_w, } = public.0; let g_list = &g_lists.g_list; let g_hat_list = &g_lists.g_hat_list; @@ -298,7 +329,7 @@ pub fn prove( .collect::>(); let mut y = vec![G::Zp::ZERO; n]; - G::Zp::hash(&mut y, &[x_bytes, c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y, &[hash, x_bytes, c_hat.to_bytes().as_ref()]); let y = OneBased(y); let scalars = (n + 1 - big_d..n + 1) @@ -310,6 +341,7 @@ pub fn prove( G::Zp::hash( &mut t, &[ + hash_t, &(1..n + 1) .flat_map(|i| y[i].to_bytes().as_ref().to_vec()) .collect::>(), @@ -323,7 +355,12 @@ pub fn prove( let mut theta_bar = vec![G::Zp::ZERO; big_n * d + 1]; G::Zp::hash( &mut theta_bar, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_lmap, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let theta = (0..big_n * d + 1).map(|k| theta_bar[k]).collect::>(); let theta0 = theta[..big_n * d].to_vec().into_boxed_slice(); @@ -402,7 +439,12 @@ pub fn prove( let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_agg, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; let mut poly_0 = vec![G::Zp::ZERO; n + 1]; @@ -466,6 +508,7 @@ pub fn prove( G::Zp::hash( core::array::from_mut(&mut z), &[ + hash_z, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -505,6 +548,7 @@ pub fn prove( G::Zp::hash( core::array::from_mut(&mut w), &[ + hash_w, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -588,6 +632,12 @@ pub fn verify( big_m, b_i, q, + ref hash, + ref hash_t, + ref hash_agg, + ref hash_lmap, + ref hash_z, + ref hash_w, } = public.0; let g_list = &g_lists.g_list; let g_hat_list = &g_lists.g_hat_list; @@ -623,18 +673,24 @@ pub fn verify( let mut delta = [G::Zp::ZERO; 2]; G::Zp::hash( &mut delta, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_agg, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let [delta_eq, delta_y] = delta; let mut y = vec![G::Zp::ZERO; n]; - G::Zp::hash(&mut y, &[x_bytes, c_hat.to_bytes().as_ref()]); + G::Zp::hash(&mut y, &[hash, x_bytes, c_hat.to_bytes().as_ref()]); let y = OneBased(y); let mut t = vec![G::Zp::ZERO; n]; G::Zp::hash( &mut t, &[ + hash_t, &(1..n + 1) .flat_map(|i| y[i].to_bytes().as_ref().to_vec()) .collect::>(), @@ -648,7 +704,12 @@ pub fn verify( let mut theta_bar = vec![G::Zp::ZERO; big_n * d + 1]; G::Zp::hash( &mut theta_bar, - &[x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref()], + &[ + hash_lmap, + x_bytes, + c_hat.to_bytes().as_ref(), + c_y.to_bytes().as_ref(), + ], ); let theta = (0..big_n * d + 1).map(|k| theta_bar[k]).collect::>(); let theta0 = theta[..big_n * d].to_vec().into_boxed_slice(); @@ -729,6 +790,7 @@ pub fn verify( G::Zp::hash( core::array::from_mut(&mut z), &[ + hash_z, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(), @@ -780,6 +842,7 @@ pub fn verify( G::Zp::hash( core::array::from_mut(&mut w), &[ + hash_w, x_bytes, c_hat.to_bytes().as_ref(), c_y.to_bytes().as_ref(),