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