ark-r1cs-std/r1cs-std/src/groups/curves/twisted_edwards/test.rs
r1cs-std/src/groups/curves/twisted_edwards/test.rsRaw
1use rand::thread_rng;
2
3use crate::{prelude::*, groups::test::group_test};
4
5use algebra::{
6 curves::{models::TEModelParameters, twisted_edwards_extended::GroupAffine as TEAffine},
7 BitIterator, Group, PrimeField, Field, UniformRand,
8};
9
10use r1cs_core::ConstraintSystem;
11
12pub(crate) fn edwards_test<ConstraintF, P, GG, CS>(cs: &mut CS)
13where
14 ConstraintF: Field,
15 P: TEModelParameters,
16 GG: GroupGadget<TEAffine<P>, ConstraintF, Value = TEAffine<P>>,
17 CS: ConstraintSystem<ConstraintF>,
18{
19 let a: TEAffine<P> = UniformRand::rand(&mut thread_rng());
20 let b: TEAffine<P> = UniformRand::rand(&mut thread_rng());
21 let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
22 let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
23 assert_eq!(gadget_a.get_value().unwrap(), a);
24 assert_eq!(gadget_b.get_value().unwrap(), b);
25 group_test::<ConstraintF, TEAffine<P>, GG, _>(
26 &mut cs.ns(|| "GroupTest(a, b)"),
27 gadget_a.clone(),
28 gadget_b,
29 );
30
31 // Check mul_bits
32 let scalar: <TEAffine<P> as Group>::ScalarField = UniformRand::rand(&mut thread_rng());
33 let native_result = a.mul(&scalar);
34
35 let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
36 // Get the scalar bits into little-endian form.
37 scalar.reverse();
38 let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
39 let zero = GG::zero(cs.ns(|| "zero")).unwrap();
40 let result = gadget_a
41 .mul_bits(cs.ns(|| "mul_bits"), &zero, input.iter())
42 .unwrap();
43 let gadget_value = result.get_value().expect("Gadget_result failed");
44 assert_eq!(native_result, gadget_value);
45}
46
47pub(crate) fn edwards_constraint_costs<ConstraintF, P, GG, CS>(cs: &mut CS)
48where
49 ConstraintF: Field,
50 P: TEModelParameters,
51 GG: GroupGadget<TEAffine<P>, ConstraintF, Value = TEAffine<P>>,
52 CS: ConstraintSystem<ConstraintF>,
53{
54 use crate::boolean::AllocatedBit;
55
56 let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
57 .unwrap()
58 .into();
59
60 let a: TEAffine<P> = rand::random();
61 let b: TEAffine<P> = rand::random();
62 let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
63 let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
64 let alloc_cost = cs.num_constraints();
65 let _ =
66 GG::conditionally_select(&mut cs.ns(|| "cond_select"), &bit, &gadget_a, &gadget_b).unwrap();
67 let cond_select_cost = cs.num_constraints() - alloc_cost;
68
69 let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
70 let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
71 assert_eq!(cond_select_cost, <GG as CondSelectGadget<_>>::cost());
72 assert_eq!(add_cost, GG::cost_of_add());
73}