mirror of
https://github.com/logos-storage/rust-poseidon-bn254-pure.git
synced 2026-04-18 12:03:11 +00:00
minor improvements (README, bench)
This commit is contained in:
parent
49e10423d0
commit
37d424c319
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
target/
|
||||
Cargo.lock
|
||||
tmp/
|
||||
18
README.md
18
README.md
@ -70,26 +70,30 @@ Some approximate benchmark numbers below.
|
||||
|
||||
On RV32IM (the primary target as of now), we have approximately the following cycle counts:
|
||||
|
||||
Poseidon2:
|
||||
- Poseidon: about 900k cycles for a single `t=3` permutation
|
||||
- Poseidon2: about 350k cycles for a single `t=3` permutation
|
||||
|
||||
- 350k cycles for a single `t=3` permutation
|
||||
Note: Poseidon is about 2.5x slower, simply because there are about 2.5x more
|
||||
field multiplications involved (which absolutely dominate the runtime).
|
||||
|
||||
#### Modern CPUs
|
||||
|
||||
On modern 64-bit CPU-s, the 64-bit version is preferred (TODO: implement it).
|
||||
On modern 64-bit CPU-s, the 64-bit version would be preferred (TODO: implement it).
|
||||
|
||||
32 bit version, running on an M2 macbook pro:
|
||||
32 bit version, running on an M2 macbook pro (single threaded):
|
||||
|
||||
- 155 msec for 10k `t=3` permutations
|
||||
- Poseidon: 320 msec for 10,000 `t=3` permutations
|
||||
- Poseidon2: 140 msec for 10,000 `t=3` permutations
|
||||
|
||||
### TODO
|
||||
|
||||
- [ ] clean up the code and make it more idiomatic
|
||||
- [ ] optimize squaring to use less multiplications (?)
|
||||
- [ ] benchmark RISC-V cycles
|
||||
- [x] benchmark RISC-V cycles
|
||||
- [ ] add more Poseidon2 state widths (not just `t=3`)
|
||||
- [x] implement `circomlib`-compatible Poseidon
|
||||
- [ ] add a proper test-suite; in particular, more complete testing of the field operations
|
||||
- [ ] add a 64 bit version
|
||||
- [ ] further optimizations
|
||||
- [ ] further optimizations (?)
|
||||
- [ ] implement the sponge construction
|
||||
|
||||
|
||||
@ -1,50 +1,76 @@
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use std::hint::{black_box};
|
||||
|
||||
use rust_poseidon_bn254_pure::bn254::field::*;
|
||||
use rust_poseidon_bn254_pure::poseidon2::permutation::*;
|
||||
use rust_poseidon_bn254_pure::bn254::montgomery::{Mont};
|
||||
use rust_poseidon_bn254_pure::poseidon;
|
||||
use rust_poseidon_bn254_pure::poseidon2;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
type State = (Felt,Felt,Felt);
|
||||
type Triple = (Felt,Felt,Felt);
|
||||
|
||||
fn initial_state() -> State {
|
||||
fn initial_triple() -> Triple {
|
||||
( Felt::from_u32(0)
|
||||
, Felt::from_u32(1)
|
||||
, Felt::from_u32(2)
|
||||
)
|
||||
}
|
||||
|
||||
fn iterate_perm(n: usize) -> State {
|
||||
let mut state: State = initial_state();
|
||||
fn initial_vector() -> [Felt; 3] {
|
||||
[ Felt::from_u32(0)
|
||||
, Felt::from_u32(1)
|
||||
, Felt::from_u32(2)
|
||||
]
|
||||
}
|
||||
|
||||
pub fn poseidon1_permute_felt(input: [Felt; 3]) -> [Felt; 3] {
|
||||
let mut state: [Mont; 3] =
|
||||
[ Felt::to_mont(&input[0])
|
||||
, Felt::to_mont(&input[1])
|
||||
, Felt::to_mont(&input[2])
|
||||
];
|
||||
state = poseidon::permutation::permute_mont_T3(state);
|
||||
let out: [Felt; 3] =
|
||||
[ Felt::from_mont(&state[0])
|
||||
, Felt::from_mont(&state[1])
|
||||
, Felt::from_mont(&state[2])
|
||||
];
|
||||
out
|
||||
}
|
||||
|
||||
fn iterate_poseidon1(n: usize) -> [Felt; 3] {
|
||||
let mut state: [Felt; 3] = initial_vector();
|
||||
for _i in 0..n {
|
||||
state = permute_felt(&state);
|
||||
state = poseidon1_permute_felt(state);
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
// for a Merkle tree update with depth 20, we need 20 permutation calls
|
||||
fn twenty_permutations() -> State {
|
||||
let mut state: State = initial_state();
|
||||
iterate_perm(20);
|
||||
fn iterate_poseidon2(n: usize) -> Triple {
|
||||
let mut state: Triple = initial_triple();
|
||||
for _i in 0..n {
|
||||
state = poseidon2::permutation::permute_felt(&state);
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
fn bench_iterated_perm(c: &mut Criterion , n: usize) {
|
||||
let msg = format!("Poseidon2 permutation iterated {} times", n);
|
||||
c.bench_function(&msg, |b| b.iter(|| iterate_perm(black_box(n)) ));
|
||||
fn bench_iterated_poseidon1(c: &mut Criterion , n: usize) {
|
||||
let msg = format!("Poseidon1 permutation iterated {} times", n);
|
||||
c.bench_function(&msg, |b| b.iter(|| iterate_poseidon1(black_box(n)) ));
|
||||
}
|
||||
|
||||
fn bench_twenty(c: &mut Criterion) {
|
||||
let msg = format!("Poseidon2 permutation iterated 20 times");
|
||||
c.bench_function(&msg, |b| b.iter(|| twenty_permutations() ));
|
||||
fn bench_iterated_poseidon2(c: &mut Criterion , n: usize) {
|
||||
let msg = format!("Poseidon2 permutation iterated {} times", n);
|
||||
c.bench_function(&msg, |b| b.iter(|| iterate_poseidon2(black_box(n)) ));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
fn bench_permutations(c: &mut Criterion) {
|
||||
bench_iterated_perm(c, 1000);
|
||||
bench_twenty(c);
|
||||
bench_iterated_poseidon1(c, 10000);
|
||||
bench_iterated_poseidon2(c, 10000);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
use std::time::Instant;
|
||||
|
||||
use rust_poseidon_bn254_pure::bn254::bigint::*;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user