arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
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}