mirror of
https://github.com/logos-storage/rust-poseidon-bn254-pure.git
synced 2026-08-10 03:43:13 +00:00
started adding some tests
This commit is contained in:
parent
b46a6dde66
commit
f6c30ed6e0
@ -87,13 +87,13 @@ On modern 64-bit CPU-s, the 64-bit version would be preferred (TODO: implement i
|
||||
|
||||
### TODO
|
||||
|
||||
- [ ] clean up the code and make it more idiomatic
|
||||
- [ ] optimize squaring to use less multiplications (?)
|
||||
- [x] clean up the code and make it more idiomatic
|
||||
- [x] implement `circomlib`-compatible Poseidon
|
||||
- [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 (?)
|
||||
- [ ] implement the sponge construction
|
||||
- [ ] optimize squaring to use less multiplications (?)
|
||||
- [ ] investigate further optimization possibilities (?)
|
||||
|
||||
|
||||
@ -6,3 +6,5 @@ pub mod constant;
|
||||
pub mod montgomery;
|
||||
pub mod field;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
@ -1,25 +1,16 @@
|
||||
|
||||
// "unstable" version
|
||||
// "unstable" (in rust parlance) version
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const U32_MASK: u64 = 0x_FFFF_FFFF;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn boolToU32(c: bool) -> u32 {
|
||||
if c { 1 } else { 0 }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn takeApart64(x: u64) -> (u32,u32) {
|
||||
let lo: u32 = (x & U32_MASK) as u32;
|
||||
let hi: u32 = (x >> 32 ) as u32;
|
||||
(lo,hi)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#[inline(always)]
|
||||
@ -79,60 +70,3 @@ pub fn u64AddAdd32(xy: (u32,u32), a: u32, b: u32) -> (u32,u32) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// "portable" version
|
||||
|
||||
/*
|
||||
|
||||
pub fn addCarry32_(x: u32, y: u32) -> (u32,bool) {
|
||||
let z: u32 = u32::wrapping_add(x, y);
|
||||
let c: bool = z < x;
|
||||
(z, c)
|
||||
}
|
||||
|
||||
pub fn subBorrow32_(x: u32, y: u32) -> (u32,bool) {
|
||||
let z: u32 = u32::wrapping_sub(x, y);
|
||||
let c: bool = z > x;
|
||||
(z, c)
|
||||
}
|
||||
|
||||
pub fn addCarry32(x :u32, y: u32, cin: bool) -> (u32,bool) {
|
||||
let z: u32 = u32::wrapping_add(u32::wrapping_add(x, y), boolToU32(cin));
|
||||
let c: bool = if cin { z <= x } else { z < x };
|
||||
(z, c)
|
||||
}
|
||||
|
||||
pub fn subBorrow32(x: u32, y: u32, cin: bool) -> (u32,bool) {
|
||||
let z: u32 = u32::wrapping_sub(u32::wrapping_sub(x, y), boolToU32(cin));
|
||||
let c: bool = if cin { z >= x } else { z > x };
|
||||
(z, c)
|
||||
}
|
||||
|
||||
pub fn mulTrunc32(x: u32, y: u32) -> u32 {
|
||||
u32::wrapping_mul(x,y)
|
||||
}
|
||||
|
||||
pub fn mulExt32(x: u32, y: u32) -> (u32,u32) {
|
||||
let z: u64 = (x as u64) * (y as u64);
|
||||
let hi = (z >> 32) as u32;
|
||||
let lo = (z & U32_MASK) as u32;
|
||||
(lo, hi)
|
||||
}
|
||||
|
||||
pub fn mulAdd32(x: u32, y: u32, a: u32) -> (u32,u32) {
|
||||
let z: u64 = (x as u64) * (y as u64) + (a as u64);
|
||||
let hi = (z >> 32) as u32;
|
||||
let lo = (z & U32_MASK) as u32;
|
||||
(lo, hi)
|
||||
}
|
||||
|
||||
pub fn mulAddAdd32(x: u32, y: u32, a: u32, b: u32) -> (u32,u32) {
|
||||
let z: u64 = (x as u64) * (y as u64) + (a as u64) + (b as u64);
|
||||
let hi = (z >> 32) as u32;
|
||||
let lo = (z & U32_MASK) as u32;
|
||||
(lo, hi)
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
52
src/bn254/test/bigint.rs
Normal file
52
src/bn254/test/bigint.rs
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
// tests for bigints
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::bn254::bigint::*;
|
||||
use crate::bn254::test::properties::*;
|
||||
|
||||
type Big = BigInt<8>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn zero_is_zero() {
|
||||
assert!( Big::is_zero( Big::zero() ) )
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_to_decimal() {
|
||||
let x: Big = Big::make( [ 0xff74e7f5 , 0x86ab86c2 , 0x7829f01b , 0x6dff3d9f , 0x7c6194d1 , 0x58fce839 , 0x1c3fc759 , 0x0ee7c7b9 ] );
|
||||
assert_eq!( Big::to_decimal_string(x) , "6741899990217662167434591118162422674873486558668509109681649862022285027317" )
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_to_hex() {
|
||||
let x: Big = Big::make( [ 0x5d8aa877 , 0x40b543d5 , 0x115812cd , 0x0563e2bd , 0x26c9552a , 0x1890edd6 , 0x803b772b , 0x1a12005c ] );
|
||||
assert_eq!( Big::to_hex_string(x) , "0x1a12005c803b772b1890edd626c9552a0563e2bd115812cd40b543d55d8aa877" )
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
fn prop_from_to_bytes_le<const N: usize>(x: BigInt<N>) -> bool where [(); 4*N]: {
|
||||
let bs: [u8; 4*N] = BigInt::to_le_bytes(x);
|
||||
BigInt::<N>::from_le_bytes(bs) == x
|
||||
}
|
||||
|
||||
fn prop_to_from_bytes_le<const N: usize>(bs: [u8; 4*N]) -> bool {
|
||||
let y: BigInt<N> = BigInt::from_le_bytes(bs);
|
||||
BigInt::<N>::to_le_bytes(y) == bs
|
||||
}
|
||||
|
||||
fn prop_from_to_bytes_be<const N: usize>(x: BigInt<N>) -> bool where [(); 4*N]: {
|
||||
let bs: [u8; 4*N] = BigInt::to_be_bytes(x);
|
||||
BigInt::<N>::from_be_bytes(bs) == x
|
||||
}
|
||||
|
||||
fn prop_to_from_bytes_be<const N: usize>(bs: [u8; 4*N]) -> bool {
|
||||
let y: BigInt<N> = BigInt::from_be_bytes(bs);
|
||||
BigInt::<N>::to_be_bytes(y) == bs
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
6
src/bn254/test/mod.rs
Normal file
6
src/bn254/test/mod.rs
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
pub mod properties;
|
||||
|
||||
pub mod bigint;
|
||||
// pub mod field;
|
||||
// pub mod mont;
|
||||
113
src/bn254/test/properties.rs
Normal file
113
src/bn254/test/properties.rs
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
// field properties
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::cmp::{Eq};
|
||||
use std::ops::{Neg,Add,Sub,Mul,Div};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
pub trait Group = Copy + Clone + Default + From<u32> + Eq + Neg<Output=Self> + Add<Output=Self> + Sub<Output=Self>;
|
||||
pub trait Ring = Group + Mul<Output=Self>;
|
||||
pub trait Field = Ring + Div<Output=Self>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
fn zero<A: Group>() -> A {
|
||||
A::default()
|
||||
}
|
||||
|
||||
fn small<A: Group>(x: u32) -> A {
|
||||
A::from(x)
|
||||
}
|
||||
|
||||
// wtf rust?
|
||||
fn xneg<A: Neg<Output=A>>(x: A ) -> A {
|
||||
-x
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
pub fn prop_left_additive_unit<A: Group>(x: A) -> bool {
|
||||
zero::<A>() + x == x
|
||||
}
|
||||
|
||||
pub fn prop_right_additive_unit<A: Group>(x: A) -> bool {
|
||||
x + zero::<A>() == x
|
||||
}
|
||||
|
||||
pub fn prop_sub_zero<A: Group>(x: A) -> bool {
|
||||
x - zero::<A>() == x
|
||||
}
|
||||
|
||||
pub fn prop_zero_subo<A: Group>(x: A) -> bool {
|
||||
zero::<A>() - x == xneg(x)
|
||||
}
|
||||
|
||||
pub fn prop_add_commutative<A: Group>(x: A, y: A) -> bool {
|
||||
x + y == y + x
|
||||
}
|
||||
|
||||
pub fn prop_sub_anticommutative<A: Group>(x: A, y: A) -> bool {
|
||||
x - y == xneg( y - x )
|
||||
}
|
||||
|
||||
pub fn prop_neg_involutive<A: Group>(x: A) -> bool {
|
||||
xneg( xneg(x) ) == x
|
||||
}
|
||||
|
||||
pub fn prop_add_sub<A: Group>(x: A, y: A) -> bool {
|
||||
(x + y) - y == x
|
||||
}
|
||||
|
||||
pub fn prop_sub_add<A: Group>(x: A, y: A) -> bool {
|
||||
(x - y) + y == x
|
||||
}
|
||||
|
||||
pub fn prop_sub_neg_add<A: Group>(x: A, y: A) -> bool {
|
||||
x - xneg(y) == x + y
|
||||
}
|
||||
|
||||
pub fn prop_sub_add_neg<A: Group>(x: A, y: A) -> bool {
|
||||
x - y == x + xneg(y)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
pub fn prop_twice<A: Ring>(x: A) -> bool {
|
||||
x + x == x * small::<A>(2)
|
||||
}
|
||||
|
||||
pub fn prop_thrice<A: Ring>(x: A) -> bool {
|
||||
x + x + x == x * small::<A>(3)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
pub fn prop_left_multiplicative_unit<A: Ring>(x: A) -> bool {
|
||||
small::<A>(1) * x == x
|
||||
}
|
||||
|
||||
pub fn prop_right_multiplicative_unit<A: Ring>(x: A) -> bool {
|
||||
x * small::<A>(1) == x
|
||||
}
|
||||
|
||||
pub fn prop_mul_commutative<A: Ring>(x: A, y: A) -> bool {
|
||||
x * y == y * x
|
||||
}
|
||||
|
||||
pub fn prop_mul_neg<A: Ring>(x: A, y: A) -> bool {
|
||||
xneg(x * y) == xneg(x) * y
|
||||
}
|
||||
|
||||
pub fn prop_distributive_add<A: Ring>(x: A, y: A, z: A) -> bool {
|
||||
(x + y) * z == x * z + y * z
|
||||
}
|
||||
|
||||
pub fn prop_distributive_sub<A: Ring>(x: A, y: A, z: A) -> bool {
|
||||
(x - y) * z == x * z - y * z
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -167,4 +167,47 @@ pub fn hash4(a: Felt, b: Felt, c: Felt, d: Felt) -> Felt {
|
||||
compress::<4>([ a, b, c, d ])
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// *** TESTS
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::bn254::field::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hash1_kat() {
|
||||
assert_eq!(
|
||||
Felt::to_decimal_string( hash1( 1u32.into() ) ),
|
||||
"18586133768512220936620570745912940619677854269274689475585506675881198879027"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash2_kat() {
|
||||
assert_eq!(
|
||||
Felt::to_decimal_string( hash2( 1u32.into(), 2u32.into() ) ),
|
||||
"7853200120776062878684798364095072458815029376092732009249414926327459813530"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash3_kat() {
|
||||
assert_eq!(
|
||||
Felt::to_decimal_string( hash3( 1u32.into(), 2u32.into(), 3u32.into() ) ),
|
||||
"6542985608222806190361240322586112750744169038454362455181422643027100751666"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash4_kat() {
|
||||
assert_eq!(
|
||||
Felt::to_decimal_string( hash4( 1u32.into(), 2u32.into(), 3u32.into(), 4u32.into() ) ),
|
||||
"18821383157269793795438455681495246036402687001665670618754263018637548127333"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -83,4 +83,27 @@ pub fn permute_iterated(input: [Felt; 3], count: usize) -> [Felt; 3] {
|
||||
out
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// *** TESTS
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::bn254::field::{Felt};
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn permute3_kat() {
|
||||
let out: [Felt; 3] = permute( [ 0u32.into() , 1u32.into() , 2u32.into() ] );
|
||||
println!(" 0 -> {}" , out[0] );
|
||||
println!(" 1 -> {}" , out[1] );
|
||||
println!(" 2 -> {}" , out[2] );
|
||||
assert_eq!( Felt::to_hex_string( out[0] ) , "0x30610a447b7dec194697fb50786aa7421494bd64c221ba4d3b1af25fb07bd103" );
|
||||
assert_eq!( Felt::to_hex_string( out[1] ) , "0x13f731d6ffbad391be22d2ac364151849e19fa38eced4e761bcd21dbdc600288" );
|
||||
assert_eq!( Felt::to_hex_string( out[2] ) , "0x1433e2c8f68382c447c5c14b8b3df7cbfd9273dd655fe52f1357c27150da786f" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user