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