-
Notifications
You must be signed in to change notification settings - Fork 118
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
Update Dev docs for Poseidon2 #710
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,85 @@ The S box power alpha, number of full rounds and partial rounds, rounds constant | |
|
||
In the current version the padding is not supported and should be performed by the user. | ||
|
||
#### Supported Bindings | ||
|
||
[`Rust`](https://github.com/ingonyama-zk/icicle/tree/main/wrappers/rust/icicle-core/src/poseidon2) | ||
[`Go`](https://github.com/ingonyama-zk/icicle/blob/main/wrappers/golang/curves/bn254/poseidon2/poseidon2.go) | ||
|
||
|
||
#### Rust API | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont understand what this should be here. Maybe in the rust page as a poseidon2 example below. |
||
|
||
This is the most basic way to use the Poseidon2 API. See the [examples/poseidon2](https://github.com/ingonyama-zk/icicle/tree/b12d83e6bcb8ee598409de78015bd118458a55d0/examples/rust/poseidon2) folder for the relevant code | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is this commit? is it merged to main? |
||
|
||
```rust | ||
let test_size = 4; | ||
let poseidon = Poseidon2::new::<F>(test_size,None).unwrap(); | ||
let config = HashConfig::default(); | ||
let inputs = vec![F::one(); test_size]; | ||
let input_slice = HostSlice::from_slice(&inputs); | ||
//digest is a single element | ||
let out_init:F = F::zero(); | ||
let mut binding = [out_init]; | ||
let out_init_slice = HostSlice::from_mut_slice(&mut binding); | ||
|
||
poseidon.hash(input_slice, &config, out_init_slice).unwrap(); | ||
println!("computed digest: {:?} ",out_init_slice.as_slice().to_vec()[0]); | ||
``` | ||
|
||
#### Merkle Tree Builder | ||
|
||
You can use Poseidon2 in a Merkle tree builder. See the [examples/poseidon2](https://github.com/ingonyama-zk/icicle/tree/b12d83e6bcb8ee598409de78015bd118458a55d0/examples/rust/poseidon2) folder for the relevant code. | ||
|
||
```rust | ||
pub fn compute_binary_tree<F:FieldImpl>( | ||
mut test_vec: Vec<F>, | ||
leaf_size: u64, | ||
hasher: Hasher, | ||
compress: Hasher, | ||
mut tree_config: MerkleTreeConfig, | ||
) -> MerkleTree | ||
{ | ||
let tree_height: usize = test_vec.len().ilog2() as usize; | ||
//just to be safe | ||
tree_config.padding_policy = PaddingPolicy::ZeroPadding; | ||
let layer_hashes: Vec<&Hasher> = std::iter::once(&hasher) | ||
.chain(std::iter::repeat(&compress).take(tree_height)) | ||
.collect(); | ||
let vec_slice: &mut HostSlice<F> = HostSlice::from_mut_slice(&mut test_vec[..]); | ||
let merkle_tree: MerkleTree = MerkleTree::new(&layer_hashes, leaf_size, 0).unwrap(); | ||
|
||
let _ = merkle_tree | ||
.build(vec_slice,&tree_config); | ||
merkle_tree | ||
} | ||
|
||
//poseidon2 supports t=2,3,4,8,12,16,20,24. In this example we build a binary tree with Poseidon2 t=2. | ||
let poseidon_state_size = 2; | ||
let leaf_size:u64 = 4;// each leaf is a 32 bit element 32/8 = 4 bytes | ||
|
||
let mut test_vec = vec![F::from_u32(random::<u32>()); 1024* (poseidon_state_size as usize)]; | ||
println!("Generated random vector of size {:?}", 1024* (poseidon_state_size as usize)); | ||
//to use later for merkle proof | ||
let mut binding = test_vec.clone(); | ||
let test_vec_slice = HostSlice::from_mut_slice(&mut binding); | ||
//define hash and compression functions (You can use different hashes here) | ||
//note:"None" does not work with generics, use F= Fm31, Fbabybear etc | ||
let hasher :Hasher = Poseidon2::new::<F>(poseidon_state_size.try_into().unwrap(),None).unwrap(); | ||
let compress: Hasher = Poseidon2::new::<F>((hasher.output_size()*2).try_into().unwrap(),None).unwrap(); | ||
//tree config | ||
let tree_config = MerkleTreeConfig::default(); | ||
let merk_tree = compute_binary_tree(test_vec.clone(), leaf_size, hasher, compress,tree_config.clone()); | ||
println!("computed Merkle root {:?}", merk_tree.get_root::<F>().unwrap()); | ||
|
||
let random_test_index = rand::thread_rng().gen_range(0..1024*(poseidon_state_size as usize)); | ||
print!("Generating proof for element {:?} at random test index {:?} ",test_vec[random_test_index], random_test_index); | ||
let merkle_proof = merk_tree.get_proof::<F>(test_vec_slice, random_test_index.try_into().unwrap(), false, &tree_config).unwrap(); | ||
|
||
//actually should construct verifier tree :) | ||
assert!(merk_tree.verify(&merkle_proof).unwrap()); | ||
println!("\n Merkle proof verified successfully!"); | ||
``` | ||
|
||
## Using Hash API | ||
|
||
### 1. Creating a Hasher Object | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go also supports Poseidon2, although it is per curve/field, for example for bn254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done