ark-r1cs-std/r1cs-std/src/instantiated/mnt4_298/curves.rs
r1cs-std/src/instantiated/mnt4_298/curves.rsRaw
1use crate::groups::mnt4;
2use algebra::mnt4_298::Parameters;
3
4pub type G1Gadget = mnt4::G1Gadget<Parameters>;
5pub type G2Gadget = mnt4::G2Gadget<Parameters>;
6
7pub type G1PreparedGadget = mnt4::G1PreparedGadget<Parameters>;
8pub type G2PreparedGadget = mnt4::G2PreparedGadget<Parameters>;
9
10#[cfg(test)]
11mod test {
12 use rand::Rng;
13
14 use super::{G1Gadget, G2Gadget};
15 use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec};
16 use algebra::{mnt4_298::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve};
17 use r1cs_core::ConstraintSystem;
18
19 #[test]
20 fn mnt4_298_g1_constraint_costs() {
21 use crate::boolean::AllocatedBit;
22
23 let mut cs = TestConstraintSystem::<Fq>::new();
24
25 let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
26 .unwrap()
27 .into();
28
29 let mut rng = test_rng();
30 let a: G1Projective = rng.gen();
31 let b: G1Projective = rng.gen();
32 let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
33 let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
34 let alloc_cost = cs.num_constraints();
35 let _ = G1Gadget::conditionally_select(
36 &mut cs.ns(|| "cond_select"),
37 &bit,
38 &gadget_a,
39 &gadget_b,
40 )
41 .unwrap();
42 let cond_select_cost = cs.num_constraints() - alloc_cost;
43
44 let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
45 let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
46
47 assert!(cs.is_satisfied());
48 assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost());
49 assert_eq!(add_cost, G1Gadget::cost_of_add());
50 }
51
52 #[test]
53 fn mnt4_298_g2_constraint_costs() {
54 use crate::boolean::AllocatedBit;
55
56 let mut cs = TestConstraintSystem::<Fq>::new();
57
58 let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
59 .unwrap()
60 .into();
61
62 let mut rng = test_rng();
63 let a: G2Projective = rng.gen();
64 let b: G2Projective = rng.gen();
65 let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
66 let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
67 let alloc_cost = cs.num_constraints();
68 let _ = G2Gadget::conditionally_select(
69 &mut cs.ns(|| "cond_select"),
70 &bit,
71 &gadget_a,
72 &gadget_b,
73 )
74 .unwrap();
75 let cond_select_cost = cs.num_constraints() - alloc_cost;
76
77 let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
78 let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
79
80 assert!(cs.is_satisfied());
81 assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost());
82 assert_eq!(add_cost, G2Gadget::cost_of_add());
83 }
84
85 #[test]
86 fn mnt4_298_g1_gadget_test() {
87 use algebra::UniformRand;
88 use rand::SeedableRng;
89 use rand_xorshift::XorShiftRng;
90 let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
91
92 let mut cs = TestConstraintSystem::<Fq>::new();
93
94 let a = G1Projective::rand(&mut rng);
95 let b = G1Projective::rand(&mut rng);
96 let a_affine = a.into_affine();
97 let b_affine = b.into_affine();
98 let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
99 let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
100 assert_eq!(gadget_a.x.value.unwrap(), a_affine.x);
101 assert_eq!(gadget_a.y.value.unwrap(), a_affine.y);
102 assert_eq!(gadget_b.x.value.unwrap(), b_affine.x);
103 assert_eq!(gadget_b.y.value.unwrap(), b_affine.y);
104
105 // Check addition
106 let ab = a + &b;
107 let ab_affine = ab.into_affine();
108 let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
109 let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
110 gadget_ba
111 .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
112 .unwrap();
113
114 let ab_val = gadget_ab
115 .get_value()
116 .expect("Doubling should be successful")
117 .into_affine();
118 assert_eq!(ab_val, ab_affine, "Result of addition is unequal");
119
120 // Check doubling
121 let aa = a.double();
122 let aa_affine = aa.into_affine();
123 gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
124 let aa_val = gadget_a
125 .get_value()
126 .expect("Doubling should be successful")
127 .into_affine();
128 assert_eq!(
129 aa_val, aa_affine,
130 "Gadget and native values are unequal after double."
131 );
132
133 // Check mul_bits
134 let scalar = Fr::rand(&mut rng);
135 let native_result = aa.into_affine().mul(scalar) + &b;
136 let native_result = native_result.into_affine();
137
138 let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
139 // Get the scalar bits into little-endian form.
140 scalar.reverse();
141 let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
142 let result = gadget_a
143 .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter())
144 .unwrap();
145 let result_val = result.get_value().unwrap().into_affine();
146 assert_eq!(
147 result_val, native_result,
148 "gadget & native values are diff. after scalar mul"
149 );
150
151 if !cs.is_satisfied() {
152 println!("{:?}", cs.which_is_unsatisfied().unwrap());
153 }
154
155 assert!(cs.is_satisfied());
156 }
157
158 #[test]
159 fn mnt4_298_g2_gadget_test() {
160 let mut cs = TestConstraintSystem::<Fq>::new();
161
162 let mut rng = test_rng();
163 let a: G2Projective = rng.gen();
164 let b: G2Projective = rng.gen();
165 let a_affine = a.into_affine();
166 let b_affine = b.into_affine();
167
168 let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
169 let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
170 assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x);
171 assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y);
172 assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x);
173 assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y);
174
175 let ab = a + &b;
176 let ab_affine = ab.into_affine();
177 let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
178 let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap();
179 gadget_ba
180 .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab)
181 .unwrap();
182 assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x);
183 assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y);
184
185 let aa = a.double();
186 let aa_affine = aa.into_affine();
187 gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap();
188
189 assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x);
190 assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y);
191
192 if !cs.is_satisfied() {
193 println!("{:?}", cs.which_is_unsatisfied().unwrap());
194 }
195
196 assert!(cs.is_satisfied());
197 }
198}