ark-curves-cherry-picked/curve-tests/src/curves.rs
curve-tests/src/curves.rsRaw
1#![allow(unused)]
2use ark_ec::{
3 AffineCurve, MontgomeryModelParameters, ProjectiveCurve, SWModelParameters, TEModelParameters,
4};
5use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
6use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SWFlags, SerializationError};
7use ark_std::{io::Cursor, vec::Vec};
8use rand::SeedableRng;
9use rand_xorshift::XorShiftRng;
10
11pub const ITERATIONS: usize = 10;
12
13fn random_addition_test<G: ProjectiveCurve>() {
14 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
15
16 for _ in 0..ITERATIONS {
17 let a = G::rand(&mut rng);
18 let b = G::rand(&mut rng);
19 let c = G::rand(&mut rng);
20 let a_affine = a.into_affine();
21 let b_affine = b.into_affine();
22 let c_affine = c.into_affine();
23
24 // a + a should equal the doubling
25 {
26 let mut aplusa = a;
27 aplusa.add_assign(&a);
28
29 let mut aplusamixed = a;
30 aplusamixed.add_assign_mixed(&a.into_affine());
31
32 let mut adouble = a;
33 adouble.double_in_place();
34
35 assert_eq!(aplusa, adouble);
36 assert_eq!(aplusa, aplusamixed);
37 }
38
39 let mut tmp = vec![G::zero(); 6];
40
41 // (a + b) + c
42 tmp[0] = (a + &b) + &c;
43
44 // a + (b + c)
45 tmp[1] = a + &(b + &c);
46
47 // (a + c) + b
48 tmp[2] = (a + &c) + &b;
49
50 // Mixed addition
51
52 // (a + b) + c
53 tmp[3] = a_affine.into_projective();
54 tmp[3].add_assign_mixed(&b_affine);
55 tmp[3].add_assign_mixed(&c_affine);
56
57 // a + (b + c)
58 tmp[4] = b_affine.into_projective();
59 tmp[4].add_assign_mixed(&c_affine);
60 tmp[4].add_assign_mixed(&a_affine);
61
62 // (a + c) + b
63 tmp[5] = a_affine.into_projective();
64 tmp[5].add_assign_mixed(&c_affine);
65 tmp[5].add_assign_mixed(&b_affine);
66
67 // Comparisons
68 for i in 0..6 {
69 for j in 0..6 {
70 if tmp[i] != tmp[j] {
71 println!("{} \n{}", tmp[i], tmp[j]);
72 }
73 assert_eq!(tmp[i], tmp[j], "Associativity failed {} {}", i, j);
74 assert_eq!(
75 tmp[i].into_affine(),
76 tmp[j].into_affine(),
77 "Associativity failed"
78 );
79 }
80
81 assert!(tmp[i] != a);
82 assert!(tmp[i] != b);
83 assert!(tmp[i] != c);
84
85 assert!(a != tmp[i]);
86 assert!(b != tmp[i]);
87 assert!(c != tmp[i]);
88 }
89 }
90}
91
92fn random_multiplication_test<G: ProjectiveCurve>() {
93 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
94
95 for _ in 0..ITERATIONS {
96 let mut a = G::rand(&mut rng);
97 let mut b = G::rand(&mut rng);
98 let a_affine = a.into_affine();
99 let b_affine = b.into_affine();
100
101 let s = G::ScalarField::rand(&mut rng);
102
103 // s ( a + b )
104 let mut tmp1 = a;
105 tmp1.add_assign(&b);
106 tmp1.mul_assign(s);
107
108 // sa + sb
109 a.mul_assign(s);
110 b.mul_assign(s);
111
112 let mut tmp2 = a;
113 tmp2.add_assign(&b);
114
115 // Affine multiplication
116 let mut tmp3 = a_affine.mul(s.into_repr());
117 tmp3.add_assign(&b_affine.mul(s.into_repr()));
118
119 assert_eq!(tmp1, tmp2);
120 assert_eq!(tmp1, tmp3);
121 }
122}
123
124fn random_doubling_test<G: ProjectiveCurve>() {
125 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
126
127 for _ in 0..ITERATIONS {
128 let mut a = G::rand(&mut rng);
129 let mut b = G::rand(&mut rng);
130
131 // 2(a + b)
132 let mut tmp1 = a;
133 tmp1.add_assign(&b);
134 tmp1.double_in_place();
135
136 // 2a + 2b
137 a.double_in_place();
138 b.double_in_place();
139
140 let mut tmp2 = a;
141 tmp2.add_assign(&b);
142
143 let mut tmp3 = a;
144 tmp3.add_assign_mixed(&b.into_affine());
145
146 assert_eq!(tmp1, tmp2);
147 assert_eq!(tmp1, tmp3);
148 }
149}
150
151fn random_negation_test<G: ProjectiveCurve>() {
152 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
153
154 for _ in 0..ITERATIONS {
155 let r = G::rand(&mut rng);
156
157 let s = G::ScalarField::rand(&mut rng);
158 let sneg = -s;
159 assert!((s + &sneg).is_zero());
160
161 let mut t1 = r;
162 t1.mul_assign(s);
163
164 let mut t2 = r;
165 t2.mul_assign(sneg);
166
167 let mut t3 = t1;
168 t3.add_assign(&t2);
169 assert!(t3.is_zero());
170
171 let mut t4 = t1;
172 t4.add_assign_mixed(&t2.into_affine());
173 assert!(t4.is_zero());
174
175 t1 = -t1;
176 assert_eq!(t1, t2);
177 }
178}
179
180fn random_transformation_test<G: ProjectiveCurve>() {
181 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
182
183 for _ in 0..ITERATIONS {
184 let g = G::rand(&mut rng);
185 let g_affine = g.into_affine();
186 let g_projective = g_affine.into_projective();
187 assert_eq!(g, g_projective);
188 }
189
190 // Batch normalization
191 for _ in 0..10 {
192 let mut v = (0..ITERATIONS)
193 .map(|_| G::rand(&mut rng))
194 .collect::<Vec<_>>();
195
196 for i in &v {
197 assert!(!i.is_normalized());
198 }
199
200 use rand::distributions::{Distribution, Uniform};
201 let between = Uniform::from(0..ITERATIONS);
202 // Sprinkle in some normalized points
203 for _ in 0..5 {
204 v[between.sample(&mut rng)] = G::zero();
205 }
206 for _ in 0..5 {
207 let s = between.sample(&mut rng);
208 v[s] = v[s].into_affine().into_projective();
209 }
210
211 let expected_v = v
212 .iter()
213 .map(|v| v.into_affine().into_projective())
214 .collect::<Vec<_>>();
215 G::batch_normalization(&mut v);
216
217 for i in &v {
218 assert!(i.is_normalized());
219 }
220
221 assert_eq!(v, expected_v);
222 }
223}
224
225pub fn curve_tests<G: ProjectiveCurve>() {
226 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
227
228 // Negation edge case with zero.
229 {
230 let z = -G::zero();
231 assert!(z.is_zero());
232 }
233
234 // Doubling edge case with zero.
235 {
236 let mut z = -G::zero();
237 z.double_in_place();
238 assert!(z.is_zero());
239 }
240
241 // Addition edge cases with zero
242 {
243 let mut r = G::rand(&mut rng);
244 let rcopy = r;
245 r.add_assign(&G::zero());
246 assert_eq!(r, rcopy);
247 r.add_assign_mixed(&G::Affine::zero());
248 assert_eq!(r, rcopy);
249
250 let mut z = G::zero();
251 z.add_assign(&G::zero());
252 assert!(z.is_zero());
253 z.add_assign_mixed(&G::Affine::zero());
254 assert!(z.is_zero());
255
256 let mut z2 = z;
257 z2.add_assign(&r);
258
259 z.add_assign_mixed(&r.into_affine());
260
261 assert_eq!(z, z2);
262 assert_eq!(z, r);
263 }
264
265 // Transformations
266 {
267 let a = G::rand(&mut rng);
268 let b = a.into_affine().into_projective();
269 let c = a
270 .into_affine()
271 .into_projective()
272 .into_affine()
273 .into_projective();
274 assert_eq!(a, b);
275 assert_eq!(b, c);
276 }
277
278 // Test COFACTOR and COFACTOR_INV
279 {
280 let a = G::rand(&mut rng);
281 let b = a.into_affine();
282 let c = b.mul_by_cofactor_inv().mul_by_cofactor();
283 assert_eq!(b, c);
284 }
285
286 random_addition_test::<G>();
287 random_multiplication_test::<G>();
288 random_doubling_test::<G>();
289 random_negation_test::<G>();
290 random_transformation_test::<G>();
291}
292
293pub fn sw_tests<P: SWModelParameters>() {
294 sw_curve_serialization_test::<P>();
295 sw_from_random_bytes::<P>();
296}
297
298pub fn sw_from_random_bytes<P: SWModelParameters>() {
299 use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
300
301 let buf_size = GroupAffine::<P>::zero().serialized_size();
302
303 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
304
305 for _ in 0..ITERATIONS {
306 let a = GroupProjective::<P>::rand(&mut rng);
307 let mut a = a.into_affine();
308 {
309 let mut serialized = vec![0; buf_size];
310 let mut cursor = Cursor::new(&mut serialized[..]);
311 a.serialize(&mut cursor).unwrap();
312
313 let mut cursor = Cursor::new(&serialized[..]);
314 let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
315 let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
316 assert_eq!(p1, p2);
317 }
318 }
319}
320
321pub fn sw_curve_serialization_test<P: SWModelParameters>() {
322 use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
323
324 let buf_size = GroupAffine::<P>::zero().serialized_size();
325
326 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
327
328 for _ in 0..ITERATIONS {
329 let a = GroupProjective::<P>::rand(&mut rng);
330 let mut a = a.into_affine();
331 {
332 let mut serialized = vec![0; buf_size];
333 let mut cursor = Cursor::new(&mut serialized[..]);
334 a.serialize(&mut cursor).unwrap();
335
336 let mut cursor = Cursor::new(&serialized[..]);
337 let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
338 assert_eq!(a, b);
339 }
340
341 {
342 a.y = -a.y;
343 let mut serialized = vec![0; buf_size];
344 let mut cursor = Cursor::new(&mut serialized[..]);
345 a.serialize(&mut cursor).unwrap();
346 let mut cursor = Cursor::new(&serialized[..]);
347 let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
348 assert_eq!(a, b);
349 }
350
351 {
352 let a = GroupAffine::<P>::zero();
353 let mut serialized = vec![0; buf_size];
354 let mut cursor = Cursor::new(&mut serialized[..]);
355 a.serialize(&mut cursor).unwrap();
356 let mut cursor = Cursor::new(&serialized[..]);
357 let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
358 assert_eq!(a, b);
359 }
360
361 {
362 let a = GroupAffine::<P>::zero();
363 let mut serialized = vec![0; buf_size - 1];
364 let mut cursor = Cursor::new(&mut serialized[..]);
365 a.serialize(&mut cursor).unwrap_err();
366 }
367
368 {
369 let serialized = vec![0; buf_size - 1];
370 let mut cursor = Cursor::new(&serialized[..]);
371 GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
372 }
373
374 {
375 let mut serialized = vec![0; a.uncompressed_size()];
376 let mut cursor = Cursor::new(&mut serialized[..]);
377 a.serialize_uncompressed(&mut cursor).unwrap();
378
379 let mut cursor = Cursor::new(&serialized[..]);
380 let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
381 assert_eq!(a, b);
382 }
383
384 {
385 a.y = -a.y;
386 let mut serialized = vec![0; a.uncompressed_size()];
387 let mut cursor = Cursor::new(&mut serialized[..]);
388 a.serialize_uncompressed(&mut cursor).unwrap();
389 let mut cursor = Cursor::new(&serialized[..]);
390 let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
391 assert_eq!(a, b);
392 }
393
394 {
395 let a = GroupAffine::<P>::zero();
396 let mut serialized = vec![0; a.uncompressed_size()];
397 let mut cursor = Cursor::new(&mut serialized[..]);
398 a.serialize_uncompressed(&mut cursor).unwrap();
399 let mut cursor = Cursor::new(&serialized[..]);
400 let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
401 assert_eq!(a, b);
402 }
403 }
404}
405
406pub fn montgomery_conversion_test<P>()
407where
408 P: TEModelParameters,
409{
410 // A = 2 * (a + d) / (a - d)
411 let a = P::BaseField::one().double()
412 * &(P::COEFF_A + &P::COEFF_D)
413 * &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
414 // B = 4 / (a - d)
415 let b = P::BaseField::one().double().double() * &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
416
417 assert_eq!(a, P::MontgomeryModelParameters::COEFF_A);
418 assert_eq!(b, P::MontgomeryModelParameters::COEFF_B);
419}
420
421pub fn edwards_tests<P: TEModelParameters>()
422where
423 P::BaseField: PrimeField,
424{
425 edwards_curve_serialization_test::<P>();
426 edwards_from_random_bytes::<P>();
427}
428
429pub fn edwards_from_random_bytes<P: TEModelParameters>()
430where
431 P::BaseField: PrimeField,
432{
433 use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
434 use ark_ff::{to_bytes, ToBytes};
435
436 let buf_size = GroupAffine::<P>::zero().serialized_size();
437
438 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
439
440 for _ in 0..ITERATIONS {
441 let a = GroupProjective::<P>::rand(&mut rng);
442 let mut a = a.into_affine();
443 {
444 let mut serialized = vec![0; buf_size];
445 let mut cursor = Cursor::new(&mut serialized[..]);
446 a.serialize(&mut cursor).unwrap();
447
448 let mut cursor = Cursor::new(&serialized[..]);
449 let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
450 let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
451 assert_eq!(p1, p2);
452 }
453 }
454
455 for _ in 0..ITERATIONS {
456 let mut biginteger =
457 <<GroupAffine<P> as AffineCurve>::BaseField as PrimeField>::BigInt::rand(&mut rng);
458 let mut bytes = to_bytes![biginteger].unwrap();
459 let mut g = GroupAffine::<P>::from_random_bytes(&bytes);
460 while g.is_none() {
461 bytes.iter_mut().for_each(|i| *i = i.wrapping_sub(1));
462 g = GroupAffine::<P>::from_random_bytes(&bytes);
463 }
464 let _g = g.unwrap();
465 }
466}
467
468pub fn edwards_curve_serialization_test<P: TEModelParameters>() {
469 use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
470
471 let buf_size = GroupAffine::<P>::zero().serialized_size();
472
473 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
474
475 for _ in 0..ITERATIONS {
476 let a = GroupProjective::<P>::rand(&mut rng);
477 let a = a.into_affine();
478 {
479 let mut serialized = vec![0; buf_size];
480 let mut cursor = Cursor::new(&mut serialized[..]);
481 a.serialize(&mut cursor).unwrap();
482
483 let mut cursor = Cursor::new(&serialized[..]);
484 let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
485 assert_eq!(a, b);
486 }
487
488 {
489 let a = GroupAffine::<P>::zero();
490 let mut serialized = vec![0; buf_size];
491 let mut cursor = Cursor::new(&mut serialized[..]);
492 a.serialize(&mut cursor).unwrap();
493 let mut cursor = Cursor::new(&serialized[..]);
494 let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
495 assert_eq!(a, b);
496 }
497
498 {
499 let a = GroupAffine::<P>::zero();
500 let mut serialized = vec![0; buf_size - 1];
501 let mut cursor = Cursor::new(&mut serialized[..]);
502 a.serialize(&mut cursor).unwrap_err();
503 }
504
505 {
506 let serialized = vec![0; buf_size - 1];
507 let mut cursor = Cursor::new(&serialized[..]);
508 GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
509 }
510
511 {
512 let mut serialized = vec![0; a.uncompressed_size()];
513 let mut cursor = Cursor::new(&mut serialized[..]);
514 a.serialize_uncompressed(&mut cursor).unwrap();
515
516 let mut cursor = Cursor::new(&serialized[..]);
517 let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
518 assert_eq!(a, b);
519 }
520
521 {
522 let a = GroupAffine::<P>::zero();
523 let mut serialized = vec![0; a.uncompressed_size()];
524 let mut cursor = Cursor::new(&mut serialized[..]);
525 a.serialize_uncompressed(&mut cursor).unwrap();
526 let mut cursor = Cursor::new(&serialized[..]);
527 let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
528 assert_eq!(a, b);
529 }
530 }
531}