1use alloc::vec::Vec;
2use core::ops::{Mul, Neg};
3use ff::{Field, PrimeField};
4use rand::SeedableRng;
5use rand_xorshift::XorShiftRng;
6
7use crate::{
8 prime::{PrimeCurve, PrimeCurveAffine},
9 wnaf::WnafGroup,
10 GroupEncoding, UncompressedEncoding,
11};
12
13pub fn curve_tests<G: PrimeCurve>() {
14 let mut rng = XorShiftRng::from_seed([
15 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
16 0xe5,
17 ]);
18
19 {
21 let z = G::identity().neg();
22 assert!(bool::from(z.is_identity()));
23 }
24
25 {
27 let z = G::identity().double();
28 assert!(bool::from(z.is_identity()));
29 }
30
31 {
33 let mut r = G::random(&mut rng);
34 let rcopy = r;
35 r.add_assign(&G::identity());
36 assert_eq!(r, rcopy);
37 r.add_assign(&G::Affine::identity());
38 assert_eq!(r, rcopy);
39
40 let mut z = G::identity();
41 z.add_assign(&G::identity());
42 assert!(bool::from(z.is_identity()));
43 z.add_assign(&G::Affine::identity());
44 assert!(bool::from(z.is_identity()));
45
46 let mut z2 = z;
47 z2.add_assign(&r);
48
49 z.add_assign(&r.to_affine());
50
51 assert_eq!(z, z2);
52 assert_eq!(z, r);
53 }
54
55 {
57 let a = G::random(&mut rng);
58 let b = a.to_affine().to_curve();
59 let c = a.to_affine().to_curve().to_affine().to_curve();
60 assert_eq!(a, b);
61 assert_eq!(b, c);
62 }
63
64 random_addition_tests::<G>();
65 random_multiplication_tests::<G>();
66 random_doubling_tests::<G>();
67 random_negation_tests::<G>();
68 random_transformation_tests::<G>();
69 random_compressed_encoding_tests::<G>();
70}
71
72pub fn random_wnaf_tests<G: WnafGroup>() {
73 use crate::wnaf::*;
74
75 let mut rng = XorShiftRng::from_seed([
76 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
77 0xe5,
78 ]);
79
80 {
81 let mut table = vec![];
82 let mut wnaf = vec![];
83
84 for w in 2..14 {
85 for _ in 0..100 {
86 let g = G::random(&mut rng);
87 let s = G::Scalar::random(&mut rng);
88 let mut g1 = g;
89 g1.mul_assign(s);
90
91 wnaf_table(&mut table, g, w);
92 wnaf_form(&mut wnaf, s.to_repr(), w);
93 let g2 = wnaf_exp(&table, &wnaf);
94
95 assert_eq!(g1, g2);
96 }
97 }
98 }
99
100 {
101 fn only_compiles_if_send<S: Send>(_: &S) {}
102
103 for _ in 0..100 {
104 let g = G::random(&mut rng);
105 let s = G::Scalar::random(&mut rng);
106 let mut g1 = g;
107 g1.mul_assign(s);
108
109 let g2 = {
110 let mut wnaf = Wnaf::new();
111 wnaf.base(g, 1).scalar(&s)
112 };
113 let g3 = {
114 let mut wnaf = Wnaf::new();
115 wnaf.scalar(&s).base(g)
116 };
117 let g4 = {
118 let mut wnaf = Wnaf::new();
119 let mut shared = wnaf.base(g, 1).shared();
120
121 only_compiles_if_send(&shared);
122
123 shared.scalar(&s)
124 };
125 let g5 = {
126 let mut wnaf = Wnaf::new();
127 let mut shared = wnaf.scalar(&s).shared();
128
129 only_compiles_if_send(&shared);
130
131 shared.base(g)
132 };
133
134 let g6 = {
135 let mut wnaf = Wnaf::new();
136 {
137 wnaf.base(G::random(&mut rng), 1)
139 .scalar(&G::Scalar::random(&mut rng));
140 }
141 wnaf.base(g, 1).scalar(&s)
142 };
143 let g7 = {
144 let mut wnaf = Wnaf::new();
145 {
146 wnaf.base(G::random(&mut rng), 1)
148 .scalar(&G::Scalar::random(&mut rng));
149 }
150 wnaf.scalar(&s).base(g)
151 };
152 let g8 = {
153 let mut wnaf = Wnaf::new();
154 {
155 wnaf.base(G::random(&mut rng), 1)
157 .scalar(&G::Scalar::random(&mut rng));
158 }
159 let mut shared = wnaf.base(g, 1).shared();
160
161 only_compiles_if_send(&shared);
162
163 shared.scalar(&s)
164 };
165 let g9 = {
166 let mut wnaf = Wnaf::new();
167 {
168 wnaf.base(G::random(&mut rng), 1)
170 .scalar(&G::Scalar::random(&mut rng));
171 }
172 let mut shared = wnaf.scalar(&s).shared();
173
174 only_compiles_if_send(&shared);
175
176 shared.base(g)
177 };
178
179 assert_eq!(g1, g2);
180 assert_eq!(g1, g3);
181 assert_eq!(g1, g4);
182 assert_eq!(g1, g5);
183 assert_eq!(g1, g6);
184 assert_eq!(g1, g7);
185 assert_eq!(g1, g8);
186 assert_eq!(g1, g9);
187 }
188 }
189}
190
191fn random_negation_tests<G: PrimeCurve>() {
192 let mut rng = XorShiftRng::from_seed([
193 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
194 0xe5,
195 ]);
196
197 for _ in 0..1000 {
198 let r = G::random(&mut rng);
199
200 let s = G::Scalar::random(&mut rng);
201 let sneg = s.neg();
202
203 let mut t1 = r;
204 t1.mul_assign(s);
205
206 let mut t2 = r;
207 t2.mul_assign(sneg);
208
209 let mut t3 = t1;
210 t3.add_assign(&t2);
211 assert!(bool::from(t3.is_identity()));
212
213 let mut t4 = t1;
214 t4.add_assign(&t2.to_affine());
215 assert!(bool::from(t4.is_identity()));
216
217 assert_eq!(t1.neg(), t2);
218 }
219}
220
221fn random_doubling_tests<G: PrimeCurve>() {
222 let mut rng = XorShiftRng::from_seed([
223 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
224 0xe5,
225 ]);
226
227 for _ in 0..1000 {
228 let mut a = G::random(&mut rng);
229 let mut b = G::random(&mut rng);
230
231 let tmp1 = (a + b).double();
233
234 a = a.double();
236 b = b.double();
237
238 let mut tmp2 = a;
239 tmp2.add_assign(&b);
240
241 let mut tmp3 = a;
242 tmp3.add_assign(&b.to_affine());
243
244 assert_eq!(tmp1, tmp2);
245 assert_eq!(tmp1, tmp3);
246 }
247}
248
249fn random_multiplication_tests<G: PrimeCurve>() {
250 let mut rng = XorShiftRng::from_seed([
251 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
252 0xe5,
253 ]);
254
255 for _ in 0..1000 {
256 let mut a = G::random(&mut rng);
257 let mut b = G::random(&mut rng);
258 let a_affine = a.to_affine();
259 let b_affine = b.to_affine();
260
261 let s = G::Scalar::random(&mut rng);
262
263 let mut tmp1 = a;
265 tmp1.add_assign(&b);
266 tmp1.mul_assign(s);
267
268 a.mul_assign(s);
270 b.mul_assign(s);
271
272 let mut tmp2 = a;
273 tmp2.add_assign(&b);
274
275 let mut tmp3 = Mul::<G::Scalar>::mul(a_affine, s);
277 tmp3.add_assign(Mul::<G::Scalar>::mul(b_affine, s));
278
279 assert_eq!(tmp1, tmp2);
280 assert_eq!(tmp1, tmp3);
281 }
282}
283
284fn random_addition_tests<G: PrimeCurve>() {
285 let mut rng = XorShiftRng::from_seed([
286 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
287 0xe5,
288 ]);
289
290 for _ in 0..1000 {
291 let a = G::random(&mut rng);
292 let b = G::random(&mut rng);
293 let c = G::random(&mut rng);
294 let a_affine = a.to_affine();
295 let b_affine = b.to_affine();
296 let c_affine = c.to_affine();
297
298 {
300 let mut aplusa = a;
301 aplusa.add_assign(&a);
302
303 let mut aplusamixed = a;
304 aplusamixed.add_assign(&a.to_affine());
305
306 let adouble = a.double();
307
308 assert_eq!(aplusa, adouble);
309 assert_eq!(aplusa, aplusamixed);
310 }
311
312 let mut tmp = vec![G::identity(); 6];
313
314 tmp[0] = a;
316 tmp[0].add_assign(&b);
317 tmp[0].add_assign(&c);
318
319 tmp[1] = b;
321 tmp[1].add_assign(&c);
322 tmp[1].add_assign(&a);
323
324 tmp[2] = a;
326 tmp[2].add_assign(&c);
327 tmp[2].add_assign(&b);
328
329 tmp[3] = a_affine.to_curve();
333 tmp[3].add_assign(&b_affine);
334 tmp[3].add_assign(&c_affine);
335
336 tmp[4] = b_affine.to_curve();
338 tmp[4].add_assign(&c_affine);
339 tmp[4].add_assign(&a_affine);
340
341 tmp[5] = a_affine.to_curve();
343 tmp[5].add_assign(&c_affine);
344 tmp[5].add_assign(&b_affine);
345
346 for i in 0..6 {
348 for j in 0..6 {
349 assert_eq!(tmp[i], tmp[j]);
350 assert_eq!(tmp[i].to_affine(), tmp[j].to_affine());
351 }
352
353 assert!(tmp[i] != a);
354 assert!(tmp[i] != b);
355 assert!(tmp[i] != c);
356
357 assert!(a != tmp[i]);
358 assert!(b != tmp[i]);
359 assert!(c != tmp[i]);
360 }
361 }
362}
363
364fn random_transformation_tests<G: PrimeCurve>() {
365 let mut rng = XorShiftRng::from_seed([
366 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
367 0xe5,
368 ]);
369
370 for _ in 0..1000 {
371 let g = G::random(&mut rng);
372 let g_affine = g.to_affine();
373 let g_projective = g_affine.to_curve();
374 assert_eq!(g, g_projective);
375 }
376
377 for _ in 0..10 {
379 let mut v = (0..1000).map(|_| G::random(&mut rng)).collect::<Vec<_>>();
380
381 use rand::distributions::{Distribution, Uniform};
382 let between = Uniform::new(0, 1000);
383 for _ in 0..5 {
385 v[between.sample(&mut rng)] = G::identity();
386 }
387 for _ in 0..5 {
388 let s = between.sample(&mut rng);
389 v[s] = v[s].to_affine().to_curve();
390 }
391
392 let expected_v = v.iter().map(|v| v.to_affine()).collect::<Vec<_>>();
393
394 let mut normalized = vec![G::Affine::identity(); v.len()];
395 G::batch_normalize(&v, &mut normalized);
396
397 assert_eq!(normalized, expected_v);
398 }
399}
400
401fn random_compressed_encoding_tests<G: PrimeCurve>() {
402 let mut rng = XorShiftRng::from_seed([
403 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
404 0xe5,
405 ]);
406
407 assert_eq!(
408 G::Affine::from_bytes(&G::Affine::identity().to_bytes()).unwrap(),
409 G::Affine::identity()
410 );
411
412 for _ in 0..1000 {
413 let mut r = G::random(&mut rng).to_affine();
414
415 let compressed = r.to_bytes();
416 let de_compressed = G::Affine::from_bytes(&compressed).unwrap();
417 assert_eq!(de_compressed, r);
418
419 r = r.neg();
420
421 let compressed = r.to_bytes();
422 let de_compressed = G::Affine::from_bytes(&compressed).unwrap();
423 assert_eq!(de_compressed, r);
424 }
425}
426
427pub fn random_uncompressed_encoding_tests<G: PrimeCurve>()
428where
429 <G as PrimeCurve>::Affine: UncompressedEncoding,
430{
431 let mut rng = XorShiftRng::from_seed([
432 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
433 0xe5,
434 ]);
435
436 assert_eq!(
437 G::Affine::from_uncompressed(&G::Affine::identity().to_uncompressed()).unwrap(),
438 G::Affine::identity()
439 );
440
441 for _ in 0..1000 {
442 let r = G::random(&mut rng).to_affine();
443
444 let uncompressed = r.to_uncompressed();
445 let de_uncompressed = G::Affine::from_uncompressed(&uncompressed).unwrap();
446 assert_eq!(de_uncompressed, r);
447 }
448}