@ -1,3 +1,13 @@
// WARNING still updating the code, it works, but is still in process the refactor.
extern crate rand ;
#[ macro_use ]
extern crate ff ;
use ff ::* ;
use poseidon_rs ::Poseidon ;
pub type Fr = poseidon_rs ::Fr ; // alias
#[ macro_use ]
#[ macro_use ]
extern crate arrayref ;
extern crate arrayref ;
extern crate generic_array ;
extern crate generic_array ;
@ -5,112 +15,180 @@ extern crate mimc_rs;
extern crate num ;
extern crate num ;
extern crate num_bigint ;
extern crate num_bigint ;
extern crate num_traits ;
extern crate num_traits ;
extern crate rand ;
extern crate rand6 ;
use rand6 ::Rng ;
use blake2 ::{ Blake2b , Digest } ;
use blake2 ::{ Blake2b , Digest } ;
use mimc_rs ::Mimc7 ;
use mimc_rs ::Mimc7 ;
use poseidon_rs ::Poseidon ;
use std ::cmp ::min ;
use std ::cmp ::min ;
use num_bigint ::{ BigInt , RandBigInt , Sign , ToBigInt } ;
use num_bigint ::{ BigInt , RandBigInt , RandomBits , Sign , ToBigInt } ;
use num_traits ::{ One , Zero } ;
use num_traits ::{ One , Zero } ;
use generic_array ::GenericArray ;
use generic_array ::GenericArray ;
mod utils ;
pub mod utils ;
#[ macro_use ]
#[ macro_use ]
extern crate lazy_static ;
extern crate lazy_static ;
lazy_static ! {
lazy_static ! {
static ref D : BigInt = BigInt ::parse_bytes ( b" 168696 " , 10 ) . unwrap ( ) ;
static ref A : BigInt = BigInt ::parse_bytes ( b" 168700 " , 10 ) . unwrap ( ) ;
static ref Q : BigInt = BigInt ::parse_bytes (
b" 21888242871839275222246405745257275088548364400416034343698204186575808495617 " ,
10 ,
static ref D : Fr = Fr ::from_str ( "168696" ) . unwrap ( ) ;
static ref D_big : BigInt = BigInt ::parse_bytes ( b" 168696 " , 10 ) . unwrap ( ) ;
static ref A : Fr = Fr ::from_str ( "168700" ) . unwrap ( ) ;
static ref A_big : BigInt = BigInt ::parse_bytes ( b" 168700 " , 10 ) . unwrap ( ) ;
pub static ref Q : BigInt = BigInt ::parse_bytes (
b" 21888242871839275222246405745257275088548364400416034343698204186575808495617 " , 10
)
)
. unwrap ( ) ;
. unwrap ( ) ;
// pub static ref Q: Fr = Fr::from_str(
// "21888242871839275222246405745257275088548364400416034343698204186575808495617"
// )
// .unwrap();
static ref B8 : Point = Point {
static ref B8 : Point = Point {
x : BigInt ::parse_bytes (
b" 5299619240641551281634865583518297030282874472190772894086521144482721001553 " ,
10 ,
x : Fr ::from_str (
"5299619240641551281634865583518297030282874472190772894086521144482721001553" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 16950150798460657717958625567821834550301663161624707787222815936182638968203 " ,
10 ,
y : Fr ::from_str (
"16950150798460657717958625567821834550301663161624707787222815936182638968203" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
// z: Fr::one(),
} ;
} ;
static ref ORDER : BigInt = BigInt ::parse_bytes (
b" 21888242871839275222246405745257275088614511777268538073601725287587578984328 " ,
10 ,
static ref ORDER : Fr = Fr ::from_str (
"21888242871839275222246405745257275088614511777268538073601725287587578984328" ,
)
)
. unwrap ( ) ;
. unwrap ( ) ;
// SUBORDER = ORDER >> 3
// static ref SUBORDER: Fr = Fr::from_str(
// "i2736030358979909402780800718157159386076813972158567259200215660948447373041",
// )
// .unwrap();
static ref SUBORDER : BigInt = & BigInt ::parse_bytes (
static ref SUBORDER : BigInt = & BigInt ::parse_bytes (
b" 21888242871839275222246405745257275088614511777268538073601725287587578984328 " ,
10 ,
)
. unwrap ( )
> > 3 ;
b" 21888242871839275222246405745257275088614511777268538073601725287587578984328 " ,
10 ,
)
. unwrap ( )
> > 3 ;
}
#[ derive(Clone, Debug) ]
pub struct PointProjective {
pub x : Fr ,
pub y : Fr ,
pub z : Fr ,
}
impl PointProjective {
pub fn affine ( & self ) -> Point {
if self . z . is_zero ( ) {
return Point {
x : Fr ::zero ( ) ,
y : Fr ::zero ( ) ,
} ;
}
let mut zinv = self . z . inverse ( ) . unwrap ( ) ;
let mut x = self . x ;
x . mul_assign ( & zinv ) ;
let mut y = self . y ;
y . mul_assign ( & zinv ) ;
Point {
x : x . clone ( ) ,
y : y . clone ( ) ,
}
}
pub fn add ( & self , q : & PointProjective ) -> Result < PointProjective , String > {
// add-2008-bbjlp https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp
let mut a = self . z ;
a . mul_assign ( & q . z ) ;
let mut b = a ;
b . square ( ) ;
let mut c = self . x ;
c . mul_assign ( & q . x ) ;
let mut d = self . y ;
d . mul_assign ( & q . y ) ;
let mut e = D . clone ( ) ;
e . mul_assign ( & c ) ;
e . mul_assign ( & d ) ;
let mut f = b ;
f . sub_assign ( & e ) ;
let mut g = b ;
g . add_assign ( & e ) ;
let mut x1y1 = self . x ;
x1y1 . add_assign ( & self . y ) ;
let mut x2y2 = q . x ;
x2y2 . add_assign ( & q . y ) ;
let mut aux = x1y1 ;
aux . mul_assign ( & x2y2 ) ;
aux . sub_assign ( & c ) ;
aux . sub_assign ( & d ) ;
let mut x3 = a ;
x3 . mul_assign ( & f ) ;
x3 . mul_assign ( & aux ) ;
let mut ac = A . clone ( ) ;
ac . mul_assign ( & c ) ;
let mut dac = d ;
dac . sub_assign ( & ac ) ;
let mut y3 = a ;
y3 . mul_assign ( & g ) ;
y3 . mul_assign ( & dac ) ;
let mut z3 = f ;
z3 . mul_assign ( & g ) ;
Ok ( PointProjective {
x : x3 . clone ( ) ,
y : y3 . clone ( ) ,
z : z3 . clone ( ) ,
} )
}
}
}
#[ derive(Clone, Debug) ]
#[ derive(Clone, Debug) ]
pub struct Point {
pub struct Point {
pub x : BigInt ,
pub y : BigInt ,
pub x : Fr ,
pub y : Fr ,
}
}
impl Point {
impl Point {
pub fn add ( & self , q : & Point ) -> Result < Point , String > {
// x = (x1*y2+y1*x2)/(c*(1+d*x1*x2*y1*y2))
// y = (y1*y2-x1*x2)/(c*(1-d*x1*x2*y1*y2))
// x = (x1 * y2 + y1 * x2) / (1 + d * x1 * y1 * y2)
let one : BigInt = One ::one ( ) ;
let x_num : BigInt = & self . x * & q . y + & self . y * & q . x ;
let x_den : BigInt = & one + & D . clone ( ) * & self . x * & q . x * & self . y * & q . y ;
let x_den_inv = utils ::modinv ( & x_den , & Q ) ? ;
let x : BigInt = utils ::modulus ( & ( & x_num * & x_den_inv ) , & Q ) ;
// y = (y1 * y2 - a * x1 * x2) / (1 - d * x1 * x2 * y1 * y2)
let y_num = & self . y * & q . y - & A . clone ( ) * & self . x * & q . x ;
let y_den = utils ::modulus ( & ( & one - & D . clone ( ) * & self . x * & q . x * & self . y * & q . y ) , & Q ) ;
let y_den_inv = utils ::modinv ( & y_den , & Q ) ? ;
let y : BigInt = utils ::modulus ( & ( & y_num * & y_den_inv ) , & Q ) ;
Ok ( Point { x : x , y : y } )
pub fn projective ( & self ) -> PointProjective {
PointProjective {
x : self . x . clone ( ) ,
y : self . y . clone ( ) ,
z : Fr ::one ( ) ,
}
}
}
pub fn mul_scalar ( & self , n : & BigInt ) -> Result < Point , String > {
pub fn mul_scalar ( & self , n : & BigInt ) -> Result < Point , String > {
let mut r : Point = Point {
x : Zero ::zero ( ) ,
y : One ::one ( ) ,
let mut r : PointProjective = PointProjective {
x : Fr ::zero ( ) ,
y : Fr ::one ( ) ,
z : Fr ::one ( ) ,
} ;
} ;
let mut rem : BigInt = n . clone ( ) ;
let mut exp : Point = self . clone ( ) ;
let zero : BigInt = Zero ::zero ( ) ;
let one : BigInt = One ::one ( ) ;
while rem ! = zero {
let is_odd = & rem & & one = = one ;
if is_odd = = true {
let mut exp : PointProjective = self . projective ( ) ;
let ( _ , b ) = n . to_bytes_le ( ) ;
for i in 0 . . n . bits ( ) {
if test_bit ( & b , i ) {
r = r . add ( & exp ) ? ;
r = r . add ( & exp ) ? ;
}
}
exp = exp . add ( & exp ) ? ;
exp = exp . add ( & exp ) ? ;
rem = rem > > 1 ;
}
}
r . x = utils ::modulus ( & r . x , & Q ) ;
r . y = utils ::modulus ( & r . y , & Q ) ;
Ok ( r )
Ok ( r . affine ( ) )
}
}
pub fn compress ( & self ) -> [ u8 ; 32 ] {
pub fn compress ( & self ) -> [ u8 ; 32 ] {
let p = & self ;
let mut r : [ u8 ; 32 ] = [ 0 ; 32 ] ;
let mut r : [ u8 ; 32 ] = [ 0 ; 32 ] ;
let ( _ , y_bytes ) = self . y . to_bytes_le ( ) ;
let x_big = BigInt ::parse_bytes ( to_hex ( & p . x ) . as_bytes ( ) , 16 ) . unwrap ( ) ;
let y_big = BigInt ::parse_bytes ( to_hex ( & p . y ) . as_bytes ( ) , 16 ) . unwrap ( ) ;
let ( _ , y_bytes ) = y_big . to_bytes_le ( ) ;
let len = min ( y_bytes . len ( ) , r . len ( ) ) ;
let len = min ( y_bytes . len ( ) , r . len ( ) ) ;
r [ . . len ] . copy_from_slice ( & y_bytes [ . . len ] ) ;
r [ . . len ] . copy_from_slice ( & y_bytes [ . . len ] ) ;
if & self . x > & ( & Q . clone ( ) > > 1 ) {
if & x_big > & ( & Q . clone ( ) > > 1 ) {
r [ 31 ] = r [ 31 ] | 0x80 ;
r [ 31 ] = r [ 31 ] | 0x80 ;
}
}
r
r
@ -124,6 +202,10 @@ impl Point {
}
}
}
}
pub fn test_bit ( b : & Vec < u8 > , i : usize ) -> bool {
return b [ i / 8 ] & ( 1 < < ( i % 8 ) ) ! = 0 ;
}
pub fn decompress_point ( bb : [ u8 ; 32 ] ) -> Result < Point , String > {
pub fn decompress_point ( bb : [ u8 ; 32 ] ) -> Result < Point , String > {
// https://tools.ietf.org/html/rfc8032#section-5.2.3
// https://tools.ietf.org/html/rfc8032#section-5.2.3
let mut sign : bool = false ;
let mut sign : bool = false ;
@ -141,7 +223,7 @@ pub fn decompress_point(bb: [u8; 32]) -> Result {
// x^2 = (1 - y^2) / (a - d * y^2) (mod p)
// x^2 = (1 - y^2) / (a - d * y^2) (mod p)
let den = utils ::modinv (
let den = utils ::modinv (
& utils ::modulus (
& utils ::modulus (
& ( & A . clone ( ) - utils ::modulus ( & ( & D . clone ( ) * ( & y * & y ) ) , & Q ) ) ,
& ( & A_big . clone ( ) - utils ::modulus ( & ( & D_big . clone ( ) * ( & y * & y ) ) , & Q ) ) ,
& Q ,
& Q ,
) ,
) ,
& Q ,
& Q ,
@ -153,9 +235,12 @@ pub fn decompress_point(bb: [u8; 32]) -> Result {
x = x * - 1. to_bigint ( ) . unwrap ( ) ;
x = x * - 1. to_bigint ( ) . unwrap ( ) ;
}
}
x = utils ::modulus ( & x , & Q ) ;
x = utils ::modulus ( & x , & Q ) ;
Ok ( Point { x : x , y : y } )
let x_fr : Fr = Fr ::from_str ( & x . to_string ( ) ) . unwrap ( ) ;
let y_fr : Fr = Fr ::from_str ( & y . to_string ( ) ) . unwrap ( ) ;
Ok ( Point { x : x_fr , y : y_fr } )
}
}
#[ derive(Debug, Clone) ]
pub struct Signature {
pub struct Signature {
r_b8 : Point ,
r_b8 : Point ,
s : BigInt ,
s : BigInt ,
@ -200,56 +285,33 @@ impl PrivateKey {
Ok ( pk . clone ( ) )
Ok ( pk . clone ( ) )
}
}
pub fn sign_mimc ( & self , msg : BigInt ) -> Result < Signature , String > {
pub fn sign ( & self , msg : BigInt ) -> Result < Signature , String > {
if msg > Q . clone ( ) {
return Err ( "msg outside the Finite Field" . to_string ( ) ) ;
}
// https://tools.ietf.org/html/rfc8032#section-5.1.6
// https://tools.ietf.org/html/rfc8032#section-5.1.6
let mut hasher = Blake2b ::new ( ) ;
let mut hasher = Blake2b ::new ( ) ;
let ( _ , sk_bytes ) = self . key . to_bytes_be ( ) ;
let ( _ , sk_bytes ) = self . key . to_bytes_be ( ) ;
hasher . input ( sk_bytes ) ;
hasher . input ( sk_bytes ) ;
let mut h = hasher . result ( ) ; // h: hash(sk)
let mut h = hasher . result ( ) ; // h: hash(sk)
// s: h[32:64]
// s: h[32:64]
let s = GenericArray ::< u8 , generic_array ::typenum ::U32 > ::from_mut_slice ( & mut h [ 32 . . 64 ] ) ;
let ( _ , msg_bytes ) = msg . to_bytes_be ( ) ;
let ( _ , msg_bytes ) = msg . to_bytes_be ( ) ;
let r_bytes = utils ::concatenate_arrays ( s , & msg_bytes ) ;
let mut r = BigInt ::from_bytes_be ( Sign ::Plus , & r_bytes [ . . ] ) ;
r = utils ::modulus ( & r , & SUBORDER ) ;
let r8 : Point = B8 . mul_scalar ( & r ) ? ;
let a = & self . public ( ) ? ;
let hm_input = vec ! [ r8 . x . clone ( ) , r8 . y . clone ( ) , a . x . clone ( ) , a . y . clone ( ) , msg ] ;
let mimc7 = Mimc7 ::new ( ) ;
let hm = mimc7 . hash ( hm_input ) ? ;
let msgFr : Fr = Fr ::from_str ( & msg . to_string ( ) ) . unwrap ( ) ;
let mut s = & self . key < < 3 ;
s = hm * s ;
s = r + s ;
s = s % & SUBORDER . clone ( ) ;
Ok ( Signature {
r_b8 : r8 . clone ( ) ,
s : s ,
} )
}
pub fn sign_poseidon ( & self , msg : BigInt ) -> Result < Signature , String > {
// https://tools.ietf.org/html/rfc8032#section-5.1.6
let mut hasher = Blake2b ::new ( ) ;
let ( _ , sk_bytes ) = self . key . to_bytes_be ( ) ;
hasher . input ( sk_bytes ) ;
let mut h = hasher . result ( ) ; // h: hash(sk)
// s: h[32:64]
let s = GenericArray ::< u8 , generic_array ::typenum ::U32 > ::from_mut_slice ( & mut h [ 32 . . 64 ] ) ;
let s = GenericArray ::< u8 , generic_array ::typenum ::U32 > ::from_mut_slice ( & mut h [ 32 . . 64 ] ) ;
let ( _ , msg_bytes ) = msg . to_bytes_be ( ) ;
let r_bytes = utils ::concatenate_arrays ( s , & msg_bytes ) ;
let r_bytes = utils ::concatenate_arrays ( s , & msg_bytes ) ;
let mut r = BigInt ::from_bytes_be ( Sign ::Plus , & r_bytes [ . . ] ) ;
let mut r = BigInt ::from_bytes_be ( Sign ::Plus , & r_bytes [ . . ] ) ;
r = utils ::modulus ( & r , & SUBORDER ) ;
r = utils ::modulus ( & r , & SUBORDER ) ;
let r8 : Point = B8 . mul_scalar ( & r ) ? ;
let r8 : Point = B8 . mul_scalar ( & r ) ? ;
let a = & self . public ( ) ? ;
let a = & self . public ( ) ? ;
let hm_input = vec ! [ r8 . x . clone ( ) , r8 . y . clone ( ) , a . x . clone ( ) , a . y . clone ( ) , msg ] ;
let hm_input = vec ! [ r8 . x . clone ( ) , r8 . y . clone ( ) , a . x . clone ( ) , a . y . clone ( ) , msgFr ] ;
let poseidon = Poseidon ::new ( ) ;
let poseidon = Poseidon ::new ( ) ;
let hm = poseidon . hash ( hm_input ) ? ;
let hm = poseidon . hash ( hm_input ) ? ;
let mut s = & self . key < < 3 ;
let mut s = & self . key < < 3 ;
s = hm * s ;
let hmB = BigInt ::parse_bytes ( to_hex ( & hm ) . as_bytes ( ) , 16 ) . unwrap ( ) ;
s = hmB * s ;
s = r + s ;
s = r + s ;
s = s % & SUBORDER . clone ( ) ;
s = s % & SUBORDER . clone ( ) ;
@ -259,9 +321,9 @@ impl PrivateKey {
} )
} )
}
}
pub fn sign_schnorr ( & self , m : Vec < u8 > ) -> Result < ( Point , BigInt ) , String > {
pub fn sign_schnorr ( & self , m : BigInt ) -> Result < ( Point , BigInt ) , String > {
// random r
// random r
let mut rng = rand ::thread_rng ( ) ;
let mut rng = rand6 ::thread_rng ( ) ;
let k = rng . gen_biguint ( 1024 ) . to_bigint ( ) . unwrap ( ) ;
let k = rng . gen_biguint ( 1024 ) . to_bigint ( ) . unwrap ( ) ;
// r = k·G
// r = k·G
@ -277,35 +339,34 @@ impl PrivateKey {
}
}
}
}
pub fn schnorr_hash ( pk : & Point , m : Vec < u8 > , c : & Point ) -> Result < BigInt , String > {
let b : & mut Vec < u8 > = & mut Vec ::new ( ) ;
// other option could be to do it without compressing the points, and concatenating x|y
b . append ( & mut pk . compress ( ) . to_vec ( ) ) ;
b . append ( & mut c . compress ( ) . to_vec ( ) ) ;
b . append ( & mut m . clone ( ) ) ;
pub fn schnorr_hash ( pk : & Point , msg : BigInt , c : & Point ) -> Result < BigInt , String > {
if msg > Q . clone ( ) {
return Err ( "msg outside the Finite Field" . to_string ( ) ) ;
}
let msgFr : Fr = Fr ::from_str ( & msg . to_string ( ) ) . unwrap ( ) ;
let hm_input = vec ! [ pk . x . clone ( ) , pk . y . clone ( ) , c . x . clone ( ) , c . y . clone ( ) , msgFr ] ;
let poseidon = Poseidon ::new ( ) ;
let poseidon = Poseidon ::new ( ) ;
let h = poseidon . hash_bytes ( b . to_vec ( ) ) ? ;
let h = poseidon . hash ( hm_input ) ? ;
println ! ( "h {:?}" , h . to_string ( ) ) ;
println ! ( "h {:?}" , h . to_string ( ) ) ;
Ok ( h )
let hB = BigInt ::parse_bytes ( to_hex ( & h ) . as_bytes ( ) , 16 ) . unwrap ( ) ;
Ok ( hB )
}
}
pub fn verify_schnorr ( pk : Point , m : Vec < u8 > , r : Point , s : BigInt ) -> Result < bool , String > {
pub fn verify_schnorr ( pk : Point , m : BigInt , r : Point , s : BigInt ) -> Result < bool , String > {
// sG = s·G
// sG = s·G
let sg = B8 . mul_scalar ( & s ) ? ;
let sg = B8 . mul_scalar ( & s ) ? ;
// r + h · x
// r + h · x
let h = schnorr_hash ( & pk , m , & r ) ? ;
let h = schnorr_hash ( & pk , m , & r ) ? ;
let pk_h = pk . mul_scalar ( & h ) ? ;
let pk_h = pk . mul_scalar ( & h ) ? ;
let right = r . add ( & pk_h ) ? ;
let right = r . projective ( ) . add ( & pk_h . projective ( ) ) ? ;
Ok ( sg . equals ( right ) )
Ok ( sg . equals ( right . affine ( ) ) )
}
}
pub fn new_key ( ) -> PrivateKey {
pub fn new_key ( ) -> PrivateKey {
// https://tools.ietf.org/html/rfc8032#section-5.1.5
// https://tools.ietf.org/html/rfc8032#section-5.1.5
let mut rng = rand ::thread_rng ( ) ;
let mut rng = rand6 ::thread_rng ( ) ;
let sk_raw = rng . gen_biguint ( 1024 ) . to_bigint ( ) . unwrap ( ) ;
let sk_raw = rng . gen_biguint ( 1024 ) . to_bigint ( ) . unwrap ( ) ;
let mut hasher = Blake2b ::new ( ) ;
let mut hasher = Blake2b ::new ( ) ;
@ -322,39 +383,18 @@ pub fn new_key() -> PrivateKey {
PrivateKey { key : sk }
PrivateKey { key : sk }
}
}
pub fn verify_mimc ( pk : Point , sig : Signature , msg : BigInt ) -> bool {
let hm_input = vec ! [
sig . r_b8 . x . clone ( ) ,
sig . r_b8 . y . clone ( ) ,
pk . x . clone ( ) ,
pk . y . clone ( ) ,
msg ,
] ;
let mimc7 = Mimc7 ::new ( ) ;
let hm = match mimc7 . hash ( hm_input ) {
Result ::Err ( _ ) = > return false ,
Result ::Ok ( hm ) = > hm ,
} ;
let l = match B8 . mul_scalar ( & sig . s ) {
Result ::Err ( _ ) = > return false ,
Result ::Ok ( l ) = > l ,
} ;
let r = match sig
. r_b8
. add ( & pk . mul_scalar ( & ( 8. to_bigint ( ) . unwrap ( ) * hm ) ) . unwrap ( ) )
{
Result ::Err ( _ ) = > return false ,
Result ::Ok ( r ) = > r ,
} ;
l . equals ( r )
}
pub fn verify_poseidon ( pk : Point , sig : Signature , msg : BigInt ) -> bool {
pub fn verify ( pk : Point , sig : Signature , msg : BigInt ) -> bool {
if msg > Q . clone ( ) {
return false ;
}
let ( _ , msg_bytes ) = msg . to_bytes_be ( ) ;
let msgFr : Fr = Fr ::from_str ( & msg . to_string ( ) ) . unwrap ( ) ;
let hm_input = vec ! [
let hm_input = vec ! [
sig . r_b8 . x . clone ( ) ,
sig . r_b8 . x . clone ( ) ,
sig . r_b8 . y . clone ( ) ,
sig . r_b8 . y . clone ( ) ,
pk . x . clone ( ) ,
pk . x . clone ( ) ,
pk . y . clone ( ) ,
pk . y . clone ( ) ,
msg ,
msgFr ,
] ;
] ;
let poseidon = Poseidon ::new ( ) ;
let poseidon = Poseidon ::new ( ) ;
let hm = match poseidon . hash ( hm_input ) {
let hm = match poseidon . hash ( hm_input ) {
@ -365,14 +405,16 @@ pub fn verify_poseidon(pk: Point, sig: Signature, msg: BigInt) -> bool {
Result ::Err ( _ ) = > return false ,
Result ::Err ( _ ) = > return false ,
Result ::Ok ( l ) = > l ,
Result ::Ok ( l ) = > l ,
} ;
} ;
let r = match sig
. r_b8
. add ( & pk . mul_scalar ( & ( 8. to_bigint ( ) . unwrap ( ) * hm ) ) . unwrap ( ) )
{
let hmB = BigInt ::parse_bytes ( to_hex ( & hm ) . as_bytes ( ) , 16 ) . unwrap ( ) ;
let r = match sig . r_b8 . projective ( ) . add (
& pk . mul_scalar ( & ( 8. to_bigint ( ) . unwrap ( ) * hmB ) )
. unwrap ( )
. projective ( ) ,
) {
Result ::Err ( _ ) = > return false ,
Result ::Err ( _ ) = > return false ,
Result ::Ok ( r ) = > r ,
Result ::Ok ( r ) = > r ,
} ;
} ;
l . equals ( r )
l . equals ( r . affine ( ) )
}
}
#[ cfg(test) ]
#[ cfg(test) ]
@ -383,102 +425,114 @@ mod tests {
#[ test ]
#[ test ]
fn test_add_same_point ( ) {
fn test_add_same_point ( ) {
let p : Point = Point {
x : BigInt ::parse_bytes (
b" 17777552123799933955779906779655732241715742912184938656739573121738514868268 " ,
10 ,
let p : PointProjective = PointProjective {
x : Fr ::from_str (
"17777552123799933955779906779655732241715742912184938656739573121738514868268" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 2626589144620713026669568689430873010625803728049924121243784502389097019475 " ,
10 ,
y : Fr ::from_str (
"2626589144620713026669568689430873010625803728049924121243784502389097019475" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
z : Fr ::one ( ) ,
} ;
} ;
let q : Point = Point {
x : BigInt ::parse_bytes (
b" 17777552123799933955779906779655732241715742912184938656739573121738514868268 " ,
10 ,
let q : PointProjective = PointProjective {
x : Fr ::from_str (
"17777552123799933955779906779655732241715742912184938656739573121738514868268" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 2626589144620713026669568689430873010625803728049924121243784502389097019475 " ,
10 ,
y : Fr ::from_str (
"2626589144620713026669568689430873010625803728049924121243784502389097019475" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
z : Fr ::one ( ) ,
} ;
} ;
let res = p . add ( & q ) . unwrap ( ) ;
let res = p . add ( & q ) . unwrap ( ) . affine ( ) ;
assert_eq ! (
assert_eq ! (
res . x . to_string ( ) ,
"6890855772600357754907169075114257697580319025794532037257385534741338397365"
res . x ,
Fr ::from_str (
"6890855772600357754907169075114257697580319025794532037257385534741338397365"
)
. unwrap ( )
) ;
) ;
assert_eq ! (
assert_eq ! (
res . y . to_string ( ) ,
"4338620300185947561074059802482547481416142213883829469920100239455078257889"
res . y ,
Fr ::from_str (
"4338620300185947561074059802482547481416142213883829469920100239455078257889"
)
. unwrap ( )
) ;
) ;
}
}
#[ test ]
#[ test ]
fn test_add_different_points ( ) {
fn test_add_different_points ( ) {
let p : Point = Point {
x : BigInt ::parse_bytes (
b" 17777552123799933955779906779655732241715742912184938656739573121738514868268 " ,
10 ,
let p : PointProjective = PointProjective {
x : Fr ::from_str (
"17777552123799933955779906779655732241715742912184938656739573121738514868268" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 2626589144620713026669568689430873010625803728049924121243784502389097019475 " ,
10 ,
y : Fr ::from_str (
"2626589144620713026669568689430873010625803728049924121243784502389097019475" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
z : Fr ::one ( ) ,
} ;
} ;
let q : Point = Point {
x : BigInt ::parse_bytes (
b" 16540640123574156134436876038791482806971768689494387082833631921987005038935 " ,
10 ,
let q : PointProjective = PointProjective {
x : Fr ::from_str (
"16540640123574156134436876038791482806971768689494387082833631921987005038935" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 20819045374670962167435360035096875258406992893633759881276124905556507972311 " ,
10 ,
y : Fr ::from_str (
"20819045374670962167435360035096875258406992893633759881276124905556507972311" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
z : Fr ::one ( ) ,
} ;
} ;
let res = p . add ( & q ) . unwrap ( ) ;
let res = p . add ( & q ) . unwrap ( ) . affine ( ) ;
assert_eq ! (
assert_eq ! (
res . x . to_string ( ) ,
"7916061937171219682591368294088513039687205273691143098332585753343424131937"
res . x ,
Fr ::from_str (
"7916061937171219682591368294088513039687205273691143098332585753343424131937"
)
. unwrap ( )
) ;
) ;
assert_eq ! (
assert_eq ! (
res . y . to_string ( ) ,
"14035240266687799601661095864649209771790948434046947201833777492504781204499"
res . y ,
Fr ::from_str (
"14035240266687799601661095864649209771790948434046947201833777492504781204499"
)
. unwrap ( )
) ;
) ;
}
}
#[ test ]
#[ test ]
fn test_mul_scalar ( ) {
fn test_mul_scalar ( ) {
let p : Point = Point {
let p : Point = Point {
x : BigInt ::parse_bytes (
b" 17777552123799933955779906779655732241715742912184938656739573121738514868268 " ,
10 ,
x : Fr ::from_str (
"17777552123799933955779906779655732241715742912184938656739573121738514868268" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 2626589144620713026669568689430873010625803728049924121243784502389097019475 " ,
10 ,
y : Fr ::from_str (
"2626589144620713026669568689430873010625803728049924121243784502389097019475" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
} ;
} ;
let res_m = p . mul_scalar ( & 3. to_bigint ( ) . unwrap ( ) ) . unwrap ( ) ;
let res_m = p . mul_scalar ( & 3. to_bigint ( ) . unwrap ( ) ) . unwrap ( ) ;
let res_a = p . add ( & p ) . unwrap ( ) ;
let res_a = res_a . add ( & p ) . unwrap ( ) ;
let res_a = p . projective ( ) . add ( & p . projective ( ) ) . unwrap ( ) ;
let res_a = res_a . add ( & p . projective ( ) ) . unwrap ( ) . affine ( ) ;
assert_eq ! ( res_m . x , res_a . x ) ;
assert_eq ! ( res_m . x , res_a . x ) ;
assert_eq ! (
assert_eq ! (
res_m . x . to_string ( ) ,
"19372461775513343691590086534037741906533799473648040012278229434133483800898"
res_m . x ,
Fr ::from_str (
"19372461775513343691590086534037741906533799473648040012278229434133483800898"
)
. unwrap ( )
) ;
) ;
assert_eq ! (
assert_eq ! (
res_m . y . to_string ( ) ,
"9458658722007214007257525444427903161243386465067105737478306991484593958249"
res_m . y ,
Fr ::from_str (
"9458658722007214007257525444427903161243386465067105737478306991484593958249"
)
. unwrap ( )
) ;
) ;
let n = BigInt ::parse_bytes (
let n = BigInt ::parse_bytes (
@ -488,65 +542,70 @@ mod tests {
. unwrap ( ) ;
. unwrap ( ) ;
let res2 = p . mul_scalar ( & n ) . unwrap ( ) ;
let res2 = p . mul_scalar ( & n ) . unwrap ( ) ;
assert_eq ! (
assert_eq ! (
res2 . x . to_string ( ) ,
"17070357974431721403481313912716834497662307308519659060910483826664480189605"
res2 . x ,
Fr ::from_str (
"17070357974431721403481313912716834497662307308519659060910483826664480189605"
)
. unwrap ( )
) ;
) ;
assert_eq ! (
assert_eq ! (
res2 . y . to_string ( ) ,
"4014745322800118607127020275658861516666525056516280575712425373174125159339"
res2 . y ,
Fr ::from_str (
"4014745322800118607127020275658861516666525056516280575712425373174125159339"
)
. unwrap ( )
) ;
) ;
}
}
#[ test ]
fn test_new_key_sign_verify_mimc_0 ( ) {
let sk = new_key ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let msg = 5. to_bigint ( ) . unwrap ( ) ;
let sig = sk . sign_mimc ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify_mimc ( pk , sig , msg ) ;
assert_eq ! ( v , true ) ;
}
// #[test]
// fn test_new_key_sign_verify_mimc_0() {
// let sk = new_key();
// let pk = sk.public().unwrap();
// let msg = 5.to_bigint().unwrap();
// let sig = sk.sign_mimc(msg.clone()).unwrap();
// let v = verify_mimc(pk, sig, msg);
// assert_eq!(v, true);
// }
//
// #[test]
// fn test_new_key_sign_verify_mimc_1() {
// let sk = new_key();
// let pk = sk.public().unwrap();
// let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
// let sig = sk.sign_mimc(msg.clone()).unwrap();
// let v = verify_mimc(pk, sig, msg);
// assert_eq!(v, true);
// }
#[ test ]
#[ test ]
fn test_new_key_sign_verify_mimc_1 ( ) {
let sk = new_key ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let msg = BigInt ::parse_bytes ( b" 123456789012345678901234567890 " , 10 ) . unwrap ( ) ;
let sig = sk . sign_mimc ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify_mimc ( pk , sig , msg ) ;
assert_eq ! ( v , true ) ;
}
#[ test ]
fn test_new_key_sign_verify_poseidon_0 ( ) {
fn test_new_key_sign_verify_0 ( ) {
let sk = new_key ( ) ;
let sk = new_key ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let msg = 5. to_bigint ( ) . unwrap ( ) ;
let msg = 5. to_bigint ( ) . unwrap ( ) ;
let sig = sk . sign_poseidon ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify_poseidon ( pk , sig , msg ) ;
let sig = sk . sign ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify ( pk , sig , msg ) ;
assert_eq ! ( v , true ) ;
assert_eq ! ( v , true ) ;
}
}
#[ test ]
#[ test ]
fn test_new_key_sign_verify_poseidon_ 1 ( ) {
fn test_new_key_sign_verify_1 ( ) {
let sk = new_key ( ) ;
let sk = new_key ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let msg = BigInt ::parse_bytes ( b" 123456789012345678901234567890 " , 10 ) . unwrap ( ) ;
let msg = BigInt ::parse_bytes ( b" 123456789012345678901234567890 " , 10 ) . unwrap ( ) ;
let sig = sk . sign_poseidon ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify_poseidon ( pk , sig , msg ) ;
let sig = sk . sign ( msg . clone ( ) ) . unwrap ( ) ;
let v = verify ( pk , sig , msg ) ;
assert_eq ! ( v , true ) ;
assert_eq ! ( v , true ) ;
}
}
#[ test ]
#[ test ]
fn test_point_compress_decompress ( ) {
fn test_point_compress_decompress ( ) {
let p : Point = Point {
let p : Point = Point {
x : BigInt ::parse_bytes (
b" 17777552123799933955779906779655732241715742912184938656739573121738514868268 " ,
10 ,
x : Fr ::from_str (
"17777552123799933955779906779655732241715742912184938656739573121738514868268" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
y : BigInt ::parse_bytes (
b" 2626589144620713026669568689430873010625803728049924121243784502389097019475 " ,
10 ,
y : Fr ::from_str (
"2626589144620713026669568689430873010625803728049924121243784502389097019475" ,
)
)
. unwrap ( ) ,
. unwrap ( ) ,
} ;
} ;
@ -574,7 +633,8 @@ mod tests {
. unwrap ( ) ;
. unwrap ( ) ;
let mut e_px_bytes : [ u8 ; 32 ] = [ 0 ; 32 ] ;
let mut e_px_bytes : [ u8 ; 32 ] = [ 0 ; 32 ] ;
e_px_bytes . copy_from_slice ( & expected_px_raw ) ;
e_px_bytes . copy_from_slice ( & expected_px_raw ) ;
let expected_px : BigInt = BigInt ::from_bytes_le ( Sign ::Plus , & e_px_bytes ) ;
let expected_px : Fr =
Fr ::from_str ( & BigInt ::from_bytes_le ( Sign ::Plus , & e_px_bytes ) . to_string ( ) ) . unwrap ( ) ;
assert_eq ! ( & p . x , & expected_px ) ;
assert_eq ! ( & p . x , & expected_px ) ;
}
}
@ -592,15 +652,16 @@ mod tests {
. unwrap ( ) ;
. unwrap ( ) ;
let mut e_px_bytes : [ u8 ; 32 ] = [ 0 ; 32 ] ;
let mut e_px_bytes : [ u8 ; 32 ] = [ 0 ; 32 ] ;
e_px_bytes . copy_from_slice ( & expected_px_raw ) ;
e_px_bytes . copy_from_slice ( & expected_px_raw ) ;
let expected_px : BigInt = BigInt ::from_bytes_le ( Sign ::Plus , & e_px_bytes ) ;
let expected_px : Fr =
Fr ::from_str ( & BigInt ::from_bytes_le ( Sign ::Plus , & e_px_bytes ) . to_string ( ) ) . unwrap ( ) ;
assert_eq ! ( & p . x , & expected_px ) ;
assert_eq ! ( & p . x , & expected_px ) ;
}
}
#[ test ]
#[ test ]
fn test_point_decompress_loop ( ) {
fn test_point_decompress_loop ( ) {
for _ in 0 . . 5 {
for _ in 0 . . 5 {
let mut rng = rand ::thread_rng ( ) ;
let sk_raw = rng . gen_biguint ( 1024 ) . to_bigint ( ) . unwrap ( ) ;
let random_bytes = rand6 ::thread_rng ( ) . gen ::< [ u8 ; 32 ] > ( ) ;
let sk_raw : BigInt = BigInt ::from_bytes_le ( Sign ::Plus , & random_bytes [ . . ] ) ;
let mut hasher = Blake2b ::new ( ) ;
let mut hasher = Blake2b ::new ( ) ;
let ( _ , sk_raw_bytes ) = sk_raw . to_bytes_be ( ) ;
let ( _ , sk_raw_bytes ) = sk_raw . to_bytes_be ( ) ;
hasher . input ( sk_raw_bytes ) ;
hasher . input ( sk_raw_bytes ) ;
@ -628,7 +689,7 @@ mod tests {
for i in 0 . . 5 {
for i in 0 . . 5 {
let msg_raw = "123456" . to_owned ( ) + & i . to_string ( ) ;
let msg_raw = "123456" . to_owned ( ) + & i . to_string ( ) ;
let msg = BigInt ::parse_bytes ( msg_raw . as_bytes ( ) , 10 ) . unwrap ( ) ;
let msg = BigInt ::parse_bytes ( msg_raw . as_bytes ( ) , 10 ) . unwrap ( ) ;
let sig = sk . sign_mimc ( msg . clone ( ) ) . unwrap ( ) ;
let sig = sk . sign ( msg . clone ( ) ) . unwrap ( ) ;
let compressed_sig = sig . compress ( ) ;
let compressed_sig = sig . compress ( ) ;
let decompressed_sig = decompress_signature ( & compressed_sig ) . unwrap ( ) ;
let decompressed_sig = decompress_signature ( & compressed_sig ) . unwrap ( ) ;
@ -636,7 +697,7 @@ mod tests {
assert_eq ! ( & sig . r_b8 . y , & decompressed_sig . r_b8 . y ) ;
assert_eq ! ( & sig . r_b8 . y , & decompressed_sig . r_b8 . y ) ;
assert_eq ! ( & sig . s , & decompressed_sig . s ) ;
assert_eq ! ( & sig . s , & decompressed_sig . s ) ;
let v = verify_mimc ( pk . clone ( ) , decompressed_sig , msg ) ;
let v = verify ( pk . clone ( ) , decompressed_sig , msg ) ;
assert_eq ! ( v , true ) ;
assert_eq ! ( v , true ) ;
}
}
}
}
@ -646,7 +707,7 @@ mod tests {
let sk = new_key ( ) ;
let sk = new_key ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let pk = sk . public ( ) . unwrap ( ) ;
let msg : Vec < u8 > = ( "123456" . to_owned ( ) + & 1. to_string ( ) ) . as_bytes ( ) . to_vec ( ) ;
let msg = BigInt ::parse_bytes ( b" 123456789012345678901234567890 " , 10 ) . unwrap ( ) ;
let ( s , e ) = sk . sign_schnorr ( msg . clone ( ) ) . unwrap ( ) ;
let ( s , e ) = sk . sign_schnorr ( msg . clone ( ) ) . unwrap ( ) ;
println ! ( "s {:?}" , s . x . to_string ( ) ) ;
println ! ( "s {:?}" , s . x . to_string ( ) ) ;
println ! ( "s {:?}" , s . y . to_string ( ) ) ;
println ! ( "s {:?}" , s . y . to_string ( ) ) ;