ark-r1cs-std/r1cs-std/src/groups/curves/short_weierstrass/mnt4/mod.rs
r1cs-std/src/groups/curves/short_weierstrass/mnt4/mod.rsRaw
1use algebra::{
2 curves::mnt4::{
3 g2::{AteAdditionCoefficients, AteDoubleCoefficients},
4 G1Prepared, G2Prepared, MNT4Parameters,
5 },
6 Field,
7};
8use r1cs_core::{ConstraintSystem, SynthesisError};
9
10use crate::{
11 fields::{fp::FpGadget, fp2::Fp2Gadget, FieldGadget},
12 groups::curves::short_weierstrass::AffineGadget,
13 pairing::mnt4::PairingGadget,
14 prelude::*,
15 Vec,
16};
17use core::borrow::Borrow;
18
19pub type G1Gadget<P> = AffineGadget<
20 <P as MNT4Parameters>::G1Parameters,
21 <P as MNT4Parameters>::Fp,
22 FpGadget<<P as MNT4Parameters>::Fp>,
23>;
24
25pub type G2Gadget<P> =
26 AffineGadget<<P as MNT4Parameters>::G2Parameters, <P as MNT4Parameters>::Fp, Fp2G<P>>;
27
28#[derive(Derivative)]
29#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
30pub struct G1PreparedGadget<P: MNT4Parameters> {
31 pub x: FpGadget<P::Fp>,
32 pub y: FpGadget<P::Fp>,
33 pub x_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
34 pub y_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
35}
36
37impl<P: MNT4Parameters> G1PreparedGadget<P> {
38 pub fn get_value(&self) -> Option<G1Prepared<P>> {
39 match (
40 self.x.get_value(),
41 self.y.get_value(),
42 self.x_twist.get_value(),
43 self.y_twist.get_value(),
44 ) {
45 (Some(x), Some(y), Some(x_twist), Some(y_twist)) => Some(G1Prepared {
46 x,
47 y,
48 x_twist,
49 y_twist,
50 }),
51 _ => None,
52 }
53 }
54
55 pub fn from_affine<CS: ConstraintSystem<P::Fp>>(
56 mut cs: CS,
57 q: &G1Gadget<P>,
58 ) -> Result<Self, SynthesisError> {
59 let x_twist = Fp2Gadget::new(
60 q.x.mul_by_constant(cs.ns(|| "g1.x * twist.c0"), &P::TWIST.c0)?,
61 q.x.mul_by_constant(cs.ns(|| "g1.x * twist.c1"), &P::TWIST.c1)?,
62 );
63 let y_twist = Fp2Gadget::new(
64 q.y.mul_by_constant(cs.ns(|| "g1.y * twist.c0"), &P::TWIST.c0)?,
65 q.y.mul_by_constant(cs.ns(|| "g1.y * twist.c1"), &P::TWIST.c1)?,
66 );
67 Ok(G1PreparedGadget {
68 x: q.x.clone(),
69 y: q.y.clone(),
70 x_twist,
71 y_twist,
72 })
73 }
74}
75
76impl<P: MNT4Parameters> AllocGadget<G1Prepared<P>, P::Fp> for G1PreparedGadget<P> {
77 fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
78 mut cs: CS,
79 t: T,
80 ) -> Result<Self, SynthesisError>
81 where
82 T: Borrow<G1Prepared<P>>,
83 {
84 let obj = t.borrow();
85 let x = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_x"), &obj.x)?;
86 let y = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_y"), &obj.y)?;
87 let x_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
88 &mut cs.ns(|| "alloc_x_twist"),
89 &obj.x_twist,
90 )?;
91 let y_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
92 &mut cs.ns(|| "alloc_y_twist"),
93 &obj.y_twist,
94 )?;
95 Ok(G1PreparedGadget {
96 x,
97 y,
98 x_twist,
99 y_twist,
100 })
101 }
102
103 fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
104 where
105 F: FnOnce() -> Result<T, SynthesisError>,
106 T: Borrow<G1Prepared<P>>,
107 {
108 todo!()
109 }
110
111 fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
112 _cs: CS,
113 _f: F,
114 ) -> Result<Self, SynthesisError>
115 where
116 F: FnOnce() -> Result<T, SynthesisError>,
117 T: Borrow<G1Prepared<P>>,
118 {
119 todo!()
120 }
121}
122
123impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G1PreparedGadget<P> {
124 #[inline]
125 fn to_bytes<CS: ConstraintSystem<P::Fp>>(
126 &self,
127 mut cs: CS,
128 ) -> Result<Vec<UInt8>, SynthesisError> {
129 let mut x = self.x.to_bytes(&mut cs.ns(|| "x to bytes"))?;
130 let mut y = self.y.to_bytes(&mut cs.ns(|| "y to bytes"))?;
131 let mut x_twist = self.x_twist.to_bytes(&mut cs.ns(|| "x_twist to bytes"))?;
132 let mut y_twist = self.y_twist.to_bytes(&mut cs.ns(|| "y_twist to bytes"))?;
133
134 x.append(&mut y);
135 x.append(&mut x_twist);
136 x.append(&mut y_twist);
137 Ok(x)
138 }
139
140 fn to_non_unique_bytes<CS: ConstraintSystem<P::Fp>>(
141 &self,
142 mut cs: CS,
143 ) -> Result<Vec<UInt8>, SynthesisError> {
144 let mut x = self.x.to_non_unique_bytes(&mut cs.ns(|| "x to bytes"))?;
145 let mut y = self.y.to_non_unique_bytes(&mut cs.ns(|| "y to bytes"))?;
146 let mut x_twist = self
147 .x_twist
148 .to_non_unique_bytes(&mut cs.ns(|| "x_twist to bytes"))?;
149 let mut y_twist = self
150 .y_twist
151 .to_non_unique_bytes(&mut cs.ns(|| "y_twist to bytes"))?;
152
153 x.append(&mut y);
154 x.append(&mut x_twist);
155 x.append(&mut y_twist);
156 Ok(x)
157 }
158}
159
160type Fp2G<P> = Fp2Gadget<<P as MNT4Parameters>::Fp2Params, <P as MNT4Parameters>::Fp>;
161#[derive(Derivative)]
162#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
163pub struct G2PreparedGadget<P: MNT4Parameters> {
164 pub x: Fp2Gadget<P::Fp2Params, P::Fp>,
165 pub y: Fp2Gadget<P::Fp2Params, P::Fp>,
166 pub x_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
167 pub y_over_twist: Fp2Gadget<P::Fp2Params, P::Fp>,
168 pub double_coefficients: Vec<AteDoubleCoefficientsGadget<P>>,
169 pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
170}
171
172impl<P: MNT4Parameters> AllocGadget<G2Prepared<P>, P::Fp> for G2PreparedGadget<P> {
173 fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
174 mut cs: CS,
175 t: T,
176 ) -> Result<Self, SynthesisError>
177 where
178 T: Borrow<G2Prepared<P>>,
179 {
180 let obj = t.borrow();
181 let x = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_x"), &obj.x)?;
182 let y = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_y"), &obj.y)?;
183 let x_over_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
184 &mut cs.ns(|| "alloc_x_over_twist"),
185 &obj.x_over_twist,
186 )?;
187 let y_over_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
188 &mut cs.ns(|| "alloc_y_over_twist"),
189 &obj.y_over_twist,
190 )?;
191 let mut double_coefficients = Vec::<AteDoubleCoefficientsGadget<P>>::new();
192 for (i, item) in obj.double_coefficients.iter().enumerate() {
193 double_coefficients.push(AteDoubleCoefficientsGadget::<P>::alloc_constant(
194 &mut cs.ns(|| format!("alloc_double_coefficients_{}", i)),
195 item,
196 )?);
197 }
198 let mut addition_coefficients = Vec::<AteAdditionCoefficientsGadget<P>>::new();
199 for (i, item) in obj.addition_coefficients.iter().enumerate() {
200 addition_coefficients.push(AteAdditionCoefficientsGadget::<P>::alloc_constant(
201 &mut cs.ns(|| format!("alloc_addition_coefficients_{}", i)),
202 item,
203 )?);
204 }
205
206 Ok(G2PreparedGadget {
207 x,
208 y,
209 x_over_twist,
210 y_over_twist,
211 double_coefficients,
212 addition_coefficients,
213 })
214 }
215
216 fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
217 where
218 F: FnOnce() -> Result<T, SynthesisError>,
219 T: Borrow<G2Prepared<P>>,
220 {
221 todo!()
222 }
223
224 fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
225 _cs: CS,
226 _f: F,
227 ) -> Result<Self, SynthesisError>
228 where
229 F: FnOnce() -> Result<T, SynthesisError>,
230 T: Borrow<G2Prepared<P>>,
231 {
232 todo!()
233 }
234}
235
236impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
237 #[inline]
238 fn to_bytes<CS: ConstraintSystem<P::Fp>>(
239 &self,
240 mut cs: CS,
241 ) -> Result<Vec<UInt8>, SynthesisError> {
242 let mut x = self.x.to_bytes(&mut cs.ns(|| "x to bytes"))?;
243 let mut y = self.y.to_bytes(&mut cs.ns(|| "y to bytes"))?;
244 let mut x_over_twist = self
245 .x_over_twist
246 .to_bytes(&mut cs.ns(|| "x_over_twist to bytes"))?;
247 let mut y_over_twist = self
248 .y_over_twist
249 .to_bytes(&mut cs.ns(|| "y_over_twist to bytes"))?;
250
251 x.append(&mut y);
252 x.append(&mut x_over_twist);
253 x.append(&mut y_over_twist);
254
255 for (i, coeff) in self.double_coefficients.iter().enumerate() {
256 x.extend_from_slice(&coeff.to_bytes(cs.ns(|| format!("double_coefficients {}", i)))?);
257 }
258 for (i, coeff) in self.addition_coefficients.iter().enumerate() {
259 x.extend_from_slice(&coeff.to_bytes(cs.ns(|| format!("addition_coefficients {}", i)))?);
260 }
261 Ok(x)
262 }
263
264 fn to_non_unique_bytes<CS: ConstraintSystem<P::Fp>>(
265 &self,
266 mut cs: CS,
267 ) -> Result<Vec<UInt8>, SynthesisError> {
268 let mut x = self.x.to_non_unique_bytes(&mut cs.ns(|| "x to bytes"))?;
269 let mut y = self.y.to_non_unique_bytes(&mut cs.ns(|| "y to bytes"))?;
270 let mut x_over_twist = self
271 .x_over_twist
272 .to_non_unique_bytes(&mut cs.ns(|| "x_over_twist to bytes"))?;
273 let mut y_over_twist = self
274 .y_over_twist
275 .to_non_unique_bytes(&mut cs.ns(|| "y_over_twist to bytes"))?;
276
277 x.append(&mut y);
278 x.append(&mut x_over_twist);
279 x.append(&mut y_over_twist);
280
281 for (i, coeff) in self.double_coefficients.iter().enumerate() {
282 x.extend_from_slice(
283 &coeff.to_non_unique_bytes(cs.ns(|| format!("double_coefficients {}", i)))?,
284 );
285 }
286 for (i, coeff) in self.addition_coefficients.iter().enumerate() {
287 x.extend_from_slice(
288 &coeff.to_non_unique_bytes(cs.ns(|| format!("addition_coefficients {}", i)))?,
289 );
290 }
291 Ok(x)
292 }
293}
294
295impl<P: MNT4Parameters> G2PreparedGadget<P> {
296 pub fn get_value(&self) -> Option<G2Prepared<P>> {
297 match (
298 self.x.get_value(),
299 self.y.get_value(),
300 self.x_over_twist.get_value(),
301 self.y_over_twist.get_value(),
302 self.double_coefficients
303 .iter()
304 .map(|coeff| coeff.get_value())
305 .collect::<Option<Vec<AteDoubleCoefficients<P>>>>(),
306 self.addition_coefficients
307 .iter()
308 .map(|coeff| coeff.get_value())
309 .collect::<Option<Vec<AteAdditionCoefficients<P>>>>(),
310 ) {
311 (
312 Some(x),
313 Some(y),
314 Some(x_over_twist),
315 Some(y_over_twist),
316 Some(double_coefficients),
317 Some(addition_coefficients),
318 ) => Some(G2Prepared {
319 x,
320 y,
321 x_over_twist,
322 y_over_twist,
323 double_coefficients,
324 addition_coefficients,
325 }),
326 _ => None,
327 }
328 }
329
330 pub fn from_affine<CS: ConstraintSystem<P::Fp>>(
331 mut cs: CS,
332 q: &G2Gadget<P>,
333 ) -> Result<Self, SynthesisError> {
334 let twist_inv = P::TWIST.inverse().unwrap();
335
336 let mut g2p = G2PreparedGadget {
337 x: q.x.clone(),
338 y: q.y.clone(),
339 x_over_twist: q.x.mul_by_constant(cs.ns(|| "x over twist"), &twist_inv)?,
340 y_over_twist: q.y.mul_by_constant(cs.ns(|| "y over twist"), &twist_inv)?,
341 double_coefficients: vec![],
342 addition_coefficients: vec![],
343 };
344
345 let fp2_one = Fp2G::<P>::one(cs.ns(|| "one"))?;
346 let mut r = G2ProjectiveExtendedGadget {
347 x: q.x.clone(),
348 y: q.y.clone(),
349 z: fp2_one.clone(),
350 t: fp2_one,
351 };
352
353 for (idx, value) in P::ATE_LOOP_COUNT.iter().rev().enumerate() {
354 let mut tmp = *value;
355 let skip_extraneous_bits = 64 - value.leading_zeros();
356 let mut v = Vec::with_capacity(16);
357 for i in 0..64 {
358 if idx == 0 && (i == 0 || i >= skip_extraneous_bits) {
359 continue;
360 }
361 v.push(tmp & 1 == 1);
362 tmp >>= 1;
363 }
364
365 let mut cs = cs.ns(|| format!("ate loop iteration {}", idx));
366
367 for (j, bit) in v.iter().rev().enumerate() {
368 let (r2, coeff) = PairingGadget::<P>::doubling_step_for_flipped_miller_loop(
369 cs.ns(|| format!("doubling step {}", j)),
370 &r,
371 )?;
372 g2p.double_coefficients.push(coeff);
373 r = r2;
374
375 if *bit {
376 let (r2, coeff) =
377 PairingGadget::<P>::mixed_addition_step_for_flipped_miller_loop(
378 cs.ns(|| format!("mixed addition step {}", j)),
379 &q.x,
380 &q.y,
381 &r,
382 )?;
383 g2p.addition_coefficients.push(coeff);
384 r = r2;
385 }
386
387 tmp >>= 1;
388 }
389 }
390
391 if P::ATE_IS_LOOP_COUNT_NEG {
392 let rz_inv = r.z.inverse(cs.ns(|| "inverse r.z"))?;
393 let rz2_inv = rz_inv.square(cs.ns(|| "rz_inv^2"))?;
394 let rz3_inv = rz_inv.mul(cs.ns(|| "rz_inv * rz_inv^2"), &rz2_inv)?;
395
396 let minus_r_affine_x = r.x.mul(cs.ns(|| "r.x * rz2_inv"), &rz2_inv)?;
397 let minus_r_affine_y =
398 r.y.negate(cs.ns(|| "-r.y"))?
399 .mul(cs.ns(|| "-r.y * rz3_inv"), &rz3_inv)?;
400
401 let add_result = PairingGadget::<P>::mixed_addition_step_for_flipped_miller_loop(
402 cs.ns(|| "mixed_addition step"),
403 &minus_r_affine_x,
404 &minus_r_affine_y,
405 &r,
406 )?;
407 g2p.addition_coefficients.push(add_result.1);
408 }
409
410 Ok(g2p)
411 }
412}
413
414#[derive(Derivative)]
415#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
416pub struct AteDoubleCoefficientsGadget<P: MNT4Parameters> {
417 pub c_h: Fp2Gadget<P::Fp2Params, P::Fp>,
418 pub c_4c: Fp2Gadget<P::Fp2Params, P::Fp>,
419 pub c_j: Fp2Gadget<P::Fp2Params, P::Fp>,
420 pub c_l: Fp2Gadget<P::Fp2Params, P::Fp>,
421}
422
423impl<P: MNT4Parameters> AllocGadget<AteDoubleCoefficients<P>, P::Fp>
424 for AteDoubleCoefficientsGadget<P>
425{
426 fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
427 mut cs: CS,
428 t: T,
429 ) -> Result<Self, SynthesisError>
430 where
431 T: Borrow<AteDoubleCoefficients<P>>,
432 {
433 let obj = t.borrow();
434 let c_h =
435 Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_h"), &obj.c_h)?;
436 let c_4c = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
437 &mut cs.ns(|| "alloc_c_4c"),
438 &obj.c_4c,
439 )?;
440 let c_j =
441 Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_j"), &obj.c_j)?;
442 let c_l =
443 Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_l"), &obj.c_l)?;
444
445 Ok(AteDoubleCoefficientsGadget {
446 c_h,
447 c_4c,
448 c_j,
449 c_l,
450 })
451 }
452
453 fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
454 where
455 F: FnOnce() -> Result<T, SynthesisError>,
456 T: Borrow<AteDoubleCoefficients<P>>,
457 {
458 todo!()
459 }
460
461 fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
462 _cs: CS,
463 _f: F,
464 ) -> Result<Self, SynthesisError>
465 where
466 F: FnOnce() -> Result<T, SynthesisError>,
467 T: Borrow<AteDoubleCoefficients<P>>,
468 {
469 todo!()
470 }
471}
472
473impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
474 #[inline]
475 fn to_bytes<CS: ConstraintSystem<P::Fp>>(
476 &self,
477 mut cs: CS,
478 ) -> Result<Vec<UInt8>, SynthesisError> {
479 let mut c_h = self.c_h.to_bytes(&mut cs.ns(|| "c_h to bytes"))?;
480 let mut c_4c = self.c_4c.to_bytes(&mut cs.ns(|| "c_4c to bytes"))?;
481 let mut c_j = self.c_j.to_bytes(&mut cs.ns(|| "c_j to bytes"))?;
482 let mut c_l = self.c_l.to_bytes(&mut cs.ns(|| "c_l to bytes"))?;
483
484 c_h.append(&mut c_4c);
485 c_h.append(&mut c_j);
486 c_h.append(&mut c_l);
487 Ok(c_h)
488 }
489
490 fn to_non_unique_bytes<CS: ConstraintSystem<P::Fp>>(
491 &self,
492 mut cs: CS,
493 ) -> Result<Vec<UInt8>, SynthesisError> {
494 let mut c_h = self
495 .c_h
496 .to_non_unique_bytes(&mut cs.ns(|| "c_h to bytes"))?;
497 let mut c_4c = self
498 .c_4c
499 .to_non_unique_bytes(&mut cs.ns(|| "c_4c to bytes"))?;
500 let mut c_j = self
501 .c_j
502 .to_non_unique_bytes(&mut cs.ns(|| "c_j to bytes"))?;
503 let mut c_l = self
504 .c_l
505 .to_non_unique_bytes(&mut cs.ns(|| "c_l to bytes"))?;
506
507 c_h.append(&mut c_4c);
508 c_h.append(&mut c_j);
509 c_h.append(&mut c_l);
510 Ok(c_h)
511 }
512}
513
514impl<P: MNT4Parameters> AteDoubleCoefficientsGadget<P> {
515 pub fn get_value(&self) -> Option<AteDoubleCoefficients<P>> {
516 match (
517 self.c_h.get_value(),
518 self.c_4c.get_value(),
519 self.c_j.get_value(),
520 self.c_l.get_value(),
521 ) {
522 (Some(c_h), Some(c_4c), Some(c_j), Some(c_l)) => Some(AteDoubleCoefficients {
523 c_h,
524 c_4c,
525 c_j,
526 c_l,
527 }),
528 _ => None,
529 }
530 }
531}
532
533#[derive(Derivative)]
534#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
535pub struct AteAdditionCoefficientsGadget<P: MNT4Parameters> {
536 pub c_l1: Fp2Gadget<P::Fp2Params, P::Fp>,
537 pub c_rz: Fp2Gadget<P::Fp2Params, P::Fp>,
538}
539
540impl<P: MNT4Parameters> AllocGadget<AteAdditionCoefficients<P>, P::Fp>
541 for AteAdditionCoefficientsGadget<P>
542{
543 fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
544 mut cs: CS,
545 t: T,
546 ) -> Result<Self, SynthesisError>
547 where
548 T: Borrow<AteAdditionCoefficients<P>>,
549 {
550 let obj = t.borrow();
551 let c_l1 = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
552 &mut cs.ns(|| "alloc_c_l1"),
553 &obj.c_l1,
554 )?;
555 let c_rz = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
556 &mut cs.ns(|| "alloc_c_rz"),
557 &obj.c_rz,
558 )?;
559 Ok(AteAdditionCoefficientsGadget { c_l1, c_rz })
560 }
561
562 fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
563 where
564 F: FnOnce() -> Result<T, SynthesisError>,
565 T: Borrow<AteAdditionCoefficients<P>>,
566 {
567 todo!()
568 }
569
570 fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
571 _cs: CS,
572 _f: F,
573 ) -> Result<Self, SynthesisError>
574 where
575 F: FnOnce() -> Result<T, SynthesisError>,
576 T: Borrow<AteAdditionCoefficients<P>>,
577 {
578 todo!()
579 }
580}
581
582impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteAdditionCoefficientsGadget<P> {
583 #[inline]
584 fn to_bytes<CS: ConstraintSystem<P::Fp>>(
585 &self,
586 mut cs: CS,
587 ) -> Result<Vec<UInt8>, SynthesisError> {
588 let mut c_l1 = self.c_l1.to_bytes(&mut cs.ns(|| "c_l1 to bytes"))?;
589 let mut c_rz = self.c_rz.to_bytes(&mut cs.ns(|| "c_rz to bytes"))?;
590
591 c_l1.append(&mut c_rz);
592 Ok(c_l1)
593 }
594
595 fn to_non_unique_bytes<CS: ConstraintSystem<P::Fp>>(
596 &self,
597 mut cs: CS,
598 ) -> Result<Vec<UInt8>, SynthesisError> {
599 let mut c_l1 = self
600 .c_l1
601 .to_non_unique_bytes(&mut cs.ns(|| "c_l1 to bytes"))?;
602 let mut c_rz = self
603 .c_rz
604 .to_non_unique_bytes(&mut cs.ns(|| "c_rz to bytes"))?;
605
606 c_l1.append(&mut c_rz);
607 Ok(c_l1)
608 }
609}
610
611impl<P: MNT4Parameters> AteAdditionCoefficientsGadget<P> {
612 pub fn get_value(&self) -> Option<AteAdditionCoefficients<P>> {
613 match (self.c_l1.get_value(), self.c_rz.get_value()) {
614 (Some(c_l1), Some(c_rz)) => Some(AteAdditionCoefficients { c_l1, c_rz }),
615 _ => None,
616 }
617 }
618}
619
620pub struct G2ProjectiveExtendedGadget<P: MNT4Parameters> {
621 pub x: Fp2Gadget<P::Fp2Params, P::Fp>,
622 pub y: Fp2Gadget<P::Fp2Params, P::Fp>,
623 pub z: Fp2Gadget<P::Fp2Params, P::Fp>,
624 pub t: Fp2Gadget<P::Fp2Params, P::Fp>,
625}