1+ use rand:: { { Rng , CryptoRng } , rngs:: OsRng } ;
2+ use group:: { Group , GroupEncoding , ff:: Field } ;
3+ use curve25519_dalek:: ristretto:: RistrettoPoint ;
4+
5+ use sigma_rs:: toolbox:: sigma:: {
6+ GroupMorphismPreimage ,
7+ SchnorrProof ,
8+ transcript:: KeccakTranscript ,
9+ NISigmaProtocol
10+ } ;
11+
12+ type G = RistrettoPoint ;
13+
14+ fn msm_pr < G : Group > ( scalars : & [ G :: Scalar ] , bases : & [ G ] ) -> G {
15+ let mut acc = G :: identity ( ) ;
16+ for ( s, p) in scalars. iter ( ) . zip ( bases. iter ( ) ) {
17+ acc += * p * s;
18+ }
19+ acc
20+ }
21+
22+
23+ #[ allow( non_snake_case) ]
24+ fn discrete_logarithm < G : Group + GroupEncoding > (
25+ rng : & mut ( impl Rng + CryptoRng )
26+ ) -> ( GroupMorphismPreimage < G > , Vec < G :: Scalar > ) {
27+ let mut morphismp: GroupMorphismPreimage < G > = GroupMorphismPreimage :: new ( ) ;
28+
29+ let var_x: usize = 0 ;
30+ let ( var_G, var_X) : ( usize , usize ) = ( 0 , 1 ) ;
31+ morphismp. allocate_scalars ( 1 ) ;
32+ morphismp. allocate_elements ( 2 ) ;
33+ morphismp. append_equation ( var_X, & [ ( var_x, var_G) ] ) ;
34+
35+ let G = G :: generator ( ) ;
36+ morphismp. set_elements ( & [ ( var_G, G ) ] ) ;
37+
38+ let x = G :: Scalar :: random ( & mut * rng) ;
39+ let X = G * x;
40+ assert ! ( vec![ X ] == morphismp. morphism. evaluate( & [ x] ) ) ;
41+
42+ morphismp. set_elements ( & [ ( var_X, X ) ] ) ;
43+ ( morphismp, vec ! [ x] )
44+ }
45+
46+
47+ #[ allow( non_snake_case) ]
48+ fn dleq < G : Group + GroupEncoding > (
49+ rng : & mut ( impl Rng + CryptoRng )
50+ ) -> ( GroupMorphismPreimage < G > , Vec < G :: Scalar > ) {
51+ let mut morphismp: GroupMorphismPreimage < G > = GroupMorphismPreimage :: new ( ) ;
52+
53+ let G = G :: generator ( ) ;
54+ let H = G :: random ( & mut * rng) ;
55+ let x = G :: Scalar :: random ( & mut * rng) ;
56+ let X = G * x;
57+ let Y = H * x;
58+
59+ let var_x: usize = 0 ;
60+ let ( var_G, var_H, var_X, var_Y) = ( 0 , 1 , 2 , 3 ) ;
61+ morphismp. allocate_scalars ( 1 ) ;
62+ morphismp. allocate_elements ( 4 ) ;
63+ morphismp. set_elements ( & [ ( var_G, G ) , ( var_H, H ) , ( var_X, X ) , ( var_Y, Y ) ] ) ;
64+ morphismp. append_equation ( var_X, & [ ( var_x, var_G) ] ) ;
65+ morphismp. append_equation ( var_Y, & [ ( var_x, var_H) ] ) ;
66+
67+ assert ! ( vec![ X , Y ] == morphismp. morphism. evaluate( & [ x] ) ) ;
68+ ( morphismp, vec ! [ x] )
69+ }
70+
71+
72+ #[ allow( non_snake_case) ]
73+ fn pedersen_commitment < G : Group + GroupEncoding > (
74+ rng : & mut ( impl Rng + CryptoRng )
75+ ) -> ( GroupMorphismPreimage < G > , Vec < G :: Scalar > ) {
76+ let mut morphismp: GroupMorphismPreimage < G > = GroupMorphismPreimage :: new ( ) ;
77+
78+ let G = G :: generator ( ) ;
79+ let H = G :: random ( & mut * rng) ;
80+ let x = G :: Scalar :: random ( & mut * rng) ;
81+ let r = G :: Scalar :: random ( & mut * rng) ;
82+ let witness = vec ! [ x, r] ;
83+
84+ let C = G * x + H * r;
85+
86+ let ( var_x, var_r) = ( 0 , 1 ) ;
87+ let ( var_G, var_H, var_C) = ( 0 , 1 , 2 ) ;
88+ morphismp. allocate_scalars ( 2 ) ;
89+ morphismp. allocate_elements ( 3 ) ;
90+ morphismp. set_elements ( & [ ( var_H, H ) , ( var_G, G ) , ( var_C, C ) ] ) ;
91+ morphismp. append_equation ( var_C, & [ ( var_x, var_G) , ( var_r, var_H) ] ) ;
92+
93+ assert ! ( vec![ C ] == morphismp. morphism. evaluate( & witness) ) ;
94+ ( morphismp, witness)
95+ }
96+
97+
98+ #[ allow( non_snake_case) ]
99+ fn pedersen_commitment_dleq < G : Group + GroupEncoding > (
100+ rng : & mut ( impl Rng + CryptoRng )
101+ ) -> ( GroupMorphismPreimage < G > , Vec < G :: Scalar > ) {
102+ let mut morphismp: GroupMorphismPreimage < G > = GroupMorphismPreimage :: new ( ) ;
103+
104+ let mut generators = Vec :: < G > :: new ( ) ;
105+ generators. push ( G :: random ( & mut * rng) ) ;
106+ generators. push ( G :: random ( & mut * rng) ) ;
107+ generators. push ( G :: random ( & mut * rng) ) ;
108+ generators. push ( G :: random ( & mut * rng) ) ;
109+
110+ let mut witness = Vec :: < G :: Scalar > :: new ( ) ;
111+ witness. push ( G :: Scalar :: random ( & mut * rng) ) ;
112+ witness. push ( G :: Scalar :: random ( & mut * rng) ) ;
113+
114+ let X = msm_pr :: < G > ( & witness, & [ generators[ 0 ] , generators[ 1 ] ] ) ;
115+ let Y = msm_pr :: < G > ( & witness, & [ generators[ 2 ] , generators[ 3 ] ] ) ;
116+
117+ let ( var_x, var_r) = ( 0 , 1 ) ;
118+ let var_Gs = ( 0 , 1 , 2 , 3 ) ;
119+ let ( var_X, var_Y) = ( 4 , 5 ) ;
120+ morphismp. allocate_scalars ( 2 ) ;
121+ morphismp. allocate_elements ( 4 ) ;
122+ morphismp. allocate_elements ( 2 ) ;
123+
124+ morphismp. set_elements ( & [ ( var_Gs. 0 , generators[ 0 ] ) , ( var_Gs. 1 , generators[ 1 ] ) , ( var_Gs. 2 , generators[ 2 ] ) , ( var_Gs. 3 , generators[ 3 ] ) ] ) ;
125+ morphismp. set_elements ( & [ ( var_X, X ) , ( var_Y, Y ) ] ) ;
126+
127+ morphismp. append_equation ( var_X, & [ ( var_x, var_Gs. 0 ) , ( var_r, var_Gs. 1 ) ] ) ;
128+ morphismp. append_equation ( var_Y, & [ ( var_x, var_Gs. 2 ) , ( var_r, var_Gs. 3 ) ] ) ;
129+
130+ assert ! ( vec![ X , Y ] == morphismp. morphism. evaluate( & witness) ) ;
131+ ( morphismp, witness)
132+ }
133+
134+
135+ #[ allow( non_snake_case) ]
136+ fn bbs_blind_commitment_computation < G : Group + GroupEncoding > (
137+ rng : & mut ( impl Rng + CryptoRng )
138+ ) -> ( GroupMorphismPreimage < G > , Vec < G :: Scalar > ) {
139+ let mut morphismp: GroupMorphismPreimage < G > = GroupMorphismPreimage :: new ( ) ;
140+
141+ // lenght (committed_messages)
142+ let M = 3 ;
143+ // BBS.create_generators(M + 1, "BLIND_" || api_id)
144+ let ( Q_2 , J_1 , J_2 , J_3 ) = ( G :: random ( & mut * rng) , G :: random ( & mut * rng) , G :: random ( & mut * rng) , G :: random ( & mut * rng) ) ;
145+ // BBS.messages_to_scalars(committed_messages, api_id)
146+ let ( msg_1, msg_2, msg_3) = ( G :: Scalar :: random ( & mut * rng) , G :: Scalar :: random ( & mut * rng) , G :: Scalar :: random ( & mut * rng) ) ;
147+
148+ // these are computed before the proof in the specification
149+ let secret_prover_blind = G :: Scalar :: random ( & mut * rng) ;
150+ let C = Q_2 * secret_prover_blind + J_1 * msg_1 + J_2 * msg_2 + J_3 * msg_3;
151+
152+ // This is the part that needs to be changed in the specification of blind bbs.
153+ let ( var_secret_prover_blind, var_msg_1, var_msg_2, var_msg_3) = ( 0 , 1 , 2 , 3 ) ;
154+ let ( var_Q_2, var_J_1, var_J_2, var_J_3) = ( 0 , 1 , 2 , 3 ) ;
155+ let var_C = M +1 ;
156+
157+ morphismp. allocate_scalars ( M +1 ) ;
158+ morphismp. allocate_elements ( M +1 ) ;
159+ morphismp. allocate_elements ( 1 ) ;
160+ morphismp. set_elements ( & [ ( var_Q_2, Q_2 ) , ( var_J_1, J_1 ) , ( var_J_2, J_2 ) , ( var_J_3, J_3 ) , ( var_C, C ) ] ) ;
161+
162+ morphismp. append_equation ( var_C, & [ ( var_secret_prover_blind, var_Q_2) , ( var_msg_1, var_J_1) , ( var_msg_2, var_J_2) , ( var_msg_3, var_J_3) ] ) ;
163+
164+ let witness = vec ! [ secret_prover_blind, msg_1, msg_2, msg_3] ;
165+
166+ assert ! ( vec![ C ] == morphismp. morphism. evaluate( & witness) ) ;
167+ ( morphismp, witness)
168+ }
169+
170+
171+ /// This part tests the functioning of morphisms
172+ /// as well as the implementation of GroupMorphismPreimage
173+ #[ test]
174+ fn test_discrete_logarithm ( ) {
175+ let mut rng = OsRng ;
176+ discrete_logarithm :: < G > ( & mut rng) ;
177+ }
178+
179+ #[ test]
180+ fn test_dleq ( ) {
181+ let mut rng = OsRng ;
182+ dleq :: < G > ( & mut rng) ;
183+ }
184+
185+ #[ test]
186+ fn test_pedersen_commitment ( ) {
187+ let mut rng = OsRng ;
188+ pedersen_commitment :: < G > ( & mut rng) ;
189+ }
190+
191+ #[ test]
192+ fn test_pedersen_commitment_dleq ( ) {
193+ let mut rng = OsRng ;
194+ pedersen_commitment_dleq :: < G > ( & mut rng) ;
195+ }
196+
197+ #[ test]
198+ fn test_bbs_blind_commitment_computation ( ) {
199+ let mut rng = OsRng ;
200+ bbs_blind_commitment_computation :: < G > ( & mut rng) ;
201+ }
202+
203+
204+ /// This part tests the implementation of the SigmaProtocol trait for the
205+ /// SchnorrProof structure as well as the Fiat-Shamir NISigmaProtocol transform
206+ #[ allow( non_snake_case) ]
207+ #[ test]
208+ fn NI_discrete_logarithm ( ) {
209+ let mut rng = OsRng ;
210+ let ( morphismp, witness) = bbs_blind_commitment_computation :: < G > ( & mut rng) ;
211+
212+ // The SigmaProtocol induced by morphismp
213+ let protocol = SchnorrProof { morphismp } ;
214+ // Fiat-Shamir wrapper
215+ let domain_sep = b"test-fiat-shamir-schnorr" ;
216+ let mut nizk = NISigmaProtocol :: < SchnorrProof < G > , KeccakTranscript < G > , G > :: new ( domain_sep, protocol) ;
217+
218+ // Prove
219+ let proof_bytes = nizk. prove ( & witness, & mut rng) ;
220+ // Verify
221+ let verified = nizk. verify ( & proof_bytes) . is_ok ( ) ;
222+ assert ! ( verified, "Fiat-Shamir Schnorr proof verification failed" ) ;
223+ }
0 commit comments