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