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

Poseidon hash #114

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
14 changes: 14 additions & 0 deletions plonk-hashing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ std = []

[dependencies]
plonk-core = { path = "../plonk-core" }
ark-ec = { version = "0.3", features = ["std"] }
ark-ff = { version = "0.3", features = ["std"] }
ark-serialize = { version = "0.3", features = ["derive"] }
ark-poly = "0.3"
ark-poly-commit = "0.3"
ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false }
ark-std = { version = "^0.3.0", default-features = false }
itertools = { version = "0.10.1", default-features = false }
num-traits = "0.2.14"
derivative = { version = "2.2.0", default-features = false, features = ["use_core"] }
hashbrown = { version = "0.11.2", default-features = false, features = ["ahash"] }
ark-relations = "0.3.0"
ark-r1cs-std = "0.3.1"
thiserror = "1.0.30"
9 changes: 7 additions & 2 deletions plonk-hashing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

//! PLONK Hashing Library

#![cfg_attr(not(any(feature = "std", test)), no_std)]
// #![cfg_attr(not(any(feature = "std", test)), no_std)]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![forbid(rustdoc::broken_intra_doc_links)]
#![forbid(missing_docs)]
// #![forbid(missing_docs)]

#[macro_use]
pub extern crate ark_std;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not depend on ark_std and use the core and alloc libraries instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, took care of this. There were two spots (here and here ) where Manta's implementation uses ark_ff::vec and I was unsure whether to remove these. It compiles fine without these imports--can you confirm that it's safe to remove them?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ark_ff::vec should be removed in favor of alloc::vec. It's just a re-export.


pub mod poseidon;
80 changes: 80 additions & 0 deletions plonk-hashing/src/poseidon/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::poseidon::{
matrix::Matrix,
mds::{factor_to_sparse_matrixes, MdsMatrices, SparseMatrix},
preprocessing::compress_round_constants,
round_constant::generate_constants,
round_numbers::calc_round_numbers,
};
use ark_ff::PrimeField;
use ark_std::convert::TryInto;
use ark_std::vec::*;

#[derive(Clone, Debug, PartialEq)]
pub struct PoseidonConstants<F: PrimeField> {
pub mds_matrices: MdsMatrices<F>,
pub round_constants: Vec<F>,
pub compressed_round_constants: Vec<F>,
pub pre_sparse_matrix: Matrix<F>,
pub sparse_matrixes: Vec<SparseMatrix<F>>,
pub domain_tag: F,
pub full_rounds: usize,
pub half_full_rounds: usize,
pub partial_rounds: usize,
}

impl<F: PrimeField> PoseidonConstants<F> {
// WIDTH = arity + 1. WIDTH is the *t* in Neptune's spec
pub fn generate<const WIDTH: usize>() -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to declare WIDTH as a constant to the structure rather than the function? This way we ensure that the poseidon trait and the constants used are initialised for the same width.

let arity = WIDTH - 1;
let mds_matrices = MdsMatrices::new(WIDTH);
let (num_full_rounds, num_partial_rounds) =
calc_round_numbers(WIDTH, true);

debug_assert_eq!(num_full_rounds % 2, 0);
let num_half_full_rounds = num_full_rounds / 2;
let round_constants = generate_constants(
1, // prime field
1, // sbox
F::size_in_bits() as u16,
WIDTH.try_into().expect("WIDTH is too large"),
num_full_rounds
.try_into()
.expect("num_full_rounds is too large"),
num_partial_rounds
.try_into()
.expect("num_partial_rounds is too large"),
);
let domain_tag = F::from(((1 << arity) - 1) as u64);

let compressed_round_constants = compress_round_constants(
WIDTH,
num_full_rounds,
num_partial_rounds,
&round_constants,
&mds_matrices,
);

let (pre_sparse_matrix, sparse_matrixes) = factor_to_sparse_matrixes(
mds_matrices.m.clone(),
num_partial_rounds,
);

assert!(
WIDTH * (num_full_rounds + num_partial_rounds)
<= round_constants.len(),
"Not enough round constants"
);

PoseidonConstants {
mds_matrices,
round_constants,
domain_tag,
full_rounds: num_full_rounds,
half_full_rounds: num_half_full_rounds,
partial_rounds: num_partial_rounds,
compressed_round_constants,
pre_sparse_matrix,
sparse_matrixes,
}
}
}
Loading