mirror of
https://github.com/logos-storage/rust-bn254-hash.git
synced 2026-01-09 09:13:11 +00:00
85 lines
2.2 KiB
Rust
85 lines
2.2 KiB
Rust
|
|
|
||
|
|
//use ark_ff::{Field,PrimeField};
|
||
|
|
use ark_bn254::Fr as F;
|
||
|
|
|
||
|
|
use crate::constants::*;
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||
|
|
pub struct State { x: F, y: F, z: F }
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
fn sbox(x: F) -> F {
|
||
|
|
let x2: F = x * x;
|
||
|
|
let x4: F = x2*x2;
|
||
|
|
x*x4
|
||
|
|
}
|
||
|
|
|
||
|
|
fn linear_layer(u: &mut State) {
|
||
|
|
let s = u.x + u.y + u.z;
|
||
|
|
u.x += s;
|
||
|
|
u.y += s;
|
||
|
|
u.z += s;
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
fn internal_round(j: usize, u: &mut State) {
|
||
|
|
let x1 = sbox( u.x + INTERNAL_ROUND_CONST[j] );
|
||
|
|
let s = x1 + u.y + u.z;
|
||
|
|
u.x = s + x1 ;
|
||
|
|
u.y = s + u.y;
|
||
|
|
u.z = s + u.z + u.z;
|
||
|
|
}
|
||
|
|
|
||
|
|
fn external_round(j: usize, u: &mut State) {
|
||
|
|
let k = 3*j;
|
||
|
|
let x1 = sbox( u.x + EXTERNAL_ROUND_CONST[k+0] );
|
||
|
|
let y1 = sbox( u.y + EXTERNAL_ROUND_CONST[k+1] );
|
||
|
|
let z1 = sbox( u.z + EXTERNAL_ROUND_CONST[k+2] );
|
||
|
|
let s = x1 + y1 + z1;
|
||
|
|
u.x = s + x1;
|
||
|
|
u.y = s + y1;
|
||
|
|
u.z = s + z1;
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
pub fn permute_inplace(u: &mut State) {
|
||
|
|
linear_layer(u);
|
||
|
|
for j in 0..4 { external_round(j, u); }
|
||
|
|
for j in 0..56 { internal_round(j, u); }
|
||
|
|
for j in 4..8 { external_round(j, u); }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn permute(u: State) -> State {
|
||
|
|
let mut v = u;
|
||
|
|
permute_inplace(&mut v);
|
||
|
|
v
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod tests {
|
||
|
|
use super::*;
|
||
|
|
use ark_std::str::FromStr;
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn permute_kat() {
|
||
|
|
let input = State { x: F::from(0u64), y: F::from(1u64), z: F::from(2u64) };
|
||
|
|
let output = permute(input);
|
||
|
|
println!("x = {}",output.x);
|
||
|
|
println!("y = {}",output.y);
|
||
|
|
println!("z = {}",output.z);
|
||
|
|
let expected = State
|
||
|
|
{ x: F::from_str("21882471761025344482456282050943515707267606647948403374880378562101343146243").unwrap()
|
||
|
|
, y: F::from_str("9030699330013392132529464674294378792132780497765201297316864012141442630280" ).unwrap()
|
||
|
|
, z: F::from_str("9137931384593657624554037900714196568304064431583163402259937475584578975855" ).unwrap()
|
||
|
|
};
|
||
|
|
assert_eq!(output,expected);
|
||
|
|
}
|
||
|
|
}
|