ark_algebra_test_templates/
groups.rs1#[macro_export]
2#[doc(hidden)]
3macro_rules! __test_group {
4 ($group: ty) => {
5 type ScalarField = <$group as PrimeGroup>::ScalarField;
6 #[test]
7 fn test_add_properties() {
8 let mut rng = &mut ark_std::test_rng();
9 let zero = <$group>::zero();
10 for _ in 0..ITERATIONS {
11 let a = <$group>::rand(rng);
12 let b = <$group>::rand(rng);
13 let c = <$group>::rand(rng);
14
15 assert_eq!((a + b) + c, a + (b + c));
17
18 assert_eq!(a + b, b + a);
20
21 assert_eq!(zero + a, a);
23 assert_eq!(zero + b, b);
24 assert_eq!(zero + c, c);
25 assert_eq!(a + zero, a);
26 assert_eq!(b + zero, b);
27 assert_eq!(c + zero, c);
28
29 assert_eq!(-a + a, zero);
31 assert_eq!(-b + b, zero);
32 assert_eq!(-c + c, zero);
33 assert_eq!(-zero, zero);
34
35 let t0 = (a + &b) + &c; let t1 = (a + &c) + &b; let t2 = (b + &c) + &a; assert_eq!(t0, t1);
41 assert_eq!(t1, t2);
42
43 assert_eq!(a.double(), a + a);
45 assert_eq!(b.double(), b + b);
46 assert_eq!(c.double(), c + c);
47 assert_eq!(zero.double(), zero);
48 assert_eq!((-zero).double(), zero);
49 }
50 }
51
52 #[test]
53 fn test_sub_properties() {
54 use ark_std::UniformRand;
55 let mut rng = test_rng();
56 let zero = <$group>::zero();
57
58 for _ in 0..ITERATIONS{
59 let a = <$group>::rand(&mut rng);
61 let b = <$group>::rand(&mut rng);
62 assert!(((a - b) + (b - a)).is_zero());
63
64 assert_eq!(zero - a, -a);
66 assert_eq!(zero - b, -b);
67
68 assert_eq!(a - zero, a);
69 assert_eq!(b - zero, b);
70
71 assert_eq!(a.into_affine() - b, a - b);
73 }
74 }
75
76 #[test]
77 fn test_mul_properties() {
78 use ark_std::UniformRand;
79 let mut rng = test_rng();
80 let zero = ScalarField::zero();
81 let one = ScalarField::one();
82 assert_eq!(one.inverse().unwrap(), one);
83 assert!(one.is_one());
84
85 for _ in 0..ITERATIONS {
86 let a = <$group>::rand(&mut rng);
88 let b = ScalarField::rand(&mut rng);
89 let c = ScalarField::rand(&mut rng);
90 assert_eq!((a * b) * c, a * (b * c));
91
92 assert_eq!(a * one, a);
94
95 assert_eq!(a * zero, <$group>::zero());
96
97 assert_eq!((a * b.inverse().unwrap()) * b, a);
99
100 assert_eq!(a * (b + c), a * b + a * c);
102
103 for w in 2..=5 {
105 let context = WnafContext::new(w);
106 assert_eq!(a * b, context.mul(a, &b));
107
108 let table = context.table(a);
109 assert_eq!(a * b, context.mul_with_table(&table, &b).unwrap());
110
111 if w > 2 {
112 let bad_context = WnafContext::new(w - 1);
113 let bad_table = bad_context.table(a);
114 assert_eq!(context.mul_with_table(&bad_table, &b), None);
115 }
116 }
117
118 let mut scalars = vec![ScalarField::rand(&mut rng); 100];
120 scalars[0] = ScalarField::zero();
121 let table = BatchMulPreprocessing::new(a, scalars.len() - 1);
122 let result = table.batch_mul(&scalars);
123 let naive_result = scalars
124 .iter()
125 .enumerate()
126 .map(|(i, s)| a * s)
127 .collect::<Vec<_>>();
128 assert_eq!(result, naive_result);
129 }
130 }
131
132 #[test]
133 fn test_serialization() {
134 for compress in [Compress::Yes, Compress::No] {
135 for validate in [Validate::Yes, Validate::No] {
136 let buf_size = <$group>::zero().serialized_size(compress);
137
138 let mut rng = ark_std::test_rng();
139
140 for _ in 0..ITERATIONS {
143 let a = <$group>::rand(&mut rng);
144 {
145 let mut serialized = vec![0; buf_size];
146 let mut cursor = Cursor::new(&mut serialized[..]);
147 a.serialize_with_mode(&mut cursor, compress).unwrap();
148
149 let mut cursor = Cursor::new(&serialized[..]);
150 let b = <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap();
151 assert_eq!(a, b);
152 }
153 }
154
155 {
158 let a = <$group>::zero();
159 let mut serialized = vec![0; buf_size];
160 let mut cursor = Cursor::new(&mut serialized[..]);
161 a.serialize_with_mode(&mut cursor, compress).unwrap();
162 let mut cursor = Cursor::new(&serialized[..]);
163 let b = <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap();
164 assert_eq!(a, b);
165 }
166
167 {
170 let a = <$group>::zero();
171 let mut serialized = vec![0; buf_size - 1];
172 let mut cursor = Cursor::new(&mut serialized[..]);
173 a.serialize_with_mode(&mut cursor, compress).unwrap_err();
174 }
175
176 {
181 let serialized = vec![0; buf_size - 1];
182 let mut cursor = Cursor::new(&serialized[..]);
183 <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap_err();
184 }
185 }
186 }
187 }
188 };
189 ($group:ty; msm) => {
190 #[test]
191 fn test_var_base_msm() {
192 $crate::msm::test_var_base_msm::<$group>();
193 }
194
195 #[test]
196 fn test_chunked_pippenger() {
197 $crate::msm::test_chunked_pippenger::<$group>();
198 }
199
200 #[test]
201 fn test_hashmap_pippenger() {
202 $crate::msm::test_hashmap_pippenger::<$group>();
203 }
204 };
205 ($group:ty; curve) => {
206 $crate::__test_group!($group);
207 $crate::__test_group!($group; msm);
208 type Affine = <$group as CurveGroup>::Affine;
209 type Config = <$group as CurveGroup>::Config;
210 type BaseField = <$group as CurveGroup>::BaseField;
211
212 #[test]
213 fn test_affine_conversion() {
214 let mut rng = &mut ark_std::test_rng();
215
216 for _ in 0..ITERATIONS {
217 let g = <$group>::rand(&mut rng);
218 let g_affine = g.into_affine();
219 let g_projective = g_affine.into_group();
220 assert_eq!(g, g_projective);
221 }
222
223 for _ in 0..10 {
225 let mut v = (0..ITERATIONS)
226 .map(|_| <$group>::rand(&mut rng).double())
227 .collect::<Vec<_>>();
228
229 use ark_std::rand::distributions::{Distribution, Uniform};
230 let between = Uniform::from(0..ITERATIONS);
231 for _ in 0..5 {
233 v[between.sample(&mut rng)] = <$group>::zero();
234 }
235 for _ in 0..5 {
236 let s = between.sample(&mut rng);
237 v[s] = v[s].into_affine().into_group();
238 }
239
240 let expected_v = v.iter().map(|v| v.into_affine()).collect::<Vec<_>>();
241 let actual_v = <$group>::normalize_batch(&v);
242
243 assert_eq!(actual_v, expected_v);
244 }
245 }
246
247 #[test]
248 fn test_cofactor_ops() {
249 let rng = &mut ark_std::test_rng();
250 for _ in 0..ITERATIONS {
251 let a = Affine::rand(rng);
252 assert_eq!(a.mul_by_cofactor_to_group(), a.mul_bigint(&Config::COFACTOR));
253 assert_eq!(a.mul_by_cofactor(), a.mul_bigint(&Config::COFACTOR));
254 assert_eq!(a.mul_by_cofactor().mul_by_cofactor_inv(), a);
255 assert_eq!(a.mul_by_cofactor_inv().mul_by_cofactor(), a);
256 assert_eq!(a.mul_by_cofactor_inv(), a * Config::COFACTOR_INV);
257
258 assert!(a.clear_cofactor().is_in_correct_subgroup_assuming_on_curve());
259 }
260 }
261
262 #[test]
263 fn test_mixed_addition() {
264 let rng = &mut ark_std::test_rng();
265 for _ in 0..ITERATIONS {
266 let a = Affine::rand(rng);
267 let a_group = a.into_group();
268 let b = <$group>::rand(rng);
269 assert!(a.is_on_curve());
270 assert!(b.into_affine().is_on_curve());
271 assert_eq!(b + a, b + a_group, "b + a failed on input {a}, {b}");
272 assert_eq!(a + b, a_group + b, "a + b failed on input {a}, {b}");
273 }
274 }
275 };
276 ($group:ty; sw) => {
277 $crate::__test_group!($group; curve);
278
279 #[test]
280 fn test_sw_properties() {
281 let mut rng = &mut ark_std::test_rng();
282
283 let generator = <$group>::generator().into_affine();
284 assert!(generator.is_on_curve());
285 assert!(generator.is_in_correct_subgroup_assuming_on_curve());
286
287 for i in 0.. {
288 let x = BaseField::from(i);
289 let rhs = x * x.square() + x * <Config as SWCurveConfig>::COEFF_A + <Config as SWCurveConfig>::COEFF_B;
291
292 if let Some(y) = rhs.sqrt() {
293 let p = Affine::new_unchecked(x, if y < -y { y } else { -y });
294 if !<<$group as CurveGroup>::Config as CurveConfig>::cofactor_is_one() {
295 if p.is_in_correct_subgroup_assuming_on_curve() {
296 continue;
297 }
298 }
299
300 let g1 = p.mul_by_cofactor_to_group();
301 if !g1.is_zero() {
302 let g1 = Affine::from(g1);
303 assert!(g1.is_in_correct_subgroup_assuming_on_curve());
304 break;
305 }
306 }
307 }
308
309 for _ in 0..ITERATIONS {
310 let f = BaseField::rand(rng);
311 assert_eq!(<Config as SWCurveConfig>::mul_by_a(f), f * <Config as SWCurveConfig>::COEFF_A);
312 assert_eq!(<Config as SWCurveConfig>::add_b(f), f + <Config as SWCurveConfig>::COEFF_B);
313 }
314 {
315 use ark_ec::models::short_weierstrass::SWFlags;
316 for compress in [Compress::Yes, Compress::No] {
317 for flag in [SWFlags::PointAtInfinity, SWFlags::YIsNegative, SWFlags::YIsPositive] {
318 let a = BaseField::rand(&mut rng);
319 let buf_size = a.serialized_size(compress);
320 let mut serialized = vec![0u8; buf_size + 1];
321 let mut cursor = Cursor::new(&mut serialized[..]);
322 a.serialize_with_flags(&mut cursor, flag)
323 .unwrap();
324 let mut cursor = Cursor::new(&serialized[..]);
325 let (b, flags) = BaseField::deserialize_with_flags::<_, SWFlags>(&mut cursor).unwrap();
326 assert_eq!(flags, flag);
327 assert_eq!(a, b);
328 }
329
330 }
331 }
332 }
333 };
334 ($group:ty; te) => {
335 $crate::__test_group!($group; curve);
336
337 #[test]
338 fn test_te_properties() {
339 let mut rng = &mut ark_std::test_rng();
340
341 let generator = <$group>::generator().into_affine();
342 assert!(generator.is_on_curve());
343 assert!(generator.is_in_correct_subgroup_assuming_on_curve());
344 let mut y = BaseField::zero();
345 let one = BaseField::one();
346 for _ in 0..ITERATIONS {
347 let f = BaseField::rand(rng);
348 assert_eq!(<Config as TECurveConfig>::mul_by_a(f), f * <Config as TECurveConfig>::COEFF_A);
349 }
350 {
351 use ark_ec::models::twisted_edwards::TEFlags;
352 for compress in [Compress::Yes, Compress::No] {
353 for flag in [TEFlags::XIsPositive, TEFlags::XIsNegative] {
354 let a = BaseField::rand(&mut rng);
355 let buf_size = a.serialized_size(compress);
356 let mut serialized = vec![0u8; buf_size + 1];
357 let mut cursor = Cursor::new(&mut serialized[..]);
358 a.serialize_with_flags(&mut cursor, flag)
359 .unwrap();
360 let mut cursor = Cursor::new(&serialized[..]);
361 let (b, flags) = BaseField::deserialize_with_flags::<_, TEFlags>(&mut cursor).unwrap();
362 assert_eq!(flags, flag);
363 assert_eq!(a, b);
364 }
365
366 }
367 }
368 }
369
370 #[test]
371 fn test_montgomery_conversion_test()
372 {
373 use ark_ec::twisted_edwards::MontCurveConfig;
374 let a = <Config as CurveConfig>::BaseField::one().double()
376 * &(<Config as TECurveConfig>::COEFF_A + &<Config as TECurveConfig>::COEFF_D)
377 * &(<Config as TECurveConfig>::COEFF_A - &<Config as TECurveConfig>::COEFF_D).inverse().unwrap();
378 let b = <Config as CurveConfig>::BaseField::one().double().double() *
380 &(<Config as TECurveConfig>::COEFF_A - &<Config as TECurveConfig>::COEFF_D).inverse().unwrap();
381
382 assert_eq!(a, <Config as MontCurveConfig>::COEFF_A);
383 assert_eq!(b, <Config as MontCurveConfig>::COEFF_B);
384 }
385 };
386 ($group:ty; glv) => {
387 type Config = <$group as CurveGroup>::Config;
388
389 #[test]
390 fn test_scalar_decomposition()
391 {
392 $crate::glv::glv_scalar_decomposition::<Config>();
393 }
394
395
396 #[test]
397 fn test_endomorphism_eigenvalue() {
398 $crate::glv::glv_endomorphism_eigenvalue::<Config>();
399 }
400
401 #[test]
402 fn test_glv_mul() {
403 $crate::glv::glv_projective::<Config>();
404 $crate::glv::glv_affine::<Config>();
405 }
406 }
407}
408
409#[macro_export]
410macro_rules! test_group {
411 ($mod_name:ident; $group:ty $(; $tail:tt)* ) => {
412 mod $mod_name {
413 use super::*;
414 use ark_ff::*;
415 use ark_ec::{PrimeGroup, CurveGroup, ScalarMul, AffineRepr, CurveConfig, short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, scalar_mul::{*, wnaf::*}};
416 use ark_serialize::*;
417 use ark_std::{io::Cursor, rand::Rng, vec::*, test_rng, vec, Zero, One, UniformRand};
418 const ITERATIONS: usize = 500;
419
420 $crate::__test_group!($group $(; $tail)*);
421 }
422 };
423
424 ($iters:expr; $mod_name:ident; $group:ty $(; $tail:tt)* ) => {
425 mod $mod_name {
426 use super::*;
427 use ark_ff::*;
428 use ark_ec::{PrimeGroup, CurveGroup, ScalarMul, AffineRepr, CurveConfig, short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, scalar_mul::{*, wnaf::*}};
429 use ark_serialize::*;
430 use ark_std::{io::Cursor, rand::Rng, vec::*, test_rng, vec, Zero, One, UniformRand};
431 const ITERATIONS: usize = $iters;
432
433 $crate::__test_group!($group $(; $tail)*);
434 }
435 };
436}