Skip to content

Commit 0dd8f65

Browse files
committed
Added new tests (sage_tests.rs):
- First part to test morphisms - Second part to test their derived NISigmaProtocol (Deserialization failed in this first test of the second part)
1 parent cbc09d2 commit 0dd8f65

File tree

2 files changed

+224
-1
lines changed

2 files changed

+224
-1
lines changed

tests/non_interactive_protocol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn fiat_shamir_schnorr_proof_ristretto() {
3030

3131
// Set the witness Vec
3232
let mut witness = Vec::new();
33-
witness.push(w.clone());
33+
witness.push(w);
3434

3535
// The H = z * G equation where z is the unique scalar variable
3636
morphismp.append_equation(1, &[(0, 0)]);

tests/sage_proofs.rs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
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

Comments
 (0)