Skip to content

Commit

Permalink
Refactor using naming conventions of the academic paper.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaker committed Mar 4, 2025
1 parent 2bdaec7 commit cd50ddb
Show file tree
Hide file tree
Showing 33 changed files with 227 additions and 1,213 deletions.
4 changes: 2 additions & 2 deletions nimue-anemoi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use ark_ff::{Field, PrimeField};
use zeroize::Zeroize;

use nimue::hash::sponge::Sponge;
use nimue::duplex_sponge::Permutation;

#[derive(Clone, Zeroize)]
pub struct AnemoiState<F: Field, const R: usize, const N: usize>([F; N]);
Expand All @@ -32,7 +32,7 @@ pub type AnemoiBls12_381_2_1 = AnemoiState<anemoi::bls12_381::Felt, 2, 1>;
use anemoi::bls12_381::anemoi_2_1::AnemoiBls12_381_2_1 as _AnemoiBls12_381_2_1;
use anemoi::Anemoi;

impl Sponge
impl Permutation
for AnemoiState<
anemoi::bls12_381::Felt,
{ _AnemoiBls12_381_2_1::RATE },
Expand Down
26 changes: 13 additions & 13 deletions nimue-poseidon/examples/schnorr_algebraic_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use ark_ec::{CurveGroup, PrimeGroup};
use ark_ff::PrimeField;
use ark_std::UniformRand;
use nimue::plugins::ark::*;
use nimue::codecs::ark::*;

/// Extend the IO pattern with the Schnorr protocol.
trait SchnorrIOPattern<G: CurveGroup> {
Expand All @@ -16,7 +16,7 @@ impl<G, H, U> SchnorrIOPattern<G> for IOPattern<H, U>
where
G: CurveGroup,
U: Unit,
H: DuplexHash<U>,
H: DuplexInterface<U>,
IOPattern<H, U>: GroupIOPattern<G> + ByteIOPattern,
{
fn add_schnorr_io(self) -> Self {
Expand All @@ -39,15 +39,15 @@ fn keygen<G: CurveGroup>() -> (G::ScalarField, G) {
}

/// The prove algorithm takes as input
/// - the prover state `Merlin`, that has access to a random oracle `H` and can absorb/squeeze elements from the group `G`.
/// - the prover state `ProverTranscript`, that has access to a random oracle `H` and can absorb/squeeze elements from the group `G`.
/// - The generator `P` in the group.
/// - the secret key $x \in \mathbb{Z}_p$
/// It returns a zero-knowledge proof of knowledge of `x` as a sequence of bytes.
#[allow(non_snake_case)]
fn prove<G, H, U>(
// the hash function `H` works over bytes.
// Algebraic hashes over a particular domain can be denoted with an additional type argument implementing `nimue::Unit`.
merlin: &mut Merlin<H, U>,
merlin: &mut ProverTranscript<H, U>,
// the generator
P: G,
// the secret key
Expand All @@ -56,11 +56,11 @@ fn prove<G, H, U>(
where
U: Unit,
G::BaseField: PrimeField,
H: DuplexHash<U>,
H: DuplexInterface<U>,
G: CurveGroup,
Merlin<H, U>: GroupWriter<G> + FieldWriter<G::BaseField> + ByteChallenges,
ProverTranscript<H, U>: GroupWriter<G> + FieldWriter<G::BaseField> + ByteChallenges,
{
// `Merlin` types implement a cryptographically-secure random number generator that is tied to the protocol transcript
// `ProverTranscript` types implement a cryptographically-secure random number generator that is tied to the protocol transcript
// and that can be accessed via the `rng()` function.
let k = G::ScalarField::rand(merlin.rng());
let K = P * k;
Expand All @@ -83,14 +83,14 @@ where
}

/// The verify algorithm takes as input
/// - the verifier state `Arthur`, that has access to a random oracle `H` and can deserialize/squeeze elements from the group `G`.
/// - the verifier state `VerifierTranscript`, that has access to a random oracle `H` and can deserialize/squeeze elements from the group `G`.
/// - the secret key `witness`
/// It returns a zero-knowledge proof of knowledge of `witness` as a sequence of bytes.
#[allow(non_snake_case)]
fn verify<'a, G, H, U>(
// `ArkGroupMelin` contains the veirifier state, including the messages currently read. In addition, it is aware of the group `G`
// from which it can serialize/deserialize elements.
arthur: &mut Arthur<'a, H, U>,
arthur: &mut VerifierTranscript<'a, H, U>,
// The group generator `P``
P: G,
// The public key `X`
Expand All @@ -100,8 +100,8 @@ where
U: Unit,
G::BaseField: PrimeField,
G: CurveGroup,
H: DuplexHash<U>,
Arthur<'a, H, U>: GroupReader<G> + FieldReader<G::BaseField> + ByteChallenges,
H: DuplexInterface<U>,
VerifierTranscript<'a, H, U>: GroupReader<G> + FieldReader<G::BaseField> + ByteChallenges,
{
// Read the protocol from the transcript:
let [K] = arthur.next_points()?;
Expand All @@ -128,7 +128,7 @@ fn main() {

// Set the hash function (commented out other valid choices):
// type H = nimue::hash::Keccak;
type H = nimue::hash::legacy::DigestBridge<blake2::Blake2s256>;
type H = nimue::duplex_sponge::legacy::DigestBridge<blake2::Blake2s256>;
// type H = nimue::hash::legacy::DigestBridge<sha2::Sha256>;
// type H = nimue_poseidon::PoseidonHash;

Expand All @@ -154,7 +154,7 @@ fn main() {
println!("Here's a Schnorr signature:\n{}", hex::encode(proof));

// Verify the proof: create the verifier transcript, add the statement to it, and invoke the verifier.
let mut arthur = Arthur::<H, U>::new(&io, &proof);
let mut arthur = VerifierTranscript::<H, U>::new(&io, &proof);
arthur.public_points(&[P, X]).unwrap();
arthur.ratchet().unwrap();
verify(&mut arthur, P, X).expect("Invalid proof");
Expand Down
2 changes: 1 addition & 1 deletion nimue-poseidon/src/bls12_381.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use nimue::hash::sponge::DuplexSponge;
use nimue::duplex_sponge::DuplexSponge;

poseidon_sponge!(255, PoseidonPermx5_255_3, x5_255_3);
poseidon_sponge!(255, PoseidonPermx5_255_5, x5_255_5);
Expand Down
9 changes: 5 additions & 4 deletions nimue-poseidon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use std::fmt::Debug;

use ark_ff::PrimeField;
use nimue::hash::sponge::DuplexSponge;
use nimue::hash::sponge::Sponge;
use nimue::hash::Unit;
use nimue::duplex_sponge::DuplexSponge;
use nimue::duplex_sponge::Permutation;
use nimue::duplex_sponge::Unit;

/// Poseidon Sponge.
///
Expand Down Expand Up @@ -91,7 +91,8 @@ impl<const NAME: u32, F: PrimeField, const R: usize, const N: usize> zeroize::Ze
}
}

impl<const NAME: u32, F, const R: usize, const N: usize> Sponge for PoseidonSponge<NAME, F, R, N>
impl<const NAME: u32, F, const R: usize, const N: usize> Permutation
for PoseidonSponge<NAME, F, R, N>
where
PoseidonSponge<NAME, F, R, N>: Default,
F: PrimeField + Unit,
Expand Down
6 changes: 3 additions & 3 deletions nimue-poseidon/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nimue::hash::sponge::Sponge;
use nimue::duplex_sponge::Permutation;

#[allow(unused)]
fn test_vector<H: Sponge>(input: &[H::U], output: &[H::U])
fn test_vector<H: Permutation>(input: &[H::U], output: &[H::U])
where
H::U: PartialEq + std::fmt::Debug,
{
Expand All @@ -20,7 +20,7 @@ fn test_squeeze_bytes_from_algebraic_hash() {
type H = crate::bls12_381::Poseidonx5_255_3;

let io = nimue::IOPattern::<H, F>::new("test").absorb(1, "in");
let io = <nimue::IOPattern<H, F> as nimue::plugins::ark::ByteIOPattern>::challenge_bytes(
let io = <nimue::IOPattern<H, F> as nimue::codecs::ark::ByteIOPattern>::challenge_bytes(
io, 2048, "out",
);
let mut merlin = io.to_merlin();
Expand Down
16 changes: 8 additions & 8 deletions nimue-pow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ pub mod blake3;
pub mod keccak;

use nimue::{
Arthur, ByteChallenges, ByteIOPattern, ByteReader, ByteWriter, DuplexHash, Merlin, ProofError,
ProofResult, Unit,
ByteChallenges, ByteIOPattern, ByteReader, ByteWriter, DuplexInterface, ProofError,
ProofResult, ProverTranscript, Unit, VerifierTranscript,
};

/// [`IOPattern`] for proof-of-work challenges.
Expand Down Expand Up @@ -36,12 +36,12 @@ pub trait PoWChallenge {
fn challenge_pow<S: PowStrategy>(&mut self, bits: f64) -> ProofResult<()>;
}

impl<H, U, R> PoWChallenge for Merlin<H, U, R>
impl<H, U, R> PoWChallenge for ProverTranscript<H, U, R>
where
U: Unit,
H: DuplexHash<U>,
H: DuplexInterface<U>,
R: rand::CryptoRng + rand::RngCore,
Merlin<H, U, R>: ByteWriter + ByteChallenges,
ProverTranscript<H, U, R>: ByteWriter + ByteChallenges,
{
fn challenge_pow<S: PowStrategy>(&mut self, bits: f64) -> ProofResult<()> {
let challenge = self.challenge_bytes()?;
Expand All @@ -53,11 +53,11 @@ where
}
}

impl<'a, H, U> PoWChallenge for Arthur<'a, H, U>
impl<'a, H, U> PoWChallenge for VerifierTranscript<'a, H, U>
where
U: Unit,
H: DuplexHash<U>,
Arthur<'a, H, U>: ByteReader + ByteChallenges,
H: DuplexInterface<U>,
VerifierTranscript<'a, H, U>: ByteReader + ByteChallenges,
{
fn challenge_pow<S: PowStrategy>(&mut self, bits: f64) -> ProofResult<()> {
let challenge = self.challenge_bytes()?;
Expand Down
10 changes: 5 additions & 5 deletions nimue/examples/bulletproof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use ark_ec::PrimeGroup;
use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM};
use ark_ff::Field;
use ark_std::log2;
use nimue::plugins::ark::*;
use nimue::codecs::ark::*;
use rand::rngs::OsRng;

/// The IO Pattern of a bulleproof.
Expand Down Expand Up @@ -46,13 +46,13 @@ where
}

fn prove<'a, G: CurveGroup>(
merlin: &'a mut Merlin,
merlin: &'a mut ProverTranscript,
generators: (&[G::Affine], &[G::Affine], &G::Affine),
statement: &G, // the actual inner-roduct of the witness is not really needed
witness: (&[G::ScalarField], &[G::ScalarField]),
) -> ProofResult<&'a [u8]>
where
Merlin: GroupWriter<G> + FieldChallenges<G::ScalarField>,
ProverTranscript: GroupWriter<G> + FieldChallenges<G::ScalarField>,
{
assert_eq!(witness.0.len(), witness.1.len());

Expand Down Expand Up @@ -97,13 +97,13 @@ where
}

fn verify<G: CurveGroup>(
arthur: &mut Arthur,
arthur: &mut VerifierTranscript,
generators: (&[G::Affine], &[G::Affine], &G::Affine),
mut n: usize,
statement: &G,
) -> ProofResult<()>
where
for<'a> Arthur<'a>: GroupReader<G> + FieldChallenges<G::ScalarField>,
for<'a> VerifierTranscript<'a>: GroupReader<G> + FieldChallenges<G::ScalarField>,
{
let mut g = generators.0.to_vec();
let mut h = generators.1.to_vec();
Expand Down
28 changes: 14 additions & 14 deletions nimue/examples/schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
/// - V -> P: c, a challenge (scalar)
/// - P -> V: r, a response (scalar)
///
/// 2. `nimue::Merlin`, describes the prover state. It contains the transcript, but not only:
/// 2. `nimue::ProverTranscript`, describes the prover state. It contains the transcript, but not only:
/// it also provides a CSPRNG and a reliable way of serializing elements into a proof, so that the prover does not have to worry about them.
/// It can be instantiated via `IOPattern::to_merlin()`.
///
/// 3. `nimue::Arthur`, describes the verifier state.
/// 3. `nimue::VerifierTranscript`, describes the verifier state.
/// It internally will read the transcript, and deserialize elements as requested making sure that they match with the IO Pattern.
/// It can be used to verify a proof.
use ark_ec::{CurveGroup, PrimeGroup};
use ark_std::UniformRand;
use nimue::plugins::ark::*;
use nimue::codecs::ark::*;
use rand::rngs::OsRng;

/// Extend the IO pattern with the Schnorr protocol.
Expand All @@ -37,7 +37,7 @@ trait SchnorrIOPattern<G: CurveGroup> {
impl<G, H> SchnorrIOPattern<G> for IOPattern<H>
where
G: CurveGroup,
H: DuplexHash,
H: DuplexInterface,
IOPattern<H>: GroupIOPattern<G> + FieldIOPattern<G::ScalarField>,
{
fn new_schnorr_proof(domsep: &str) -> Self {
Expand Down Expand Up @@ -69,26 +69,26 @@ fn keygen<G: CurveGroup>() -> (G::ScalarField, G) {
}

/// The prove algorithm takes as input
/// - the prover state `Merlin`, that has access to a random oracle `H` and can absorb/squeeze elements from the group `G`.
/// - the prover state `ProverTranscript`, that has access to a random oracle `H` and can absorb/squeeze elements from the group `G`.
/// - The generator `P` in the group.
/// - the secret key $x \in \mathbb{Z}_p$
/// It returns a zero-knowledge proof of knowledge of `x` as a sequence of bytes.
#[allow(non_snake_case)]
fn prove<H, G>(
// the hash function `H` works over bytes.
// Algebraic hashes over a particular domain can be denoted with an additional type argument implementing `nimue::Unit`.
merlin: &mut Merlin<H>,
merlin: &mut ProverTranscript<H>,
// the generator
P: G,
// the secret key
x: G::ScalarField,
) -> ProofResult<&[u8]>
where
H: DuplexHash,
H: DuplexInterface,
G: CurveGroup,
Merlin<H>: GroupWriter<G> + FieldChallenges<G::ScalarField>,
ProverTranscript<H>: GroupWriter<G> + FieldChallenges<G::ScalarField>,
{
// `Merlin` types implement a cryptographically-secure random number generator that is tied to the protocol transcript
// `ProverTranscript` types implement a cryptographically-secure random number generator that is tied to the protocol transcript
// and that can be accessed via the `rng()` function.
let k = G::ScalarField::rand(merlin.rng());
let K = P * k;
Expand All @@ -109,23 +109,23 @@ where
}

/// The verify algorithm takes as input
/// - the verifier state `Arthur`, that has access to a random oracle `H` and can deserialize/squeeze elements from the group `G`.
/// - the verifier state `VerifierTranscript`, that has access to a random oracle `H` and can deserialize/squeeze elements from the group `G`.
/// - the secret key `witness`
/// It returns a zero-knowledge proof of knowledge of `witness` as a sequence of bytes.
#[allow(non_snake_case)]
fn verify<G, H>(
// `ArkGroupMelin` contains the veirifier state, including the messages currently read. In addition, it is aware of the group `G`
// from which it can serialize/deserialize elements.
arthur: &mut Arthur<H>,
arthur: &mut VerifierTranscript<H>,
// The group generator `P``
P: G,
// The public key `X`
X: G,
) -> ProofResult<()>
where
G: CurveGroup,
H: DuplexHash,
for<'a> Arthur<'a, H>:
H: DuplexInterface,
for<'a> VerifierTranscript<'a, H>:
GroupReader<G> + FieldReader<G::ScalarField> + FieldChallenges<G::ScalarField>,
{
// Read the protocol from the transcript.
Expand Down Expand Up @@ -160,7 +160,7 @@ fn main() {
type G = ark_curve25519::EdwardsProjective;
// Set the hash function (commented out other valid choices):
// type H = nimue::hash::Keccak;
type H = nimue::hash::legacy::DigestBridge<blake2::Blake2s256>;
type H = nimue::duplex_sponge::legacy::DigestBridge<blake2::Blake2s256>;
// type H = nimue::hash::legacy::DigestBridge<sha2::Sha256>;

// Set up the IO for the protocol transcript with domain separator "nimue::examples::schnorr"
Expand Down
Loading

0 comments on commit cd50ddb

Please # to comment.