2019-06-14 15:14:06 -07:00
/*
Implementation of the ZK Range Proof scheme , based on :
Efficient Protocols for Set Membership and Range Proofs
Jan Camenisch , Rafik Chaabouni , and abhi shelat
Asiacrypt 2008
* /
extern crate pairing ;
extern crate rand ;
2019-08-30 11:57:21 -07:00
use rand ::Rng ;
2019-06-14 15:14:06 -07:00
use super ::* ;
2019-08-30 11:57:21 -07:00
use cl ::{ Signature , PublicParams , setup , BlindKeyPair , ProofState , SignatureProof } ;
2019-07-12 16:52:16 -07:00
use ped92 ::{ Commitment , CSMultiParams } ;
2019-06-16 09:27:35 -07:00
use pairing ::{ Engine , CurveProjective } ;
2019-06-14 15:14:06 -07:00
use ff ::PrimeField ;
2019-06-16 09:27:35 -07:00
use std ::collections ::HashMap ;
2019-06-14 15:14:06 -07:00
2019-07-02 15:39:23 -07:00
/**
2019-06-14 15:14:06 -07:00
paramsUL contains elements generated by the verifier , which are necessary for the prover .
This must be computed in a trusted setup .
* /
2019-07-29 21:53:58 -07:00
#[ derive(Clone, Serialize, Deserialize) ]
#[ serde(bound(serialize = " <E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize " )) ]
#[ serde(bound(deserialize = " <E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de> " )) ]
2019-06-14 15:14:06 -07:00
struct ParamsUL < E : Engine > {
pub mpk : PublicParams < E > ,
2019-06-16 09:27:35 -07:00
pub signatures : HashMap < String , Signature < E > > ,
2019-07-12 16:52:16 -07:00
pub csParams : CSMultiParams < E > ,
2019-07-01 18:51:24 -07:00
kp : BlindKeyPair < E > ,
2019-06-14 15:14:06 -07:00
// u determines the amount of signatures we need in the public params.
// Each signature can be compressed to just 1 field element of 256 bits.
// Then the parameters have minimum size equal to 256*u bits.
2019-07-19 13:27:15 -07:00
u : i32 ,
2019-06-14 15:14:06 -07:00
// l determines how many pairings we need to compute, then in order to improve
// verifier`s performance we want to minize it.
// Namely, we have 2*l pairings for the prover and 3*l for the verifier.
2019-07-19 13:27:15 -07:00
l : i32 ,
2019-06-14 15:14:06 -07:00
}
2019-07-12 13:43:48 -07:00
#[ derive(Clone) ]
2019-07-19 12:19:28 -07:00
pub struct ProofULState < E : Engine > {
2019-07-19 13:27:15 -07:00
pub decx : Vec < i32 > ,
2019-07-19 12:19:28 -07:00
pub proofStates : Vec < ProofState < E > > ,
pub V : Vec < Signature < E > > ,
pub D : E ::G1 ,
pub m : E ::Fr ,
pub s : Vec < E ::Fr > ,
2019-07-12 13:43:48 -07:00
}
2019-07-02 15:39:23 -07:00
/**
proofUL contains the necessary elements for the ZK range proof with range [ 0 , u ^ l ) .
2019-06-14 15:14:06 -07:00
* /
2019-07-31 19:06:57 -07:00
#[ derive(Clone, Serialize, Deserialize) ]
#[ serde(bound(serialize = " <E as ff::ScalarEngine>::Fr: serde::Serialize, \
< E as pairing ::Engine > ::G1 : serde ::Serialize , \
< E as pairing ::Engine > ::G2 : serde ::Serialize , \
< E as pairing ::Engine > ::Fqk : serde ::Serialize "
) ) ]
#[ serde(bound(deserialize = " <E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
< E as pairing ::Engine > ::G1 : serde ::Deserialize < ' de > , \
< E as pairing ::Engine > ::G2 : serde ::Deserialize < ' de > , \
< E as pairing ::Engine > ::Fqk : serde ::Deserialize < ' de > "
) ) ]
2019-07-19 12:19:28 -07:00
pub struct ProofUL < E : Engine > {
pub V : Vec < Signature < E > > ,
pub D : E ::G1 ,
pub comm : Commitment < E > ,
pub sigProofs : Vec < SignatureProof < E > > ,
pub zr : E ::Fr ,
pub zs : Vec < E ::Fr > ,
2019-06-14 15:14:06 -07:00
}
2019-07-12 13:43:48 -07:00
#[ derive(Clone) ]
pub struct RangeProofState < E : Engine > {
2019-07-19 12:19:28 -07:00
pub com1 : Commitment < E > ,
pub ps1 : ProofULState < E > ,
2019-08-30 12:55:59 -07:00
pub com2 : Option < Commitment < E > > ,
pub ps2 : Option < ProofULState < E > > ,
2019-07-12 13:43:48 -07:00
}
2019-07-02 15:39:23 -07:00
/**
RangeProof contains the necessary elements for the ZK range proof .
* /
2019-07-31 19:06:57 -07:00
#[ derive(Clone, Serialize, Deserialize) ]
#[ serde(bound(serialize = " <E as ff::ScalarEngine>::Fr: serde::Serialize, \
< E as pairing ::Engine > ::G1 : serde ::Serialize , \
< E as pairing ::Engine > ::G2 : serde ::Serialize , \
< E as pairing ::Engine > ::Fqk : serde ::Serialize "
) ) ]
#[ serde(bound(deserialize = " <E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
< E as pairing ::Engine > ::G1 : serde ::Deserialize < ' de > , \
< E as pairing ::Engine > ::G2 : serde ::Deserialize < ' de > , \
< E as pairing ::Engine > ::Fqk : serde ::Deserialize < ' de > "
) ) ]
2019-06-14 15:14:06 -07:00
pub struct RangeProof < E : Engine > {
2019-07-19 12:19:28 -07:00
pub p1 : ProofUL < E > ,
2019-08-30 12:55:59 -07:00
pub p2 : Option < ProofUL < E > > ,
2019-06-14 15:14:06 -07:00
}
2019-07-02 15:39:23 -07:00
/**
2019-06-14 15:14:06 -07:00
params contains elements generated by the verifier , which are necessary for the prover .
This must be computed in a trusted setup .
* /
2019-07-29 21:53:58 -07:00
#[ derive(Clone, Serialize, Deserialize) ]
#[ serde(bound(serialize = " <E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize " )) ]
#[ serde(bound(deserialize = " <E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de> " )) ]
2019-06-14 15:14:06 -07:00
pub struct RPPublicParams < E : Engine > {
p : ParamsUL < E > ,
2019-07-19 13:27:15 -07:00
a : i32 ,
b : i32 ,
2019-06-14 15:14:06 -07:00
}
2019-06-16 13:29:48 -07:00
impl < E : Engine > ParamsUL < E > {
2019-07-02 15:39:23 -07:00
/**
setup_ul generates the signature for the interval [ 0 , u ^ l ) .
The value of u should be roughly b / log ( b ) , but we can choose smaller values in
order to get smaller parameters , at the cost of having worse performance .
* /
2019-07-19 13:27:15 -07:00
pub fn setup_ul < R : Rng > ( rng : & mut R , u : i32 , l : i32 , csParams : CSMultiParams < E > ) -> Self {
2019-06-16 13:29:48 -07:00
let mpk = setup ( rng ) ;
2019-07-01 18:51:24 -07:00
let kp = BlindKeyPair ::< E > ::generate ( rng , & mpk , 1 ) ;
2019-06-14 15:14:06 -07:00
2019-06-16 13:29:48 -07:00
let mut signatures : HashMap < String , Signature < E > > = HashMap ::new ( ) ;
for i in 0 .. u {
let sig_i = kp . sign ( rng , & vec! { E ::Fr ::from_str ( i . to_string ( ) . as_str ( ) ) . unwrap ( ) } ) ;
signatures . insert ( i . to_string ( ) , sig_i ) ;
}
2019-06-14 15:14:06 -07:00
2019-07-12 11:15:00 -07:00
return ParamsUL { mpk , signatures , csParams , kp , u , l } ;
2019-06-14 15:14:06 -07:00
}
2019-07-02 15:39:23 -07:00
/**
prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [ 0 , U ^ L ) .
* /
2019-07-19 13:27:15 -07:00
pub fn prove_ul < R : Rng > ( & self , rng : & mut R , x : i32 , r : E ::Fr , C : Commitment < E > , k : usize , otherM : Vec < E ::Fr > ) -> ProofUL < E > {
2019-07-21 11:55:38 -07:00
let proofUlState = self . prove_ul_commitment ( rng , x , k , None , None ) ;
2019-07-12 13:43:48 -07:00
// Fiat-Shamir heuristic
let mut a = Vec ::< E ::Fqk > ::with_capacity ( self . l as usize ) ;
for state in proofUlState . proofStates . clone ( ) {
a . push ( state . a ) ;
}
let c = hash ::< E > ( a , vec! ( proofUlState . D . clone ( ) ) ) ;
2019-07-19 12:04:56 -07:00
self . prove_ul_response ( r , C , & proofUlState , c , k , otherM )
2019-07-12 13:43:48 -07:00
}
2019-07-21 11:55:38 -07:00
fn prove_ul_commitment < R : Rng > ( & self , rng : & mut R , x : i32 , k : usize , sOptional : Option < Vec < E ::Fr > > , mOptional : Option < E ::Fr > ) -> ProofULState < E > {
2019-06-28 14:44:14 -07:00
if x > self . u . pow ( self . l as u32 ) | | x < 0 {
panic! ( " x is not within the range. " ) ;
}
2019-06-17 12:01:31 -07:00
let decx = decompose ( x , self . u , self . l ) ;
2019-06-16 09:27:35 -07:00
2019-07-02 15:39:23 -07:00
// Initialize variables
2019-07-03 12:56:41 -07:00
let mut proofStates = Vec ::< ProofState < E > > ::with_capacity ( self . l as usize ) ;
2019-07-02 15:39:23 -07:00
let mut V = Vec ::< Signature < E > > ::with_capacity ( self . l as usize ) ;
2019-07-19 12:04:56 -07:00
let mut s = Vec ::< E ::Fr > ::with_capacity ( self . csParams . pub_bases . len ( ) - 2 ) ;
2019-07-12 07:46:25 -07:00
let mut D = E ::G1 ::zero ( ) ;
2019-07-21 11:55:38 -07:00
let m = mOptional . unwrap_or ( E ::Fr ::rand ( rng ) ) ;
2019-06-16 09:27:35 -07:00
2019-06-18 13:20:16 -07:00
// D = H^m
2019-07-12 16:52:16 -07:00
let mut hm = self . csParams . pub_bases [ 0 ] . clone ( ) ;
2019-06-17 12:01:31 -07:00
hm . mul_assign ( m ) ;
2019-06-26 10:33:08 -07:00
for i in 0 .. self . l as usize {
2019-07-01 18:51:24 -07:00
let signature = self . signatures . get ( & decx [ i ] . to_string ( ) ) . unwrap ( ) ;
2019-07-21 08:02:36 -07:00
let proofState = self . kp . prove_commitment ( rng , & self . mpk , & signature , None , None ) ;
2019-07-01 18:51:24 -07:00
2019-07-03 12:56:41 -07:00
V . push ( proofState . blindSig . clone ( ) ) ;
proofStates . push ( proofState ) ;
2019-06-16 09:27:35 -07:00
2019-06-16 13:29:48 -07:00
let ui = self . u . pow ( i as u32 ) ;
2019-07-12 16:52:16 -07:00
let mut aux = self . csParams . pub_bases [ k ] . clone ( ) ;
2019-07-12 07:46:25 -07:00
for j in 0 .. self . kp . public . Y1 . len ( ) {
2019-07-03 12:56:41 -07:00
let mut muiti = proofStates [ i ] . t [ j ] . clone ( ) ;
2019-07-02 14:28:49 -07:00
muiti . mul_assign ( & E ::Fr ::from_str ( & ui . to_string ( ) ) . unwrap ( ) ) ;
aux . mul_assign ( muiti ) ;
}
2019-06-16 13:29:48 -07:00
D . add_assign ( & aux ) ;
2019-06-26 10:33:08 -07:00
}
2019-07-21 11:55:38 -07:00
let sVec = sOptional . unwrap_or ( Vec ::< E ::Fr > ::with_capacity ( 0 ) ) ;
2019-07-19 12:04:56 -07:00
for i in 1 .. self . csParams . pub_bases . len ( ) {
if i ! = k {
let mut g = self . csParams . pub_bases [ i ] . clone ( ) ;
2019-07-21 11:55:38 -07:00
let s1 : E ::Fr ;
if sVec . len ( ) > = i {
2019-08-30 12:55:59 -07:00
s1 = sVec [ i - 1 ] ;
2019-07-21 11:55:38 -07:00
} else {
s1 = E ::Fr ::rand ( rng ) ;
}
2019-07-19 12:04:56 -07:00
s . push ( s1 ) ;
g . mul_assign ( s1 ) ;
D . add_assign ( & g ) ;
}
}
2019-06-17 12:01:31 -07:00
D . add_assign ( & hm ) ;
2019-07-19 12:04:56 -07:00
ProofULState { decx , proofStates , V , D , m , s }
2019-07-12 13:43:48 -07:00
}
2019-06-16 13:29:48 -07:00
2019-07-19 12:04:56 -07:00
fn prove_ul_response ( & self , r : E ::Fr , C : Commitment < E > , proofUlState : & ProofULState < E > , c : E ::Fr , k : usize , otherM : Vec < E ::Fr > ) -> ProofUL < E > {
2019-07-12 13:43:48 -07:00
let mut sigProofs = Vec ::< SignatureProof < E > > ::with_capacity ( self . l as usize ) ;
let mut zr = proofUlState . m . clone ( ) ;
2019-06-17 12:01:31 -07:00
let mut rc = r . clone ( ) ;
rc . mul_assign ( & c ) ;
2019-06-18 13:20:16 -07:00
zr . add_assign ( & rc ) ;
2019-06-16 13:29:48 -07:00
for i in 0 .. self . l as usize {
2019-07-21 11:55:38 -07:00
let dx = E ::Fr ::from_str ( & proofUlState . decx [ i ] . to_string ( ) ) . unwrap ( ) ;
2019-07-01 18:51:24 -07:00
2019-07-12 13:43:48 -07:00
let proof = self . kp . prove_response ( & proofUlState . proofStates [ i ] . clone ( ) , c , & mut vec! { dx } ) ;
2019-07-01 18:51:24 -07:00
2019-07-03 12:56:41 -07:00
sigProofs . push ( proof ) ;
2019-06-17 12:01:31 -07:00
}
2019-07-19 12:04:56 -07:00
let mut zs = Vec ::< E ::Fr > ::with_capacity ( self . csParams . pub_bases . len ( ) - 2 ) ;
for i in 1 .. self . csParams . pub_bases . len ( ) {
2019-07-21 11:55:38 -07:00
let j : usize ;
2019-07-19 12:04:56 -07:00
if i < k {
j = i - 1 ;
} else if i > k {
j = i - 2 ;
} else {
continue ;
}
let mut mc = otherM [ j ] . clone ( ) ;
mc . mul_assign ( & c ) ;
let mut s = proofUlState . s [ j ] . clone ( ) ;
s . add_assign ( & mc ) ;
zs . push ( s ) ;
}
ProofUL { V : proofUlState . V . clone ( ) , D : proofUlState . D . clone ( ) , comm : C , sigProofs , zr , zs }
2019-06-17 12:01:31 -07:00
}
2019-07-02 15:39:23 -07:00
/**
verify_ul is used to validate the ZKRP proof . It returns true iff the proof is valid .
* /
2019-07-12 16:52:16 -07:00
pub fn verify_ul ( & self , proof : & ProofUL < E > , ch : E ::Fr , k : usize ) -> bool {
let r1 = self . verify_part1 ( & proof , ch . clone ( ) , k ) ;
2019-07-12 08:01:40 -07:00
let r2 = self . verify_part2 ( & proof , ch . clone ( ) ) ;
2019-07-19 12:04:56 -07:00
r1 & & r2
2019-07-04 08:35:55 -07:00
}
2019-07-12 08:01:40 -07:00
fn compute_challenge ( & self , proof : & ProofUL < E > ) -> E ::Fr {
2019-07-04 08:35:55 -07:00
let mut a = Vec ::< E ::Fqk > ::with_capacity ( self . l as usize ) ;
for sigProof in proof . sigProofs . clone ( ) {
a . push ( sigProof . a ) ;
}
2019-07-12 13:43:48 -07:00
hash ::< E > ( a , vec! ( proof . D . clone ( ) ) )
2019-06-17 12:01:31 -07:00
}
2019-07-12 08:01:40 -07:00
fn verify_part2 ( & self , proof : & ProofUL < E > , challenge : E ::Fr ) -> bool {
2019-06-17 12:01:31 -07:00
let mut r2 = true ;
for i in 0 .. self . l as usize {
2019-07-12 08:01:40 -07:00
let subResult = self . kp . public . verify_proof ( & self . mpk , proof . V [ i ] . clone ( ) , proof . sigProofs [ i ] . clone ( ) , challenge ) ;
2019-06-18 13:20:16 -07:00
2019-07-01 18:51:24 -07:00
r2 = r2 & & subResult ;
}
r2
}
2019-06-18 13:20:16 -07:00
2019-07-12 16:52:16 -07:00
fn verify_part1 ( & self , proof : & ProofUL < E > , challenge : E ::Fr , k : usize ) -> bool {
2019-07-12 07:46:25 -07:00
let mut D = proof . comm . c . clone ( ) ;
2019-07-12 08:01:40 -07:00
D . mul_assign ( challenge ) ;
2019-06-18 13:20:16 -07:00
D . negate ( ) ;
2019-07-12 16:52:16 -07:00
let mut hzr = self . csParams . pub_bases [ 0 ] . clone ( ) ;
2019-06-17 12:01:31 -07:00
hzr . mul_assign ( proof . zr ) ;
D . add_assign ( & hzr ) ;
2019-07-02 14:28:49 -07:00
for i in 0 .. self . l as usize {
2019-06-17 12:01:31 -07:00
let ui = self . u . pow ( i as u32 ) ;
2019-07-12 16:52:16 -07:00
let mut aux = self . csParams . pub_bases [ k ] . clone ( ) ;
2019-07-12 07:46:25 -07:00
for j in 0 .. self . kp . public . Y1 . len ( ) {
2019-07-03 12:56:41 -07:00
let mut muizsigi = proof . sigProofs [ i ] . zsig [ j ] ;
2019-07-02 14:28:49 -07:00
muizsigi . mul_assign ( & E ::Fr ::from_str ( & ui . to_string ( ) ) . unwrap ( ) ) ;
aux . mul_assign ( muizsigi ) ;
}
2019-06-17 12:01:31 -07:00
D . add_assign ( & aux ) ;
2019-06-16 13:29:48 -07:00
}
2019-07-19 12:04:56 -07:00
for i in 1 .. self . csParams . pub_bases . len ( ) {
2019-07-21 11:55:38 -07:00
let j : usize ;
2019-07-19 12:04:56 -07:00
if i < k {
j = i - 1 ;
} else if i > k {
j = i - 2 ;
} else {
continue ;
}
let mut g = self . csParams . pub_bases [ i ] . clone ( ) ;
g . mul_assign ( proof . zs [ j ] . into_repr ( ) ) ;
D . add_assign ( & g ) ;
}
2019-07-04 08:35:55 -07:00
D = = proof . D
2019-06-16 09:27:35 -07:00
}
}
2019-07-12 13:43:48 -07:00
fn hash < E : Engine > ( a : Vec < E ::Fqk > , D : Vec < E ::G1 > ) -> E ::Fr {
2019-07-19 12:04:56 -07:00
// create a Sha256 object
2019-06-16 09:27:35 -07:00
let mut a_vec : Vec < u8 > = Vec ::new ( ) ;
for a_el in a {
2019-07-04 08:35:55 -07:00
a_vec . extend ( format! ( " {} " , a_el ) . bytes ( ) ) ;
2019-06-16 09:27:35 -07:00
}
let mut x_vec : Vec < u8 > = Vec ::new ( ) ;
2019-07-12 13:43:48 -07:00
for d_el in D {
x_vec . extend ( format! ( " {} " , d_el ) . bytes ( ) ) ;
}
2019-06-16 09:27:35 -07:00
a_vec . extend ( x_vec ) ;
2019-07-04 08:35:55 -07:00
util ::hash_to_fr ::< E > ( a_vec )
2019-06-16 09:27:35 -07:00
}
2019-06-14 15:14:06 -07:00
2019-06-16 13:29:48 -07:00
/*
Decompose receives as input an integer x and outputs an array of integers such that
x = sum ( xi . u ^ i ) , i . e . it returns the decomposition of x into base u .
* /
2019-07-19 13:27:15 -07:00
fn decompose ( x : i32 , u : i32 , l : i32 ) -> Vec < i32 > {
2019-06-16 13:29:48 -07:00
let mut result = Vec ::with_capacity ( l as usize ) ;
let mut decomposer = x . clone ( ) ;
2019-06-26 10:33:08 -07:00
for _i in 0 .. l {
2019-06-16 13:29:48 -07:00
result . push ( decomposer % u ) ;
decomposer = decomposer / u ;
}
return result ;
}
2019-06-16 12:38:07 -07:00
impl < E : Engine > RPPublicParams < E > {
2019-07-02 15:39:23 -07:00
/**
Setup receives integers a and b , and configures the parameters for the rangeproof scheme .
2019-06-16 12:38:07 -07:00
* /
2019-07-19 13:27:15 -07:00
pub fn setup < R : Rng > ( rng : & mut R , a : i32 , b : i32 , csParams : CSMultiParams < E > ) -> Self {
2019-07-19 12:04:56 -07:00
// Compute optimal values for u and l
2019-06-16 12:38:07 -07:00
if a > b {
panic! ( " a must be less than or equal to b " ) ;
}
2019-07-21 12:13:18 -07:00
2019-07-19 13:27:15 -07:00
let logb = ( b as f32 ) . log2 ( ) ;
2019-07-01 18:51:24 -07:00
let loglogb = logb . log2 ( ) ;
if loglogb > 0.0 {
2019-07-19 13:27:15 -07:00
let mut u = ( logb / loglogb ) as i32 ;
2019-07-21 12:13:18 -07:00
u = 57 ; //TODO: optimize u?
2019-07-19 13:27:15 -07:00
let l = ( b as f32 ) . log ( u as f32 ) . ceil ( ) as i32 ;
2019-07-12 11:15:00 -07:00
let params_out : ParamsUL < E > = ParamsUL ::< E > ::setup_ul ( rng , u , l , csParams . clone ( ) ) ;
2019-07-01 18:51:24 -07:00
return RPPublicParams { p : params_out , a , b } ;
2019-06-14 15:14:06 -07:00
} else {
2019-07-01 18:51:24 -07:00
panic! ( " log(log(b)) is zero " ) ;
2019-06-14 15:14:06 -07:00
}
}
2019-06-18 15:17:51 -07:00
2019-07-02 15:39:23 -07:00
/**
Prove method is responsible for generating the zero knowledge range proof .
2019-06-18 15:17:51 -07:00
* /
2019-07-19 13:27:15 -07:00
pub fn prove < R : Rng > ( & self , rng : & mut R , x : i32 , C : Commitment < E > , r : E ::Fr , k : usize , otherM : Vec < E ::Fr > ) -> RangeProof < E > {
2019-07-21 11:55:38 -07:00
let rpState = self . prove_commitment ( rng , x , C , k , None , None ) ;
2019-07-12 13:43:48 -07:00
let mut a = Vec ::< E ::Fqk > ::with_capacity ( self . p . l as usize ) ;
for i in 0 .. rpState . ps1 . proofStates . len ( ) {
a . push ( rpState . ps1 . proofStates [ i ] . a ) ;
2019-08-30 12:55:59 -07:00
if rpState . ps2 . is_some ( ) {
a . push ( rpState . ps2 . clone ( ) . unwrap ( ) . proofStates [ i ] . a ) ;
}
2019-07-12 13:43:48 -07:00
}
2019-08-30 12:55:59 -07:00
let ch = match rpState . ps2 . is_some ( ) {
true = > hash ::< E > ( a , vec! ( rpState . ps1 . D . clone ( ) , rpState . ps2 . clone ( ) . unwrap ( ) . D ) ) ,
false = > hash ::< E > ( a , vec! ( rpState . ps1 . D . clone ( ) ) )
} ;
2019-07-12 13:43:48 -07:00
2019-07-19 12:04:56 -07:00
self . prove_response ( r , & rpState , ch , k , otherM )
2019-07-12 13:43:48 -07:00
}
2019-07-21 11:55:38 -07:00
pub fn prove_commitment < R : Rng > ( & self , rng : & mut R , x : i32 , C : Commitment < E > , k : usize , sOptional : Option < Vec < E ::Fr > > , mOptional : Option < E ::Fr > ) -> RangeProofState < E > {
2019-06-28 14:44:14 -07:00
if x > self . b | | x < self . a {
panic! ( " x is not within the range. " ) ;
}
2019-06-18 15:17:51 -07:00
let ul = self . p . u . pow ( self . p . l as u32 ) ;
// x - b + ul
2019-06-26 09:37:27 -07:00
let xb = x - self . b + ul ;
2019-07-12 16:52:16 -07:00
let mut gb = self . p . csParams . pub_bases [ k ] . clone ( ) ;
2019-07-12 11:15:00 -07:00
let mut b = E ::Fr ::from_str ( & ( self . b . to_string ( ) ) ) . unwrap ( ) ;
b . negate ( ) ;
gb . mul_assign ( b . into_repr ( ) ) ;
2019-07-12 16:52:16 -07:00
let mut gul = self . p . csParams . pub_bases [ k ] . clone ( ) ;
2019-07-12 11:15:00 -07:00
gul . mul_assign ( E ::Fr ::from_str ( & ( ul . to_string ( ) ) ) . unwrap ( ) . into_repr ( ) ) ;
let mut comXB = C . clone ( ) ;
comXB . c . add_assign ( & gb ) ;
comXB . c . add_assign ( & gul ) ;
2019-07-21 11:55:38 -07:00
let firstState = self . p . prove_ul_commitment ( rng , xb , k , sOptional . clone ( ) , mOptional . clone ( ) ) ;
2019-06-18 15:17:51 -07:00
// x - a
2019-08-30 12:55:59 -07:00
let mut comXAOption = None ;
let mut secondState = None ;
if self . a ! = 0 | | x < 0 {
let xa = x - self . a ;
let mut ga = self . p . csParams . pub_bases [ k ] . clone ( ) ;
let mut a = E ::Fr ::from_str ( & ( self . a . to_string ( ) ) ) . unwrap ( ) ;
a . negate ( ) ;
ga . mul_assign ( a . into_repr ( ) ) ;
let mut comXA = C . clone ( ) ;
comXA . c . add_assign ( & ga ) ;
comXAOption = Some ( comXA ) ;
secondState = Some ( self . p . prove_ul_commitment ( rng , xa , k , sOptional . clone ( ) , mOptional . clone ( ) ) ) ;
}
RangeProofState { com1 : comXB , ps1 : firstState , com2 : comXAOption , ps2 : secondState }
2019-07-12 13:43:48 -07:00
}
2019-06-18 15:17:51 -07:00
2019-07-19 12:04:56 -07:00
pub fn prove_response ( & self , r : E ::Fr , rpState : & RangeProofState < E > , ch : E ::Fr , k : usize , otherM : Vec < E ::Fr > ) -> RangeProof < E > {
let first = self . p . prove_ul_response ( r . clone ( ) , rpState . com1 . clone ( ) , & rpState . ps1 , ch . clone ( ) , k , otherM . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let mut second = None ;
if rpState . com2 . is_some ( ) & & rpState . ps2 . is_some ( ) {
second = Some ( self . p . prove_ul_response ( r . clone ( ) , rpState . com2 . clone ( ) . unwrap ( ) , & rpState . ps2 . clone ( ) . unwrap ( ) , ch . clone ( ) , k , otherM . clone ( ) ) ) ;
}
2019-07-12 13:43:48 -07:00
RangeProof { p1 : first , p2 : second }
2019-06-18 15:17:51 -07:00
}
2019-07-02 15:39:23 -07:00
/**
Verify is responsible for validating the range proof .
2019-06-18 15:17:51 -07:00
* /
2019-07-12 16:52:16 -07:00
pub fn verify ( & self , proof : RangeProof < E > , ch : E ::Fr , k : usize ) -> bool {
let first = self . p . verify_ul ( & proof . p1 , ch . clone ( ) , k ) ;
2019-08-30 12:55:59 -07:00
let mut second = true ;
if proof . p2 . is_some ( ) {
second = self . p . verify_ul ( & proof . p2 . unwrap ( ) , ch . clone ( ) , k ) ;
}
first & & second
2019-07-12 16:52:16 -07:00
}
2019-08-30 11:57:21 -07:00
pub fn compute_challenge ( & self , proof : & RangeProof < E > ) -> E ::Fr {
2019-07-12 13:43:48 -07:00
let mut a = Vec ::< E ::Fqk > ::with_capacity ( self . p . l as usize ) ;
for i in 0 .. proof . p1 . sigProofs . len ( ) {
a . push ( proof . p1 . sigProofs [ i ] . a ) ;
2019-08-30 12:55:59 -07:00
if proof . p2 . is_some ( ) {
a . push ( proof . p2 . clone ( ) . unwrap ( ) . sigProofs [ i ] . a ) ;
}
}
match proof . p2 . is_some ( ) {
true = > hash ::< E > ( a . clone ( ) , vec! ( proof . p1 . D . clone ( ) , proof . p2 . clone ( ) . unwrap ( ) . D ) ) ,
false = > hash ::< E > ( a , vec! ( proof . p1 . D . clone ( ) ) )
2019-07-12 13:43:48 -07:00
}
2019-06-18 15:17:51 -07:00
}
2019-06-14 15:14:06 -07:00
}
#[ cfg(test) ]
mod tests {
use super ::* ;
2019-08-30 11:57:21 -07:00
use pairing ::bls12_381 ::{ Bls12 , G1 , Fr } ;
2019-06-28 14:44:14 -07:00
use time ::PreciseTime ;
use std ::ops ::Add ;
use core ::mem ;
2019-07-04 08:35:55 -07:00
use rand ::rngs ::ThreadRng ;
2019-06-14 15:14:06 -07:00
#[ test ]
fn setup_ul_works ( ) {
2019-06-16 13:29:48 -07:00
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
2019-07-12 11:15:00 -07:00
2019-07-12 16:52:16 -07:00
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 3 , csParams . clone ( ) ) ;
2019-06-17 12:01:31 -07:00
assert_eq! ( params . signatures . len ( ) , 2 ) ;
2019-06-16 13:29:48 -07:00
for ( m , s ) in params . signatures {
2019-07-02 14:28:49 -07:00
assert_eq! ( params . kp . verify ( & params . mpk , & vec! { Fr ::from_str ( m . to_string ( ) . as_str ( ) ) . unwrap ( ) } , & Fr ::zero ( ) , & s ) , true ) ;
2019-06-14 15:14:06 -07:00
}
}
2019-06-16 13:29:48 -07:00
#[ test ]
fn prove_ul_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
2019-07-12 11:15:00 -07:00
2019-07-12 16:52:16 -07:00
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 4 , csParams . clone ( ) ) ;
2019-06-16 13:29:48 -07:00
let fr = Fr ::rand ( rng ) ;
2019-07-12 11:15:00 -07:00
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove_ul ( rng , 10 , fr , C , 1 , vec! { } ) ;
2019-06-28 14:44:14 -07:00
assert_eq! ( proof . V . len ( ) , 4 ) ;
2019-07-03 12:56:41 -07:00
assert_eq! ( proof . sigProofs . len ( ) , 4 ) ;
2019-06-28 14:44:14 -07:00
}
#[ test ]
#[ should_panic(expected = " x is not within the range " ) ]
fn prove_ul_not_in_range ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 3 , csParams . clone ( ) ) ;
2019-06-28 14:44:14 -07:00
let fr = Fr ::rand ( rng ) ;
2019-07-12 11:15:00 -07:00
let modx = Fr ::from_str ( & ( 100. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
params . prove_ul ( rng , 100 , fr , C , 1 , vec! { } ) ;
2019-06-17 12:01:31 -07:00
}
#[ test ]
fn prove_and_verify_part1_ul_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 4 , csParams . clone ( ) ) ;
2019-06-17 12:01:31 -07:00
let fr = Fr ::rand ( rng ) ;
2019-07-12 11:15:00 -07:00
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove_ul ( rng , 10 , fr , C , 1 , vec! { } ) ;
2019-07-12 08:01:40 -07:00
let ch = params . compute_challenge ( & proof ) ;
2019-07-12 16:52:16 -07:00
assert_eq! ( params . verify_part1 ( & proof , ch , 1 ) , true ) ;
2019-06-17 12:01:31 -07:00
}
#[ test ]
fn prove_and_verify_part2_ul_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 4 , csParams . clone ( ) ) ;
2019-06-17 12:01:31 -07:00
let fr = Fr ::rand ( rng ) ;
2019-07-12 11:15:00 -07:00
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove_ul ( rng , 10 , fr , C , 1 , vec! { } ) ;
2019-07-12 08:01:40 -07:00
let ch = params . compute_challenge ( & proof ) ;
assert_eq! ( params . verify_part2 ( & proof , ch ) , true ) ;
2019-06-17 12:01:31 -07:00
}
2019-06-16 13:29:48 -07:00
2019-06-17 12:01:31 -07:00
#[ test ]
fn prove_and_verify_ul_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 4 , csParams . clone ( ) ) ;
2019-06-17 12:01:31 -07:00
let fr = Fr ::rand ( rng ) ;
2019-07-12 11:15:00 -07:00
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove_ul ( rng , 10 , fr , C , 1 , vec! { } ) ;
2019-07-12 13:43:48 -07:00
let ch = params . compute_challenge ( & proof ) ;
2019-07-12 16:52:16 -07:00
assert_eq! ( params . verify_ul ( & proof , ch , 1 ) , true ) ;
}
#[ test ]
fn prove_and_verify_ul_bigger_commit_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
let csParams = CSMultiParams ::setup_gen_params ( rng , 3 ) ;
let params = ParamsUL ::< Bls12 > ::setup_ul ( rng , 2 , 4 , csParams . clone ( ) ) ;
let fr = Fr ::rand ( rng ) ;
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-19 12:04:56 -07:00
let fr1 = Fr ::rand ( rng ) ;
let fr2 = Fr ::rand ( rng ) ;
let C = csParams . commit ( & vec! ( fr1 , modx , fr2 ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove_ul ( rng , 10 , fr , C , 2 , vec! { fr1 , fr2 } ) ;
2019-07-12 16:52:16 -07:00
let ch = params . compute_challenge ( & proof ) ;
assert_eq! ( params . verify_ul ( & proof , ch , 2 ) , true ) ;
2019-06-16 13:29:48 -07:00
}
2019-06-18 15:17:51 -07:00
#[ test ]
fn prove_and_verify_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = RPPublicParams ::< Bls12 > ::setup ( rng , 2 , 25 , csParams . clone ( ) ) ;
2019-07-12 11:15:00 -07:00
let fr = Fr ::rand ( rng ) ;
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove ( rng , 10 , C , fr , 1 , vec! { } ) ;
2019-07-12 16:52:16 -07:00
let ch = params . compute_challenge ( & proof ) ;
assert_eq! ( params . verify ( proof , ch , 1 ) , true ) ;
}
#[ test ]
fn prove_and_verify_bigger_commit_works ( ) {
let rng = & mut rand ::thread_rng ( ) ;
let csParams = CSMultiParams ::setup_gen_params ( rng , 3 ) ;
let params = RPPublicParams ::< Bls12 > ::setup ( rng , 2 , 25 , csParams . clone ( ) ) ;
let fr = Fr ::rand ( rng ) ;
let modx = Fr ::from_str ( & ( 10. to_string ( ) ) ) . unwrap ( ) ;
2019-07-19 12:04:56 -07:00
let fr1 = Fr ::rand ( rng ) ;
let fr2 = Fr ::rand ( rng ) ;
let C = csParams . commit ( & vec! ( fr1 , modx , fr2 ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove ( rng , 10 , C , fr , 2 , vec! { fr1 , fr2 } ) ;
2019-07-12 16:52:16 -07:00
let ch = params . compute_challenge ( & proof ) ;
assert_eq! ( params . verify ( proof , ch , 2 ) , true ) ;
2019-06-18 15:17:51 -07:00
}
2019-06-28 14:44:14 -07:00
#[ test ]
#[ should_panic(expected = " x is not within the range " ) ]
fn prove_not_in_range ( ) {
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = RPPublicParams ::< Bls12 > ::setup ( rng , 2 , 25 , csParams . clone ( ) ) ;
2019-07-12 11:15:00 -07:00
let fr = Fr ::rand ( rng ) ;
let modx = Fr ::from_str ( & ( 26. to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
params . prove ( rng , 26 , C , fr , 1 , vec! { } ) ;
2019-06-28 14:44:14 -07:00
}
#[ test ]
#[ ignore ]
fn prove_and_verify_performance ( ) {
let rng = & mut rand ::thread_rng ( ) ;
let mut averageSetup = time ::Duration ::nanoseconds ( 0 ) ;
let mut averageSetupSize = 0 ;
let mut averageProve = time ::Duration ::nanoseconds ( 0 ) ;
let mut averageProofSize = 0 ;
let mut averageVerify = time ::Duration ::nanoseconds ( 0 ) ;
let iter = 5 ;
2019-08-30 11:57:21 -07:00
for _i in 0 .. iter {
2019-06-28 14:44:14 -07:00
let a = rng . gen_range ( 0 , 1000000 ) ;
let b = rng . gen_range ( a , 1000000 ) ;
let x = rng . gen_range ( a , b ) ;
let sSetup = PreciseTime ::now ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
let params = RPPublicParams ::< Bls12 > ::setup ( rng , a , b , csParams . clone ( ) ) ;
2019-06-28 14:44:14 -07:00
averageSetup = averageSetup . add ( sSetup . to ( PreciseTime ::now ( ) ) ) ;
averageSetupSize + = mem ::size_of_val ( & params ) ;
let sProve = PreciseTime ::now ( ) ;
2019-07-12 11:15:00 -07:00
let fr = Fr ::rand ( rng ) ;
let modx = Fr ::from_str ( & ( x . to_string ( ) ) ) . unwrap ( ) ;
2019-07-12 16:52:16 -07:00
let C = csParams . commit ( & vec! ( modx ) , & fr . clone ( ) ) ;
2019-08-30 12:55:59 -07:00
let proof = params . prove ( rng , x , C , fr , 1 , vec! { } ) ;
2019-06-28 14:44:14 -07:00
averageProve = averageProve . add ( sProve . to ( PreciseTime ::now ( ) ) ) ;
averageProofSize + = mem ::size_of_val ( & proof ) ;
let sVerify = PreciseTime ::now ( ) ;
2019-07-12 16:52:16 -07:00
let ch = params . compute_challenge ( & proof ) ;
params . verify ( proof , ch , 1 ) ;
2019-06-28 14:44:14 -07:00
averageVerify = averageVerify . add ( sVerify . to ( PreciseTime ::now ( ) ) ) ;
}
print! ( " Setup: {} \n " , averageSetup . num_milliseconds ( ) / iter ) ;
print! ( " Setup size: {} \n " , averageSetupSize / iter as usize ) ;
print! ( " Prove: {} \n " , averageProve . num_milliseconds ( ) / iter ) ;
print! ( " Proof size: {} \n " , averageProofSize / iter as usize ) ;
print! ( " Verify: {} \n " , averageVerify . num_milliseconds ( ) / iter ) ;
}
2019-06-14 15:14:06 -07:00
#[ test ]
fn decompose_works ( ) {
2019-06-17 12:01:31 -07:00
assert_eq! ( decompose ( 25 , 3 , 3 ) , vec! { 1 , 2 , 2 } ) ;
assert_eq! ( decompose ( 336 , 7 , 3 ) , vec! { 0 , 6 , 6 } ) ;
assert_eq! ( decompose ( 285 , 8 , 3 ) , vec! { 5 , 3 , 4 } ) ;
assert_eq! ( decompose ( 125 , 13 , 2 ) , vec! { 8 , 9 } ) ;
assert_eq! ( decompose ( 143225 , 6 , 7 ) , vec! { 5 , 2 , 0 , 3 , 2 , 0 , 3 } ) ;
}
#[ test ]
fn decompose_recompose_works ( ) {
let vec1 = decompose ( 25 , 3 , 5 ) ;
let mut result = 0 ;
for i in 0 .. 5 {
2019-07-19 13:27:15 -07:00
result + = vec1 [ i ] * 3 i32 . pow ( i as u32 ) ;
2019-06-17 12:01:31 -07:00
}
assert_eq! ( result , 25 ) ;
let vec1 = decompose ( 143225 , 6 , 7 ) ;
let mut result = 0 ;
for i in 0 .. 7 {
2019-07-19 13:27:15 -07:00
result + = vec1 [ i ] * 6 i32 . pow ( i as u32 ) ;
2019-06-17 12:01:31 -07:00
}
assert_eq! ( result , 143225 ) ;
2019-06-14 15:14:06 -07:00
}
#[ test ]
fn setup_works ( ) {
2019-06-16 13:29:48 -07:00
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
2019-07-12 11:15:00 -07:00
let public_params = RPPublicParams ::< Bls12 > ::setup ( rng , 2 , 10 , csParams ) ;
2019-06-17 12:01:31 -07:00
assert_eq! ( public_params . a , 2 ) ;
assert_eq! ( public_params . b , 10 ) ;
2019-07-21 12:13:18 -07:00
assert_eq! ( public_params . p . signatures . len ( ) , 57 ) ;
assert_eq! ( public_params . p . u , 57 ) ;
assert_eq! ( public_params . p . l , 1 ) ;
2019-06-14 15:14:06 -07:00
for ( m , s ) in public_params . p . signatures {
2019-07-02 14:28:49 -07:00
assert_eq! ( public_params . p . kp . verify ( & public_params . p . mpk , & vec! { Fr ::from_str ( m . to_string ( ) . as_str ( ) ) . unwrap ( ) } , & Fr ::zero ( ) , & s ) , true ) ;
2019-06-14 15:14:06 -07:00
}
}
#[ test ]
#[ should_panic(expected = " a must be less than or equal to b " ) ]
fn setup_wrong_a_and_b ( ) {
2019-06-16 13:29:48 -07:00
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
2019-07-12 11:15:00 -07:00
RPPublicParams ::< Bls12 > ::setup ( rng , 10 , 2 , csParams ) ;
2019-06-14 15:14:06 -07:00
}
#[ test ]
2019-07-01 18:51:24 -07:00
#[ should_panic(expected = " log(log(b)) is zero " ) ]
2019-06-14 15:14:06 -07:00
fn setup_wrong_logb ( ) {
2019-06-16 13:29:48 -07:00
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 16:52:16 -07:00
let csParams = CSMultiParams ::setup_gen_params ( rng , 1 ) ;
2019-07-12 11:15:00 -07:00
RPPublicParams ::< Bls12 > ::setup ( rng , - 2 , - 1 , csParams ) ;
2019-06-16 12:38:07 -07:00
}
#[ test ]
fn hash_works ( ) {
2019-06-16 13:29:48 -07:00
let rng = & mut rand ::thread_rng ( ) ;
2019-07-12 07:46:25 -07:00
let D = G1 ::rand ( rng ) ;
let D2 = G1 ::rand ( rng ) ;
2019-07-04 08:35:55 -07:00
let params = setup ::< ThreadRng , Bls12 > ( rng ) ;
2019-07-03 12:56:41 -07:00
let kp = BlindKeyPair ::generate ( rng , & params , 2 ) ;
let m1 = Fr ::rand ( rng ) ;
let m2 = Fr ::rand ( rng ) ;
let sig = kp . sign ( rng , & vec! { m1 , m2 } ) ;
2019-07-21 08:02:36 -07:00
let state = kp . prove_commitment ( rng , & params , & sig , None , None ) ;
let state1 = kp . prove_commitment ( rng , & params , & sig , None , None ) ;
let state2 = kp . prove_commitment ( rng , & params , & sig , None , None ) ;
let state3 = kp . prove_commitment ( rng , & params , & sig , None , None ) ;
let state4 = kp . prove_commitment ( rng , & params , & sig , None , None ) ;
2019-07-04 08:35:55 -07:00
let a = vec! { state . a , state1 . a , state2 . a } ;
let a2 = vec! { state3 . a , state4 . a } ;
2019-07-12 13:43:48 -07:00
assert_eq! ( hash ::< Bls12 > ( a . clone ( ) , vec! ( D . clone ( ) ) ) . is_zero ( ) , false ) ;
assert_ne! ( hash ::< Bls12 > ( a2 . clone ( ) , vec! ( D . clone ( ) ) ) , hash ::< Bls12 > ( a . clone ( ) , vec! ( D . clone ( ) ) ) ) ;
assert_ne! ( hash ::< Bls12 > ( a . clone ( ) , vec! ( D2 . clone ( ) ) ) , hash ::< Bls12 > ( a . clone ( ) , vec! ( D . clone ( ) ) ) ) ;
assert_ne! ( hash ::< Bls12 > ( a2 . clone ( ) , vec! ( D2 . clone ( ) ) ) , hash ::< Bls12 > ( a . clone ( ) , vec! ( D . clone ( ) ) ) )
2019-06-14 15:14:06 -07:00
}
}