feat(zk): add randomness to hash functions

This commit is contained in:
sarah el kazdadi
2024-06-19 11:21:39 +02:00
committed by sarah
parent 9cd7aeccf5
commit 44c64210ca
5 changed files with 214 additions and 25 deletions

View File

@@ -3,15 +3,24 @@ use super::*;
#[derive(Clone, Debug)]
pub struct PublicParams<G: Curve> {
g_lists: GroupElements<G>,
hash: [u8; HASH_METADATA_LEN_BYTES],
hash_t: [u8; HASH_METADATA_LEN_BYTES],
hash_agg: [u8; HASH_METADATA_LEN_BYTES],
}
impl<G: Curve> PublicParams<G> {
pub fn from_vec(
g_list: Vec<Affine<G::Zp, G::G1>>,
g_hat_list: Vec<Affine<G::Zp, G::G2>>,
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<G: Curve>(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<G: Curve>(
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<G: Curve>(
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<G: Curve>(
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<G: Curve>(
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;

View File

@@ -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<G: Curve> GroupElements<G> {
}
}
pub const HASH_METADATA_LEN_BYTES: usize = 256;
pub mod binary;
pub mod index;
pub mod pke;

View File

@@ -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<G: Curve> {
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<G: Curve> PublicParams<G> {
@@ -35,6 +40,12 @@ impl<G: Curve> PublicParams<G> {
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::<G>::from_vec(g_list, g_hat_list),
@@ -46,6 +57,12 @@ impl<G: Curve> PublicParams<G> {
b_r,
q,
t,
hash,
hash_t,
hash_agg,
hash_lmap,
hash_z,
hash_w,
}
}
@@ -133,6 +150,12 @@ pub fn crs_gen<G: Curve>(
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<G: Curve>(
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<G: Curve>(
.collect::<Box<_>>();
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<G: Curve>(
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: Curve>(
G::Zp::hash_128bit(
&mut t,
&[
hash_t,
&(1..n + 1)
.flat_map(|i| y[i].to_bytes().as_ref().to_vec())
.collect::<Box<_>>(),
@@ -357,7 +392,12 @@ pub fn prove<G: Curve>(
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: Curve>(
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: Curve>(
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<G: Curve>(
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<G: Curve>(
.collect::<Box<_>>();
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: Curve>(
G::Zp::hash_128bit(
&mut t,
&[
hash_t,
&(1..n + 1)
.flat_map(|i| y[i].to_bytes().as_ref().to_vec())
.collect::<Box<_>>(),
@@ -751,7 +805,12 @@ pub fn verify<G: Curve>(
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: Curve>(
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: Curve>(
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(),

View File

@@ -3,15 +3,27 @@ use super::*;
#[derive(Clone, Debug)]
pub struct PublicParams<G: Curve> {
g_lists: GroupElements<G>,
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<G: Curve> PublicParams<G> {
pub fn from_vec(
g_list: Vec<Affine<G::Zp, G::G1>>,
g_hat_list: Vec<Affine<G::Zp, G::G2>>,
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<G: Curve>(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<G: Curve>(
) -> Proof<G> {
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<G: Curve>(
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: Curve>(
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: Curve>(
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: Curve>(
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<G: Curve>(
) -> 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<G: Curve>(
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: Curve>(
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: Curve>(
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: Curve>(
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(),

View File

@@ -15,9 +15,16 @@ pub struct PublicParams<G: Curve> {
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<G: Curve> PublicParams<G> {
#[allow(clippy::too_many_arguments)]
pub fn from_vec(
g_list: Vec<Affine<G::Zp, G::G1>>,
g_hat_list: Vec<Affine<G::Zp, G::G2>>,
@@ -26,6 +33,12 @@ impl<G: Curve> PublicParams<G> {
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<G: Curve> PublicParams<G> {
big_m,
b_i,
q,
hash,
hash_t,
hash_agg,
hash_lmap,
hash_z,
hash_w,
}
}
}
@@ -86,6 +105,12 @@ pub fn crs_gen<G: Curve>(
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<G: Curve>(
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<G: Curve>(
.collect::<Box<_>>();
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: Curve>(
G::Zp::hash(
&mut t,
&[
hash_t,
&(1..n + 1)
.flat_map(|i| y[i].to_bytes().as_ref().to_vec())
.collect::<Box<_>>(),
@@ -323,7 +355,12 @@ pub fn prove<G: Curve>(
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::<Box<_>>();
let theta0 = theta[..big_n * d].to_vec().into_boxed_slice();
@@ -402,7 +439,12 @@ pub fn prove<G: Curve>(
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: Curve>(
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: Curve>(
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<G: Curve>(
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<G: Curve>(
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::<Box<_>>(),
@@ -648,7 +704,12 @@ pub fn verify<G: Curve>(
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::<Box<_>>();
let theta0 = theta[..big_n * d].to_vec().into_boxed_slice();
@@ -729,6 +790,7 @@ pub fn verify<G: Curve>(
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: Curve>(
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(),