mirror of
https://github.com/arnaucube/poseidon-ark.git
synced 2026-01-09 23:41:29 +01:00
Update methods to more efficient usage of ff
On a Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz, with 16GB of RAM: - Old (using num-bigint): hash time: [5.9258 ms 5.9407 ms 5.9587 ms] - New (using ff): hash time: [120.12 us 121.08 us 122.30 us] On a Intel(R) Core(TM) i7-8705G CPU @ 3.10GHz, with 32 GB of RAM: - Old (using num-bigint): hash time: [4.1192 ms 4.1318 ms 4.1461 ms] - In the previous commit (using ff): hash time: [91.394 us 91.430 us 91.476 us] - In this commit (using ff): hash time: [85.517 us 85.545 us 85.574 us]
This commit is contained in:
@@ -8,7 +8,3 @@ Compatible with the Poseidon Go implementation done in https://github.com/iden3/
|
||||
## Warning
|
||||
Do not use in production
|
||||
|
||||
## Benchmarks
|
||||
```
|
||||
hash time: [120.12 us 121.08 us 122.30 us]
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
extern crate rand;
|
||||
#[macro_use]
|
||||
|
||||
44
src/lib.rs
44
src/lib.rs
@@ -164,32 +164,26 @@ impl Poseidon {
|
||||
constants: load_constants(),
|
||||
}
|
||||
}
|
||||
pub fn ark(&self, state: &Vec<Fr>, c: &Fr) -> Vec<Fr> {
|
||||
let mut new_state: Vec<Fr> = state.clone();
|
||||
pub fn ark(&self, state: &mut Vec<Fr>, c: &Fr) {
|
||||
for i in 0..state.len() {
|
||||
new_state[i] = state[i];
|
||||
new_state[i].add_assign(c);
|
||||
state[i].add_assign(c);
|
||||
}
|
||||
|
||||
new_state
|
||||
}
|
||||
|
||||
pub fn sbox(&self, state: &Vec<Fr>, i: usize) -> Vec<Fr> {
|
||||
let mut new_state: Vec<Fr> = state.clone();
|
||||
pub fn sbox(&self, state: &mut Vec<Fr>, i: usize) {
|
||||
if i < NROUNDSF / 2 || i >= NROUNDSF / 2 + NROUNDSP {
|
||||
for j in 0..T {
|
||||
new_state[j] = state[j];
|
||||
new_state[j].square();
|
||||
new_state[j].square();
|
||||
new_state[j].mul_assign(&state[j]);
|
||||
let aux = state[j];
|
||||
state[j].square();
|
||||
state[j].square();
|
||||
state[j].mul_assign(&aux);
|
||||
}
|
||||
} else {
|
||||
new_state[0] = state[0];
|
||||
new_state[0].square();
|
||||
new_state[0].square();
|
||||
new_state[0].mul_assign(&state[0]);
|
||||
let aux = state[0];
|
||||
state[0].square();
|
||||
state[0].square();
|
||||
state[0].mul_assign(&aux);
|
||||
}
|
||||
new_state
|
||||
}
|
||||
|
||||
pub fn mix(&self, state: &Vec<Fr>, m: &Vec<Vec<Fr>>) -> Vec<Fr> {
|
||||
@@ -216,8 +210,8 @@ impl Poseidon {
|
||||
}
|
||||
|
||||
for i in 0..(NROUNDSF + NROUNDSP) {
|
||||
state = self.ark(&state, &self.constants.c[i]);
|
||||
state = self.sbox(&state, i);
|
||||
self.ark(&mut state, &self.constants.c[i]);
|
||||
self.sbox(&mut state, i);
|
||||
state = self.mix(&state, &self.constants.m);
|
||||
}
|
||||
|
||||
@@ -236,13 +230,21 @@ mod tests {
|
||||
"0000000000000000000000000000000000000000000000000000000000000002",
|
||||
to_hex(&a)
|
||||
);
|
||||
println!("`2` into hex = {}", to_hex(&a));
|
||||
|
||||
let b: Fr = Fr::from_str(
|
||||
"21888242871839275222246405745257275088548364400416034343698204186575808495619",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
"0000000000000000000000000000000000000000000000000000000000000002",
|
||||
to_hex(&b)
|
||||
);
|
||||
assert_eq!(&a, &b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_load_constants() {
|
||||
let constants = load_constants();
|
||||
println!("{:?}", constants.c[0].to_string());
|
||||
assert_eq!(
|
||||
constants.c[0].to_string(),
|
||||
"Fr(0x1fd4a35e68f0946f8f5dfd2ac9d7882ce2466ec1c9766f69b5a14c3f84a17be2)"
|
||||
|
||||
Reference in New Issue
Block a user