Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sponge API refactor #146

Merged
merged 29 commits into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
460cbb6
Implement ark-sponge for a new RescueSponge struct
tessico Nov 22, 2022
9d3656f
Replace all usages of Permutation::sponge with new struct
tessico Nov 24, 2022
e1bd82d
Merge branch 'main' into ark-sponge-traits
tessico Nov 29, 2022
df7cdf0
Update primitives/src/rescue/sponge.rs
tessico Nov 30, 2022
abbdfad
Add missing license information to sponge.rs
tessico Nov 30, 2022
15ac8e8
use PhantomData from ark_std
tessico Nov 30, 2022
b2bb4c7
remove unused code
tessico Nov 30, 2022
c094a0d
Remove `_expected_size` param since impl accepts non-multiples of chunk
tessico Nov 30, 2022
e908f37
Unify naming of const to CHUNK_SIZE
tessico Nov 30, 2022
ef81c46
Replace the hardcoded integers with appropriate constants for sponge
tessico Nov 30, 2022
97e9c08
enforce correct usage of CRHF and PRF
tessico Nov 30, 2022
3e52bba
Rename RescueSpongeCRHF -> RescueCRH, RescueSpongePRF -> RescuePRF
tessico Nov 30, 2022
1d15387
Change `RescueCRH` and `PRF` from Rust types to newtype structs
tessico Nov 30, 2022
8ef1f14
Panic with `unimplemented` on methods we don't use and don't test
tessico Nov 30, 2022
3ec4b32
use internal `CHUNK_SIZE` instead of `RATE`
tessico Nov 30, 2022
de0ad53
Add a `permutation: Permutation<F>` field to the `RescueSponge` struct
tessico Nov 30, 2022
f42a428
Merge branch 'main' into ark-sponge-traits
tessico Dec 5, 2022
98b9f6e
Remove unnecessary constructor, since `RescueCRH` methods are stateless
tessico Dec 5, 2022
995ec47
Fill and unify `unimplemented` messages
tessico Dec 5, 2022
ae2bbe1
Rename CRH -> CRHF as per github discussion consensus
tessico Dec 5, 2022
e6e330d
Finally remove `sponge...` methods from the `Permutation` struct
tessico Dec 5, 2022
0e5538d
Rename `CHUNK_SIZE` to `RATE`
tessico Dec 5, 2022
c0be216
Update public docs and code comments for sponge
tessico Dec 5, 2022
b19891d
fixup! Finally remove `sponge...` methods from the `Permutation` struct
tessico Dec 5, 2022
d55e477
Update CHANGELOG
tessico Dec 6, 2022
0e89961
Merge branch 'main' into ark-sponge-traits
tessico Dec 6, 2022
a7b0aac
Merge branch 'main' into ark-sponge-traits
tessico Dec 8, 2022
2c817a4
Be very explicit about supported trait functions for CryptographicSponge
tessico Dec 8, 2022
a25088e
Merge branch 'main' into ark-sponge-traits
tessico Dec 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ and follow [semantic versioning](https://semver.org/) for our releases.
- [#144](https://github.com/EspressoSystems/jellyfish/pull/144) (`jf-primitives`) Updated append-only merkle tree gadget with the latest MT API
- [#119](https://github.com/EspressoSystems/jellyfish/pull/119) (all) Updated dependencies
- Upgraded `criterion` from `0.3.1` to `0.4.0`
- [#146](https://github.com/EspressoSystems/jellyfish/pull/146) (`jf-primitives`) Refactored Rescue sponge API:
- Remove all `.*sponge.*` methods from `Permutation`.
- Introduce `RescueCRHF` which takes over `sponge_with_padding` and `sponge_no_padding` from `Permutation`.
- Introduce `RescuePRF` which takes over `full_state_keyed_sponge_with_padding` and `full_state_keyed_sponge_no_padding` from `Permutation`.

### Fixed

Expand Down
6 changes: 2 additions & 4 deletions plonk/src/transcript/rescue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ark_ec::{
use ark_std::vec::Vec;
use jf_primitives::{
pcs::prelude::Commitment,
rescue::{Permutation as RescueHash, RescueParameter, STATE_SIZE},
rescue::{sponge::RescueCRHF, RescueParameter, STATE_SIZE},
};
use jf_relation::gadgets::ecc::{Point, SWToTEConParam};
use jf_utils::{bytes_to_field_elements, field_switching, fq_to_fr_with_mask};
Expand Down Expand Up @@ -176,10 +176,8 @@ where
// 2. challenge = state[0] in Fr
// 3. transcript = Vec::new()

let hasher = RescueHash::default();

let input = [self.state.as_ref(), self.transcript.as_ref()].concat();
let tmp = hasher.sponge_with_padding(&input, STATE_SIZE);
let tmp = RescueCRHF::sponge_with_padding(&input, STATE_SIZE);
let challenge = fq_to_fr_with_mask::<F, E::Fr>(&tmp[0]);
self.state.copy_from_slice(&tmp);
self.transcript = Vec::new();
Expand Down
1 change: 1 addition & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ark-ed-on-bn254 = "0.3.0"
ark-ff = "0.3.0"
ark-poly = "0.3.0"
ark-serialize = "0.3.0"
ark-sponge = "0.3.0"
ark-std = { version = "0.3.0", default-features = false }
blst = "0.3.10"
crypto_box = "0.8.1"
Expand Down
4 changes: 2 additions & 2 deletions primitives/src/circuit/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

use crate::{
circuit::rescue::RescueGadget,
rescue::{RescueParameter, RATE},
rescue::{RescueParameter, CRHF_RATE},
utils::pad_with,
};
use ark_std::vec;
Expand All @@ -33,7 +33,7 @@ where
fn commit(&mut self, input: &[Variable], blinding: Variable) -> Result<Variable, CircuitError> {
let mut msg = vec![blinding];
msg.extend_from_slice(input);
pad_with(&mut msg, RATE, self.zero());
pad_with(&mut msg, CRHF_RATE, self.zero());
Ok(self.rescue_sponge_no_padding(&msg, 1)?[0])
}
}
Expand Down
26 changes: 9 additions & 17 deletions primitives/src/circuit/rescue/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,8 @@ mod tests {

use super::{RescueGadget, RescueHelperGadget, RescueStateVar};
use crate::rescue::{
Permutation, RescueMatrix, RescueParameter, RescueVector, PRP, RATE, STATE_SIZE,
sponge::{RescueCRHF, RescuePRF},
Permutation, RescueMatrix, RescueParameter, RescueVector, CRHF_RATE, PRP, STATE_SIZE,
};
use ark_ed_on_bls12_377::Fq as FqEd377;
use ark_ed_on_bls12_381::Fq as FqEd381;
Expand Down Expand Up @@ -965,14 +966,13 @@ mod tests {
let mut circuit = PlonkCircuit::new_turbo_plonk();

let mut prng = ark_std::test_rng();
let data = (0..2 * RATE).map(|_| F::rand(&mut prng)).collect_vec();
let data = (0..2 * CRHF_RATE).map(|_| F::rand(&mut prng)).collect_vec();
let data_vars = data
.iter()
.map(|&x| circuit.create_variable(x).unwrap())
.collect_vec();

let rescue_perm = Permutation::default();
let expected_sponge = rescue_perm.sponge_no_padding(&data, 1).unwrap()[0];
let expected_sponge = RescueCRHF::sponge_no_padding(&data, 1).unwrap()[0];
let sponge_var = circuit
.rescue_sponge_no_padding(data_vars.as_slice(), 1)
.unwrap()[0];
Expand All @@ -987,7 +987,7 @@ mod tests {
// If the data length is not a multiple of RATE==3 then an error is triggered
let mut circuit = PlonkCircuit::<F>::new_turbo_plonk();

let size = 2 * RATE + 1; // Non multiple of RATE
let size = 2 * CRHF_RATE + 1; // Non multiple of RATE
let data = (0..size).map(|_| F::rand(&mut prng)).collect_vec();
let data_vars = data
.iter()
Expand Down Expand Up @@ -1022,17 +1022,13 @@ mod tests {
.rescue_sponge_no_padding(&input_var, output_len)
.unwrap();

let rescue_hash = Permutation::default();

// Check consistency between inputs
for i in 0..rate {
assert_eq!(input_vec[i], circuit.witness(input_var[i]).unwrap());
}

// Check consistency between outputs
let expected_hash = rescue_hash
.sponge_no_padding(&input_vec, output_len)
.unwrap();
let expected_hash = RescueCRHF::sponge_no_padding(&input_vec, output_len).unwrap();

for (e, f) in out_var.iter().zip(expected_hash.iter()) {
assert_eq!(*f, circuit.witness(*e).unwrap());
Expand Down Expand Up @@ -1087,15 +1083,13 @@ mod tests {
.rescue_sponge_with_padding(&input_var, output_len)
.unwrap();

let rescue_hash = Permutation::default();

// Check consistency between inputs
for i in 0..input_len {
assert_eq!(input_vec[i], circuit.witness(input_var[i]).unwrap());
}

// Check consistency between outputs
let expected_hash = rescue_hash.sponge_with_padding(&input_vec, output_len);
let expected_hash = RescueCRHF::sponge_with_padding(&input_vec, output_len);

for (&e, &f) in expected_hash.iter().zip(out_var.iter()) {
assert_eq!(e, circuit.witness(f).unwrap());
Expand Down Expand Up @@ -1131,10 +1125,8 @@ mod tests {
.map(|&x| circuit.create_variable(x).unwrap())
.collect_vec();

let perm = Permutation::default();
let expected_fsks_output = perm
.full_state_keyed_sponge_no_padding(&key, &data, 1)
.unwrap();
let expected_fsks_output =
RescuePRF::full_state_keyed_sponge_no_padding(&key, &data, 1).unwrap();

let fsks_var = circuit
.rescue_full_state_keyed_sponge_no_padding(key_var, &data_vars)
Expand Down
30 changes: 12 additions & 18 deletions primitives/src/circuit/rescue/non_native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,8 @@ mod tests {

use super::{RescueNonNativeGadget, RescueNonNativeHelperGadget, RescueNonNativeStateVar};
use crate::rescue::{
Permutation, RescueMatrix, RescueParameter, RescueVector, PRP, RATE, STATE_SIZE,
sponge::{RescueCRHF, RescuePRF},
Permutation, RescueMatrix, RescueParameter, RescueVector, CRHF_RATE, PRP, STATE_SIZE,
};
use ark_bls12_377::Fq as Fq377;
use ark_ed_on_bls12_377::Fq as FqEd377;
Expand Down Expand Up @@ -1063,16 +1064,15 @@ mod tests {
let mut prng = ark_std::test_rng();

// setup the inputs
let data_t: Vec<T> = (0..2 * RATE).map(|_| T::rand(&mut prng)).collect_vec();
let data_t: Vec<T> = (0..2 * CRHF_RATE).map(|_| T::rand(&mut prng)).collect_vec();
let data_f: Vec<F> = data_t.iter().map(|x| field_switching(x)).collect();
let data_vars: Vec<FpElemVar<F>> = data_f
.iter()
.map(|x| FpElemVar::new_from_field_element(&mut circuit, x, m, None).unwrap())
.collect();

// sponge no padding with output length 1
let rescue_perm = Permutation::<T>::default();
let expected_sponge = rescue_perm.sponge_no_padding(&data_t, 1).unwrap()[0];
let expected_sponge = RescueCRHF::sponge_no_padding(&data_t, 1).unwrap()[0];
let sponge_var = circuit
.rescue_sponge_no_padding::<T>(data_vars.as_slice(), 1)
.unwrap()[0];
Expand All @@ -1091,8 +1091,7 @@ mod tests {

// general sponge no padding
for output_len in 1..max_output_len {
let rescue_perm = Permutation::<T>::default();
let expected_sponge = rescue_perm.sponge_no_padding(&data_t, output_len).unwrap();
let expected_sponge = RescueCRHF::sponge_no_padding(&data_t, output_len).unwrap();
let sponge_var = circuit
.rescue_sponge_no_padding::<T>(data_vars.as_slice(), output_len)
.unwrap();
Expand All @@ -1111,7 +1110,7 @@ mod tests {
// If the data length is not a multiple of RATE==3 then an error is triggered
let mut circuit = PlonkCircuit::<F>::new_ultra_plonk(RANGE_BIT_LEN_FOR_TEST);

let size = 2 * RATE + 1; // Non multiple of RATE
let size = 2 * CRHF_RATE + 1; // Non multiple of RATE
let data_t = (0..size).map(|_| T::rand(&mut prng)).collect_vec();
let data_f: Vec<F> = data_t.iter().map(|x| field_switching(x)).collect();
let data_vars: Vec<FpElemVar<F>> = data_f
Expand Down Expand Up @@ -1153,8 +1152,7 @@ mod tests {
.map(|x| FpElemVar::new_from_field_element(&mut circuit, x, m, None).unwrap())
.collect();

let rescue_perm = Permutation::<T>::default();
let expected_sponge = rescue_perm.sponge_with_padding(&data_t, 1);
let expected_sponge = RescueCRHF::sponge_with_padding(&data_t, 1);

// sponge with padding
let sponge_var = circuit
Expand All @@ -1175,8 +1173,7 @@ mod tests {

// sponge full with padding
for output_len in 1..max_output_len {
let rescue_perm = Permutation::<T>::default();
let expected_sponge = rescue_perm.sponge_with_padding(&data_t, output_len);
let expected_sponge = RescueCRHF::sponge_with_padding(&data_t, output_len);

let sponge_var = circuit
.rescue_sponge_with_padding::<T>(data_vars.as_slice(), output_len)
Expand Down Expand Up @@ -1220,16 +1217,15 @@ mod tests {
.rescue_sponge_no_padding::<T>(&input_var, 1)
.unwrap()[0];

let rescue_hash = Permutation::<T>::default();

// Check consistency between inputs
for i in 0..rate {
assert_eq!(input_vec_f[i], input_var[i].witness(&circuit).unwrap());
}

// Check consistency between outputs
let expected_hash =
rescue_hash.hash_3_to_1(&[input_vec_t[0], input_vec_t[1], input_vec_t[2]]);
RescueCRHF::sponge_no_padding(&[input_vec_t[0], input_vec_t[1], input_vec_t[2]], 1)
.unwrap()[0];
assert_eq!(
field_switching::<T, F>(&expected_hash),
out_var.witness(&circuit).unwrap()
Expand Down Expand Up @@ -1271,10 +1267,8 @@ mod tests {
})
.collect();

let perm = Permutation::<T>::default();
let expected_fsks_output = perm
.full_state_keyed_sponge_no_padding(&key_t, &data_t, 1)
.unwrap();
let expected_fsks_output =
RescuePRF::full_state_keyed_sponge_no_padding(&key_t, &data_t, 1).unwrap();

let fsks_var = circuit
.rescue_full_state_keyed_sponge_no_padding::<T>(key_var, &data_vars)
Expand Down
12 changes: 7 additions & 5 deletions primitives/src/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,29 @@

//! Implements a rescue hash based commitment scheme.

use ark_std::marker::PhantomData;

use crate::{
errors::PrimitivesError,
rescue::{Permutation, RescueParameter, RATE},
rescue::{sponge::RescueCRHF, RescueParameter, CRHF_RATE},
};
use ark_std::{format, string::String, vec};
use jf_utils::pad_with_zeros;

#[derive(Default)]
/// Commitment instance for user defined input size (in scalar elements)
pub struct Commitment<F: RescueParameter> {
hash: Permutation<F>,
input_len: usize,
phantom_f: PhantomData<F>,
}

impl<F: RescueParameter> Commitment<F> {
/// Create a new commitment instance for inputs of length `input_len`
pub fn new(input_len: usize) -> Commitment<F> {
assert!(input_len > 0, "input_len must be positive");
Commitment {
hash: Permutation::default(),
input_len,
phantom_f: PhantomData,
}
}
/// Commits to `input` slice using blinding `blind`. Return
Expand All @@ -44,8 +46,8 @@ impl<F: RescueParameter> Commitment<F> {
let mut msg = vec![*blind];
msg.extend_from_slice(input);
// Ok to pad with 0's since input length is fixed for the commitment instance
pad_with_zeros(&mut msg, RATE);
let result_vec = self.hash.sponge_no_padding(msg.as_slice(), 1)?;
pad_with_zeros(&mut msg, CRHF_RATE);
let result_vec = RescueCRHF::sponge_no_padding(msg.as_slice(), 1)?;
Ok(result_vec[0])
}
/// Verifies `commitment` against `input` and `blind`.
Expand Down
8 changes: 3 additions & 5 deletions primitives/src/merkle_tree/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! E.g. Sparse merkle tree with BigUInt index.

use super::{append_only::MerkleTree, prelude::RescueHash, DigestAlgorithm, Element, Index};
use crate::rescue::{Permutation, RescueParameter};
use crate::rescue::{sponge::RescueCRHF, RescueParameter};
use ark_ff::Field;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write};
use sha3::{Digest, Sha3_256};
Expand All @@ -21,14 +21,12 @@ pub struct Interval<F: Field>(pub F, pub F);

impl<F: RescueParameter> DigestAlgorithm<Interval<F>, u64, F> for RescueHash<F> {
fn digest(data: &[F]) -> F {
let perm = Permutation::default();
perm.sponge_no_padding(data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(data, 1).unwrap()[0]
}

fn digest_leaf(pos: &u64, elem: &Interval<F>) -> F {
let data = [F::from(*pos), elem.0, elem.1];
let perm = Permutation::default();
perm.sponge_no_padding(&data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(&data, 1).unwrap()[0]
}
}

Expand Down
14 changes: 5 additions & 9 deletions primitives/src/merkle_tree/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use crate::{
},
};

use crate::rescue::{Permutation, RescueParameter};
use crate::rescue::{sponge::RescueCRHF, RescueParameter};
use ark_std::marker::PhantomData;
use num_bigint::BigUint;
use typenum::U3;
Expand All @@ -28,14 +28,12 @@ pub struct RescueHash<F: RescueParameter> {

impl<F: RescueParameter> DigestAlgorithm<F, u64, F> for RescueHash<F> {
fn digest(data: &[F]) -> F {
let perm = Permutation::default();
perm.sponge_no_padding(data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(data, 1).unwrap()[0]
}

fn digest_leaf(pos: &u64, elem: &F) -> F {
let data = [F::zero(), F::from(*pos), *elem];
let perm = Permutation::default();
perm.sponge_no_padding(&data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(&data, 1).unwrap()[0]
}
}

Expand All @@ -44,14 +42,12 @@ pub type RescueMerkleTree<F> = MerkleTree<F, RescueHash<F>, u64, U3, F>;

impl<F: RescueParameter> DigestAlgorithm<F, BigUint, F> for RescueHash<F> {
fn digest(data: &[F]) -> F {
let perm = Permutation::default();
perm.sponge_no_padding(data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(data, 1).unwrap()[0]
}

fn digest_leaf(pos: &BigUint, elem: &F) -> F {
let data = [F::zero(), F::from(pos.clone()), *elem];
let perm = Permutation::default();
perm.sponge_no_padding(&data, 1).unwrap()[0]
RescueCRHF::<F>::sponge_no_padding(&data, 1).unwrap()[0]
}
}

Expand Down
Loading