diff --git a/tfhe-zk-pok/src/proofs/pke_v2/hashes.rs b/tfhe-zk-pok/src/proofs/pke_v2/hashes.rs new file mode 100644 index 000000000..7b15a83e1 --- /dev/null +++ b/tfhe-zk-pok/src/proofs/pke_v2/hashes.rs @@ -0,0 +1,773 @@ +/// Scalar generation using the hash random oracle +use crate::{ + curve_api::{Curve, FieldOps}, + proofs::pke_v2::{compute_crs_params, inf_norm_bound_to_euclidean_squared}, +}; + +use super::{PKEv2DomainSeparators, PublicCommit, PublicParams}; + +// The scalar used for the proof are generated using sha3 as a random oracle. The inputs of the hash +// that generates a given scalar are reused for the subsequent hashes. We use the typestate pattern +// to propagate the inputs from one hash to the next. + +struct RInputs<'a> { + ds: &'a PKEv2DomainSeparators, + sid_bytes: Box<[u8]>, + metadata: &'a [u8], + x_bytes: Box<[u8]>, + C_hat_e_bytes: &'a [u8], + C_e_bytes: &'a [u8], + C_r_tilde_bytes: &'a [u8], + D: usize, + m: usize, + n: usize, + k: usize, + d: usize, +} + +pub(super) struct RHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, +} + +impl<'a> RHash<'a> { + pub(super) fn new( + public: (&'a PublicParams, &PublicCommit), + metadata: &'a [u8], + C_hat_e_bytes: &'a [u8], + C_e_bytes: &'a [u8], + C_r_tilde_bytes: &'a [u8], + ) -> (Box<[i8]>, Self) { + let ( + &PublicParams { + g_lists: _, + D: _, + n, + d, + k: _, + B_bound_squared: _, + B_inf, + q, + t: t_input, + msbs_zero_padding_bit_count, + bound_type, + sid, + domain_separators: ref ds, + }, + PublicCommit { a, b, c1, c2, .. }, + ) = public; + + let k = c2.len(); + let B_squared = inf_norm_bound_to_euclidean_squared(B_inf, d + k); + let (_, D, _, m) = compute_crs_params( + d, + k, + B_squared, + t_input, + msbs_zero_padding_bit_count, + bound_type, + ); + + let x_bytes = [ + q.to_le_bytes().as_slice(), + (d as u64).to_le_bytes().as_slice(), + B_squared.to_le_bytes().as_slice(), + t_input.to_le_bytes().as_slice(), + msbs_zero_padding_bit_count.to_le_bytes().as_slice(), + &*a.iter() + .flat_map(|&x| x.to_le_bytes()) + .collect::>(), + &*b.iter() + .flat_map(|&x| x.to_le_bytes()) + .collect::>(), + &*c1.iter() + .flat_map(|&x| x.to_le_bytes()) + .collect::>(), + &*c2.iter() + .flat_map(|&x| x.to_le_bytes()) + .collect::>(), + ] + .iter() + .copied() + .flatten() + .copied() + .collect::>(); + + let sid_bytes = Box::from(sid.to_le_bytes().as_slice()); + + // make R_bar a random number generator from the given bytes + use sha3::digest::{ExtendableOutput, Update, XofReader}; + + let mut hasher = sha3::Shake256::default(); + for &data in &[ + ds.hash_R(), + &sid_bytes, + metadata, + &x_bytes, + C_hat_e_bytes, + C_e_bytes, + C_r_tilde_bytes, + ] { + hasher.update(data); + } + let mut R_bar = hasher.finalize_xof(); + let R = (0..128 * (2 * (d + k) + 4)) + .map(|_| { + let mut byte = 0u8; + R_bar.read(core::slice::from_mut(&mut byte)); + + // take two bits + match byte & 0b11 { + // probability 1/2 + 0 | 1 => 0, + // probability 1/4 + 2 => 1, + // probability 1/4 + 3 => -1, + _ => unreachable!(), + } + }) + .collect::>(); + + let R_coeffs = |i: usize, j: usize| R[i + j * 128]; + let R_bytes = (0..128) + .flat_map(|i| (0..(2 * (d + k) + 4)).map(move |j| R_coeffs(i, j) as u8)) + .collect(); + + ( + R, + Self { + R_inputs: RInputs { + ds, + sid_bytes, + metadata, + x_bytes, + C_hat_e_bytes, + C_e_bytes, + C_r_tilde_bytes, + D, + m, + n, + k, + d, + }, + + R_bytes, + }, + ) + } + + pub(super) fn gen_phi(self, C_R_bytes: &'a [u8]) -> ([Zp; 128], PhiHash<'a>) { + let Self { R_inputs, R_bytes } = self; + + let mut phi = [Zp::ZERO; 128]; + Zp::hash( + &mut phi, + &[ + R_inputs.ds.hash_phi(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &R_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + C_R_bytes, + R_inputs.C_r_tilde_bytes, + ], + ); + let phi_bytes = phi + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + phi, + PhiHash { + R_inputs, + phi_inputs: PhiInputs { C_R_bytes }, + R_bytes, + phi_bytes, + }, + ) + } +} + +struct PhiInputs<'a> { + C_R_bytes: &'a [u8], +} + +pub(super) struct PhiHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, +} + +impl<'a> PhiHash<'a> { + pub(super) fn gen_xi(self, C_hat_bin_bytes: &'a [u8]) -> ([Zp; 128], XiHash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + } = self; + + let mut xi = [Zp::ZERO; 128]; + Zp::hash( + &mut xi, + &[ + R_inputs.ds.hash_xi(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + &phi_bytes, + phi_inputs.C_R_bytes, + C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + ], + ); + + let xi_bytes = xi + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + xi, + XiHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs: XiInputs { C_hat_bin_bytes }, + xi_bytes, + }, + ) + } +} + +struct XiInputs<'a> { + C_hat_bin_bytes: &'a [u8], +} + +pub(super) struct XiHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, +} + +impl<'a> XiHash<'a> { + pub(super) fn gen_y(self) -> (Vec, YHash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + } = self; + + let mut y = vec![Zp::ZERO; R_inputs.D + 128 * R_inputs.m]; + Zp::hash( + &mut y, + &[ + R_inputs.ds.hash(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &R_bytes, + &phi_bytes, + &xi_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + ], + ); + let y_bytes = y + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + y, + YHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + }, + ) + } +} + +pub(super) struct YHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, +} + +impl<'a> YHash<'a> { + pub(super) fn gen_t(self, C_y_bytes: &'a [u8]) -> (Vec, THash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + } = self; + + let mut t = vec![Zp::ZERO; R_inputs.n]; + Zp::hash_128bit( + &mut t, + &[ + R_inputs.ds.hash_t(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &phi_bytes, + &xi_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + C_y_bytes, + ], + ); + let t_bytes = t + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + t, + THash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs: TInputs { C_y_bytes }, + t_bytes, + }, + ) + } +} + +struct TInputs<'a> { + C_y_bytes: &'a [u8], +} + +pub(super) struct THash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, + t_inputs: TInputs<'a>, + t_bytes: Box<[u8]>, +} + +impl<'a> THash<'a> { + pub(super) fn gen_theta(self) -> (Vec, ThetaHash<'a>) { + let Self { + R_inputs, + phi_inputs, + xi_inputs, + t_inputs, + t_bytes, + R_bytes, + phi_bytes, + xi_bytes, + y_bytes, + } = self; + + let mut theta = vec![Zp::ZERO; R_inputs.d + R_inputs.k]; + Zp::hash( + &mut theta, + &[ + R_inputs.ds.hash_lmap(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &t_bytes, + &phi_bytes, + &xi_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + t_inputs.C_y_bytes, + ], + ); + let theta_bytes = theta + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + theta, + ThetaHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + }, + ) + } +} + +pub(super) struct ThetaHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, + t_inputs: TInputs<'a>, + t_bytes: Box<[u8]>, + theta_bytes: Box<[u8]>, +} + +impl<'a> ThetaHash<'a> { + pub(super) fn gen_omega(self) -> (Vec, OmegaHash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + } = self; + + let mut omega = vec![Zp::ZERO; R_inputs.n]; + Zp::hash_128bit( + &mut omega, + &[ + R_inputs.ds.hash_w(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &t_bytes, + &phi_bytes, + &xi_bytes, + &theta_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + t_inputs.C_y_bytes, + ], + ); + let omega_bytes = omega + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + omega, + OmegaHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + omega_bytes, + }, + ) + } +} + +pub(super) struct OmegaHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, + t_inputs: TInputs<'a>, + t_bytes: Box<[u8]>, + theta_bytes: Box<[u8]>, + omega_bytes: Box<[u8]>, +} + +impl<'a> OmegaHash<'a> { + pub(super) fn gen_delta(self) -> ([Zp; 7], DeltaHash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + omega_bytes, + } = self; + + let mut delta = [Zp::ZERO; 7]; + Zp::hash( + &mut delta, + &[ + R_inputs.ds.hash_agg(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &t_bytes, + &phi_bytes, + &xi_bytes, + &theta_bytes, + &omega_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + t_inputs.C_y_bytes, + ], + ); + let delta_bytes = delta + .iter() + .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) + .collect::>(); + + ( + delta, + DeltaHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + delta_bytes, + }, + ) + } +} + +pub(super) struct DeltaHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, + t_inputs: TInputs<'a>, + t_bytes: Box<[u8]>, + theta_bytes: Box<[u8]>, + delta_bytes: Box<[u8]>, +} + +impl<'a> DeltaHash<'a> { + pub(super) fn gen_z( + self, + C_h1_bytes: &'a [u8], + C_h2_bytes: &'a [u8], + C_hat_t_bytes: &'a [u8], + C_hat_h3_bytes: &'a [u8], + C_hat_omega_bytes: &'a [u8], + ) -> (Zp, ZHash<'a>) { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + delta_bytes, + } = self; + + let mut z = Zp::ZERO; + Zp::hash( + core::slice::from_mut(&mut z), + &[ + R_inputs.ds.hash_z(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &t_bytes, + &phi_bytes, + &R_inputs.x_bytes, // x is duplicated but we have to keep it for backward compat + &theta_bytes, + &delta_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + t_inputs.C_y_bytes, + C_h1_bytes, + C_h2_bytes, + C_hat_t_bytes, + C_hat_h3_bytes, + C_hat_omega_bytes, + ], + ); + + ( + z, + ZHash { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + delta_bytes, + z_inputs: ZInputs { + C_h1_bytes, + C_h2_bytes, + C_hat_t_bytes, + C_hat_h3_bytes, + C_hat_omega_bytes, + }, + z_bytes: Box::from(z.to_le_bytes().as_ref()), + }, + ) + } +} + +struct ZInputs<'a> { + C_h1_bytes: &'a [u8], + C_h2_bytes: &'a [u8], + C_hat_t_bytes: &'a [u8], + C_hat_h3_bytes: &'a [u8], + C_hat_omega_bytes: &'a [u8], +} + +pub(super) struct ZHash<'a> { + R_inputs: RInputs<'a>, + R_bytes: Box<[u8]>, + phi_inputs: PhiInputs<'a>, + phi_bytes: Box<[u8]>, + xi_inputs: XiInputs<'a>, + xi_bytes: Box<[u8]>, + y_bytes: Box<[u8]>, + t_inputs: TInputs<'a>, + t_bytes: Box<[u8]>, + theta_bytes: Box<[u8]>, + delta_bytes: Box<[u8]>, + z_inputs: ZInputs<'a>, + z_bytes: Box<[u8]>, +} + +impl<'a> ZHash<'a> { + pub(super) fn gen_chi(self, p_h1: Zp, p_h2: Zp, p_t: Zp) -> Zp { + let Self { + R_inputs, + R_bytes, + phi_inputs, + phi_bytes, + xi_inputs, + xi_bytes, + y_bytes, + t_inputs, + t_bytes, + theta_bytes, + delta_bytes, + z_inputs, + z_bytes, + } = self; + + let mut chi = Zp::ZERO; + Zp::hash( + core::slice::from_mut(&mut chi), + &[ + R_inputs.ds.hash_chi(), + &R_inputs.sid_bytes, + R_inputs.metadata, + &R_inputs.x_bytes, + &y_bytes, + &t_bytes, + &phi_bytes, + &xi_bytes, + &theta_bytes, + &delta_bytes, + R_inputs.C_hat_e_bytes, + R_inputs.C_e_bytes, + &R_bytes, + phi_inputs.C_R_bytes, + xi_inputs.C_hat_bin_bytes, + R_inputs.C_r_tilde_bytes, + t_inputs.C_y_bytes, + z_inputs.C_h1_bytes, + z_inputs.C_h2_bytes, + z_inputs.C_hat_t_bytes, + z_inputs.C_hat_h3_bytes, + z_inputs.C_hat_omega_bytes, + &z_bytes, + p_h1.to_le_bytes().as_ref(), + p_h2.to_le_bytes().as_ref(), + p_t.to_le_bytes().as_ref(), + ], + ); + + chi + } +} diff --git a/tfhe-zk-pok/src/proofs/pke_v2.rs b/tfhe-zk-pok/src/proofs/pke_v2/mod.rs similarity index 83% rename from tfhe-zk-pok/src/proofs/pke_v2.rs rename to tfhe-zk-pok/src/proofs/pke_v2/mod.rs index 183c8fe21..e306c5c42 100644 --- a/tfhe-zk-pok/src/proofs/pke_v2.rs +++ b/tfhe-zk-pok/src/proofs/pke_v2/mod.rs @@ -15,6 +15,10 @@ use core::marker::PhantomData; use rayon::prelude::*; use serde::{Deserialize, Serialize}; +mod hashes; + +use hashes::RHash; + fn bit_iter(x: u64, nbits: u32) -> impl Iterator { (0..nbits).map(move |idx| ((x >> idx) & 1) != 0) } @@ -416,6 +420,19 @@ pub(crate) struct ComputeLoadProofFields { pub(crate) C_hat_w: G::G2, } +impl ComputeLoadProofFields { + fn to_le_bytes(fields: &Option) -> (Box<[u8]>, Box<[u8]>) { + if let Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }) = fields.as_ref() { + ( + Box::from(G::G2::to_le_bytes(*C_hat_h3).as_ref()), + Box::from(G::G2::to_le_bytes(*C_hat_w).as_ref()), + ) + } else { + (Box::from([]), Box::from([])) + } + } +} + #[derive(Serialize, Deserialize, Versionize)] #[serde(bound( deserialize = "G: Curve, CompressedG1: serde::Deserialize<'de>, CompressedG2: serde::Deserialize<'de>", @@ -821,7 +838,7 @@ fn prove_impl( t: t_input, msbs_zero_padding_bit_count, bound_type, - sid, + sid: _, domain_separators: ref ds, }, PublicCommit { a, b, c1, c2, .. }, @@ -939,69 +956,18 @@ fn prove_impl( }, ); - let x_bytes = &*[ - q.to_le_bytes().as_slice(), - (d as u64).to_le_bytes().as_slice(), - B_squared.to_le_bytes().as_slice(), - t_input.to_le_bytes().as_slice(), - msbs_zero_padding_bit_count.to_le_bytes().as_slice(), - &*a.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*b.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*c1.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*c2.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - ] - .iter() - .copied() - .flatten() - .copied() - .collect::>(); + let C_hat_e_bytes = C_hat_e.to_le_bytes(); + let C_e_bytes = C_e.to_le_bytes(); + let C_r_tilde_bytes = C_r_tilde.to_le_bytes(); - // make R_bar a random number generator from the given bytes - use sha3::digest::{ExtendableOutput, Update, XofReader}; - - let mut hasher = sha3::Shake256::default(); - for &data in &[ - ds.hash_R(), - sid.to_le_bytes().as_slice(), + let (R, R_hash) = RHash::new( + public, metadata, - x_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ] { - hasher.update(data); - } - let mut R_bar = hasher.finalize_xof(); - let R = (0..128 * (2 * (d + k) + 4)) - .map(|_| { - let mut byte = 0u8; - R_bar.read(core::slice::from_mut(&mut byte)); - - // take two bits - match byte & 0b11 { - // probability 1/2 - 0 | 1 => 0, - // probability 1/4 - 2 => 1, - // probability 1/4 - 3 => -1, - _ => unreachable!(), - } - }) - .collect::>(); - + C_hat_e_bytes.as_ref(), + C_e_bytes.as_ref(), + C_r_tilde_bytes.as_ref(), + ); let R = |i: usize, j: usize| R[i + j * 128]; - let R_bytes = &*(0..128) - .flat_map(|i| (0..(2 * (d + k) + 4)).map(move |j| R(i, j) as u8)) - .collect::>(); let w_R = (0..128) .map(|i| { @@ -1041,25 +1007,8 @@ fn prove_impl( .collect::>(), ); - let mut phi = vec![G::Zp::ZERO; 128]; - G::Zp::hash( - &mut phi, - &[ - ds.hash_phi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - R_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_R.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); - let phi_bytes = &*phi - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let C_R_bytes = C_R.to_le_bytes(); + let (phi, phi_hash) = R_hash.gen_phi(C_R_bytes.as_ref()); let m = m_bound; @@ -1082,51 +1031,10 @@ fn prove_impl( .map(G::G2::projective) .sum::(); - let mut xi = vec![G::Zp::ZERO; 128]; - G::Zp::hash( - &mut xi, - &[ - ds.hash_xi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - phi_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); + let C_hat_bin_bytes = C_hat_bin.to_le_bytes(); + let (xi, xi_hash) = phi_hash.gen_xi::(C_hat_bin_bytes.as_ref()); - let xi_bytes = &*xi - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); - - let mut y = vec![G::Zp::ZERO; D + 128 * m]; - G::Zp::hash( - &mut y, - &[ - ds.hash(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - R_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); - let y_bytes = &*y - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let (y, y_hash) = xi_hash.gen_y(); if sanity_check_mode == ProofSanityCheckMode::Panic { assert_eq!(y.len(), w_bin.len()); @@ -1140,56 +1048,10 @@ fn prove_impl( let C_y = g.mul_scalar(gamma_y) + G::G1::multi_mul_scalar(&g_list[n - (D + 128 * m)..n], &scalars); - let mut t = vec![G::Zp::ZERO; n]; - G::Zp::hash_128bit( - &mut t, - &[ - ds.hash_t(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let t_bytes = &*t - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let C_y_bytes = C_y.to_le_bytes(); + let (t, t_hash) = y_hash.gen_t(C_y_bytes.as_ref()); - let mut theta = vec![G::Zp::ZERO; d + k]; - G::Zp::hash( - &mut theta, - &[ - ds.hash_lmap(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let theta_bytes = &*theta - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let (theta, theta_hash) = t_hash.gen_theta(); let mut a_theta = vec![G::Zp::ZERO; D]; compute_a_theta::(&mut a_theta, &theta, a, k, b, effective_cleartext_t, delta); @@ -1201,61 +1063,10 @@ fn prove_impl( .map(|(x, y)| x * y) .sum::(); - let mut w = vec![G::Zp::ZERO; n]; - G::Zp::hash_128bit( - &mut w, - &[ - ds.hash_w(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let w_bytes = &*w - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let (omega, omega_hash) = theta_hash.gen_omega(); - let mut delta = [G::Zp::ZERO; 7]; - G::Zp::hash( - &mut delta, - &[ - ds.hash_agg(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - w_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); + let (delta, delta_hash) = omega_hash.gen_delta::(); let [delta_r, delta_dec, delta_eq, delta_y, delta_theta, delta_e, delta_l] = delta; - let delta_bytes = &*delta - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); let mut poly_0_lhs = vec![G::Zp::ZERO; 1 + n]; let mut poly_0_rhs = vec![G::Zp::ZERO; 1 + D + 128 * m]; @@ -1270,7 +1081,7 @@ fn prove_impl( let mut poly_5_lhs = vec![G::Zp::ZERO; 1 + n]; let mut poly_5_rhs = vec![G::Zp::ZERO; 1 + n]; - let mut xi_scaled = xi.clone(); + let mut xi_scaled = xi; poly_0_lhs[0] = delta_y * gamma_y; for j in 0..D + 128 * m { let p = &mut poly_0_lhs[n - j]; @@ -1326,7 +1137,7 @@ fn prove_impl( for j in 0..n { let p = &mut poly_1_lhs[n - j]; - let mut acc = delta_e * w[j]; + let mut acc = delta_e * omega[j]; if j < d + k { acc += delta_theta * theta[j]; } @@ -1413,7 +1224,7 @@ fn prove_impl( for j in 0..d + k + 4 { let p = &mut poly_4_rhs[1 + j]; - *p = w[j]; + *p = omega[j]; } poly_5_lhs[0] = delta_eq * gamma_y; @@ -1507,7 +1318,7 @@ fn prove_impl( g.mul_scalar(P_pi[0]) + G::G1::multi_mul_scalar(&g_list[..P_pi.len() - 1], &P_pi[1..]) }; - let mut xi_scaled = xi.clone(); + let mut xi_scaled = xi; let mut scalars = (0..D + 128 * m) .map(|j| { let mut acc = G::Zp::ZERO; @@ -1545,7 +1356,7 @@ fn prove_impl( acc += delta_theta * theta[j]; } - acc += delta_e * w[j]; + acc += delta_e * omega[j]; if j < d + k + 4 { let mut acc2 = G::Zp::ZERO; @@ -1587,7 +1398,7 @@ fn prove_impl( .collect::>(), ) }, - || G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &w[..d + k + 4]), + || G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &omega[..d + k + 4]), ); Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }) @@ -1595,49 +1406,21 @@ fn prove_impl( ComputeLoad::Verify => None, }; - let byte_generators = - if let Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }) = compute_load_proof_fields { - Some((G::G2::to_le_bytes(C_hat_h3), G::G2::to_le_bytes(C_hat_w))) - } else { - None - }; - - let (C_hat_h3_bytes, C_hat_w_bytes): (&[u8], &[u8]) = - if let Some((C_hat_h3_bytes_owner, C_hat_w_bytes_owner)) = byte_generators.as_ref() { - (C_hat_h3_bytes_owner.as_ref(), C_hat_w_bytes_owner.as_ref()) - } else { - (&[], &[]) - }; - let C_hat_t = G::G2::multi_mul_scalar(g_hat_list, &t); - let mut z = G::Zp::ZERO; - G::Zp::hash( - core::slice::from_mut(&mut z), - &[ - ds.hash_z(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - x_bytes, - theta_bytes, - delta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - C_h1.to_le_bytes().as_ref(), - C_h2.to_le_bytes().as_ref(), - C_hat_t.to_le_bytes().as_ref(), - C_hat_h3_bytes, - C_hat_w_bytes, - ], + let (C_hat_h3_bytes, C_hat_w_bytes) = + ComputeLoadProofFields::to_le_bytes(&compute_load_proof_fields); + + let C_h1_bytes = C_h1.to_le_bytes(); + let C_h2_bytes = C_h2.to_le_bytes(); + let C_hat_t_bytes = C_hat_t.to_le_bytes(); + + let (z, z_hash) = delta_hash.gen_z( + C_h1_bytes.as_ref(), + C_h2_bytes.as_ref(), + C_hat_t_bytes.as_ref(), + &C_hat_h3_bytes, + &C_hat_w_bytes, ); let mut P_h1 = vec![G::Zp::ZERO; 1 + n]; @@ -1652,7 +1435,7 @@ fn prove_impl( ComputeLoad::Verify => vec![], }; - let mut xi_scaled = xi.clone(); + let mut xi_scaled = xi; for j in 0..D + 128 * m { let p = &mut P_h1[n - j]; if j < D { @@ -1684,7 +1467,7 @@ fn prove_impl( *p += delta_theta * theta[j]; } - *p += delta_e * w[j]; + *p += delta_e * omega[j]; if j < d + k + 4 { let mut acc = G::Zp::ZERO; @@ -1720,7 +1503,7 @@ fn prove_impl( } if !P_w.is_empty() { - P_w[1..].copy_from_slice(&w[..d + k + 4]); + P_w[1..].copy_from_slice(&omega[..d + k + 4]); } let mut p_h1 = G::Zp::ZERO; @@ -1745,38 +1528,7 @@ fn prove_impl( pow = pow * z; } - let mut chi = G::Zp::ZERO; - G::Zp::hash( - core::slice::from_mut(&mut chi), - &[ - ds.hash_chi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - delta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - C_h1.to_le_bytes().as_ref(), - C_h2.to_le_bytes().as_ref(), - C_hat_t.to_le_bytes().as_ref(), - C_hat_h3_bytes, - C_hat_w_bytes, - z.to_le_bytes().as_ref(), - p_h1.to_le_bytes().as_ref(), - p_h2.to_le_bytes().as_ref(), - p_t.to_le_bytes().as_ref(), - ], - ); + let chi = z_hash.gen_chi(p_h1, p_h2, p_t); let mut Q_kzg = vec![G::Zp::ZERO; 1 + n]; let chi2 = chi * chi; @@ -1967,8 +1719,8 @@ pub fn verify_impl( t: t_input, msbs_zero_padding_bit_count, bound_type, - sid, - domain_separators: ref ds, + sid: _, + domain_separators: _, } = public.0; let g_list = &*g_lists.g_list.0; let g_hat_list = &*g_lists.g_hat_list.0; @@ -2004,227 +1756,31 @@ pub fn verify_impl( return Err(()); } - let byte_generators = if let Some(&ComputeLoadProofFields { C_hat_h3, C_hat_w }) = - compute_load_proof_fields.as_ref() - { - Some((G::G2::to_le_bytes(C_hat_h3), G::G2::to_le_bytes(C_hat_w))) - } else { - None - }; + let C_hat_e_bytes = C_hat_e.to_le_bytes(); + let C_e_bytes = C_e.to_le_bytes(); + let C_r_tilde_bytes = C_r_tilde.to_le_bytes(); - let (C_hat_h3_bytes, C_hat_w_bytes): (&[u8], &[u8]) = - if let Some((C_hat_h3_bytes_owner, C_hat_w_bytes_owner)) = byte_generators.as_ref() { - (C_hat_h3_bytes_owner.as_ref(), C_hat_w_bytes_owner.as_ref()) - } else { - (&[], &[]) - }; - - let x_bytes = &*[ - q.to_le_bytes().as_slice(), - (d as u64).to_le_bytes().as_slice(), - B_squared.to_le_bytes().as_slice(), - t_input.to_le_bytes().as_slice(), - msbs_zero_padding_bit_count.to_le_bytes().as_slice(), - &*a.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*b.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*c1.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - &*c2.iter() - .flat_map(|&x| x.to_le_bytes()) - .collect::>(), - ] - .iter() - .copied() - .flatten() - .copied() - .collect::>(); - - // make R_bar a random number generator from the given bytes - use sha3::digest::{ExtendableOutput, Update, XofReader}; - - let mut hasher = sha3::Shake256::default(); - for &data in &[ - ds.hash_R(), - sid.to_le_bytes().as_slice(), + let (R, R_hash) = RHash::new( + public, metadata, - x_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ] { - hasher.update(data); - } - let mut R_bar = hasher.finalize_xof(); - let R = (0..128 * (2 * (d + k) + 4)) - .map(|_| { - let mut byte = 0u8; - R_bar.read(core::slice::from_mut(&mut byte)); - - // take two bits - match byte & 0b11 { - // probability 1/2 - 0 | 1 => 0, - // probability 1/4 - 2 => 1, - // probability 1/4 - 3 => -1, - _ => unreachable!(), - } - }) - .collect::>(); - + C_hat_e_bytes.as_ref(), + C_e_bytes.as_ref(), + C_r_tilde_bytes.as_ref(), + ); let R = |i: usize, j: usize| R[i + j * 128]; - let R_bytes = &*(0..128) - .flat_map(|i| (0..(2 * (d + k) + 4)).map(move |j| R(i, j) as u8)) - .collect::>(); - let mut phi = vec![G::Zp::ZERO; 128]; - G::Zp::hash( - &mut phi, - &[ - ds.hash_phi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - R_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_R.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); - let phi_bytes = &*phi - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let C_R_bytes = C_R.to_le_bytes(); + let (phi, phi_hash) = R_hash.gen_phi(C_R_bytes.as_ref()); - let mut xi = vec![G::Zp::ZERO; 128]; - G::Zp::hash( - &mut xi, - &[ - ds.hash_xi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - phi_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); - let xi_bytes = &*xi - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let C_hat_bin_bytes = C_hat_bin.to_le_bytes(); + let (xi, xi_hash) = phi_hash.gen_xi::(C_hat_bin_bytes.as_ref()); - let mut y = vec![G::Zp::ZERO; D + 128 * m]; - G::Zp::hash( - &mut y, - &[ - ds.hash(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - R_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - ], - ); - let y_bytes = &*y - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let (y, y_hash) = xi_hash.gen_y(); - let mut t = vec![G::Zp::ZERO; n]; - G::Zp::hash_128bit( - &mut t, - &[ - ds.hash_t(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let t_bytes = &*t - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let C_y_bytes = C_y.to_le_bytes(); + let (t, t_hash) = y_hash.gen_t(C_y_bytes.as_ref()); - let mut theta = vec![G::Zp::ZERO; d + k]; - G::Zp::hash( - &mut theta, - &[ - ds.hash_lmap(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let theta_bytes = &*theta - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); - - let mut w = vec![G::Zp::ZERO; n]; - G::Zp::hash_128bit( - &mut w, - &[ - ds.hash_w(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); - let w_bytes = &*w - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); + let (theta, theta_hash) = t_hash.gen_theta(); let mut a_theta = vec![G::Zp::ZERO; D]; compute_a_theta::(&mut a_theta, &theta, a, k, b, effective_cleartext_t, delta); @@ -2236,34 +1792,10 @@ pub fn verify_impl( .map(|(x, y)| x * y) .sum::(); - let mut delta = [G::Zp::ZERO; 7]; - G::Zp::hash( - &mut delta, - &[ - ds.hash_agg(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - w_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - ], - ); + let (omega, omega_hash) = theta_hash.gen_omega(); + + let (delta, delta_hash) = omega_hash.gen_delta(); let [delta_r, delta_dec, delta_eq, delta_y, delta_theta, delta_e, delta_l] = delta; - let delta_bytes = &*delta - .iter() - .flat_map(|x| x.to_le_bytes().as_ref().to_vec()) - .collect::>(); let g = G::G1::GENERATOR; let g_hat = G::G2::GENERATOR; @@ -2319,7 +1851,7 @@ pub fn verify_impl( C_hat_h3: _, C_hat_w, }) => C_hat_w, - None => G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &w[..d + k + 4]), + None => G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &omega[..d + k + 4]), }, ); let lhs5 = pairing(C_y.mul_scalar(delta_eq), C_hat_t); @@ -2336,41 +1868,27 @@ pub fn verify_impl( return Err(()); } - let mut z = G::Zp::ZERO; - G::Zp::hash( - core::slice::from_mut(&mut z), - &[ - ds.hash_z(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - x_bytes, - theta_bytes, - delta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - C_h1.to_le_bytes().as_ref(), - C_h2.to_le_bytes().as_ref(), - C_hat_t.to_le_bytes().as_ref(), - C_hat_h3_bytes, - C_hat_w_bytes, - ], - ); - let load = if compute_load_proof_fields.is_some() { ComputeLoad::Proof } else { ComputeLoad::Verify }; + let (C_hat_h3_bytes, C_hat_w_bytes) = + ComputeLoadProofFields::to_le_bytes(compute_load_proof_fields); + + let C_h1_bytes = C_h1.to_le_bytes(); + let C_h2_bytes = C_h2.to_le_bytes(); + let C_hat_t_bytes = C_hat_t.to_le_bytes(); + + let (z, z_hash) = delta_hash.gen_z( + C_h1_bytes.as_ref(), + C_h2_bytes.as_ref(), + C_hat_t_bytes.as_ref(), + &C_hat_h3_bytes, + &C_hat_w_bytes, + ); + let mut P_h1 = vec![G::Zp::ZERO; 1 + n]; let mut P_h2 = vec![G::Zp::ZERO; 1 + n]; let mut P_t = vec![G::Zp::ZERO; 1 + n]; @@ -2383,7 +1901,7 @@ pub fn verify_impl( ComputeLoad::Verify => vec![], }; - let mut xi_scaled = xi.clone(); + let mut xi_scaled = xi; for j in 0..D + 128 * m { let p = &mut P_h1[n - j]; if j < D { @@ -2415,7 +1933,7 @@ pub fn verify_impl( *p += delta_theta * theta[j]; } - *p += delta_e * w[j]; + *p += delta_e * omega[j]; if j < d + k + 4 { let mut acc = G::Zp::ZERO; @@ -2451,7 +1969,7 @@ pub fn verify_impl( } if !P_w.is_empty() { - P_w[1..].copy_from_slice(&w[..d + k + 4]); + P_w[1..].copy_from_slice(&omega[..d + k + 4]); } let mut p_h1 = G::Zp::ZERO; @@ -2476,38 +1994,8 @@ pub fn verify_impl( pow = pow * z; } - let mut chi = G::Zp::ZERO; - G::Zp::hash( - core::slice::from_mut(&mut chi), - &[ - ds.hash_chi(), - sid.to_le_bytes().as_slice(), - metadata, - x_bytes, - y_bytes, - t_bytes, - phi_bytes, - xi_bytes, - theta_bytes, - delta_bytes, - C_hat_e.to_le_bytes().as_ref(), - C_e.to_le_bytes().as_ref(), - R_bytes, - C_R.to_le_bytes().as_ref(), - C_hat_bin.to_le_bytes().as_ref(), - C_r_tilde.to_le_bytes().as_ref(), - C_y.to_le_bytes().as_ref(), - C_h1.to_le_bytes().as_ref(), - C_h2.to_le_bytes().as_ref(), - C_hat_t.to_le_bytes().as_ref(), - C_hat_h3_bytes, - C_hat_w_bytes, - z.to_le_bytes().as_ref(), - p_h1.to_le_bytes().as_ref(), - p_h2.to_le_bytes().as_ref(), - p_t.to_le_bytes().as_ref(), - ], - ); + let chi = z_hash.gen_chi(p_h1, p_h2, p_t); + let chi2 = chi * chi; let chi3 = chi2 * chi; let chi4 = chi3 * chi;