ark-r1cs-std/r1cs-std/src/fields/fp6_3over2.rs
r1cs-std/src/fields/fp6_3over2.rsRaw
1use crate::fields::{cubic_extension::*, fp2::*};
2use algebra::fields::{fp6_3over2::*, CubicExtParameters, Fp2};
3use core::ops::MulAssign;
4use r1cs_core::SynthesisError;
5
6pub type Fp6Var<P> = CubicExtVar<Fp2Var<<P as Fp6Parameters>::Fp2Params>, Fp6ParamsWrapper<P>>;
7
8impl<P: Fp6Parameters> CubicExtVarParams<Fp2Var<P::Fp2Params>> for Fp6ParamsWrapper<P> {
9 fn mul_base_field_vars_by_frob_coeff(
10 c1: &mut Fp2Var<P::Fp2Params>,
11 c2: &mut Fp2Var<P::Fp2Params>,
12 power: usize,
13 ) {
14 *c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
15 *c2 *= Self::FROBENIUS_COEFF_C2[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
16 }
17}
18
19impl<P: Fp6Parameters> Fp6Var<P> {
20 pub fn mul_by_0_c1_0(&self, c1: &Fp2Var<P::Fp2Params>) -> Result<Self, SynthesisError> {
21 // Karatsuba multiplication
22 // v0 = a0 * b0 = 0
23
24 // v1 = a1 * b1
25 let v1 = &self.c1 * c1;
26
27 // v2 = a2 * b2 = 0
28
29 let a1_plus_a2 = &self.c1 + &self.c2;
30 let b1_plus_b2 = c1.clone();
31
32 let a0_plus_a1 = &self.c0 + &self.c1;
33
34 // c0 = (NONRESIDUE * ((a1 + a2)*(b1 + b2) - v1 - v2)) + v0
35 // = NONRESIDUE * ((a1 + a2) * b1 - v1)
36 let c0 = &(a1_plus_a2 * &b1_plus_b2 - &v1) * P::NONRESIDUE;
37
38 // c1 = (a0 + a1) * (b0 + b1) - v0 - v1 + NONRESIDUE * v2
39 // = (a0 + a1) * b1 - v1
40 let c1 = a0_plus_a1 * c1 - &v1;
41 // c2 = (a0 + a2) * (b0 + b2) - v0 - v2 + v1
42 // = v1
43 let c2 = v1;
44 Ok(Self::new(c0, c1, c2))
45 }
46
47 // #[inline]
48 pub fn mul_by_c0_c1_0(
49 &self,
50 c0: &Fp2Var<P::Fp2Params>,
51 c1: &Fp2Var<P::Fp2Params>,
52 ) -> Result<Self, SynthesisError> {
53 let v0 = &self.c0 * c0;
54 let v1 = &self.c1 * c1;
55 // v2 = 0.
56
57 let a1_plus_a2 = &self.c1 + &self.c2;
58 let a0_plus_a1 = &self.c0 + &self.c1;
59 let a0_plus_a2 = &self.c0 + &self.c2;
60
61 let b1_plus_b2 = c1.clone();
62 let b0_plus_b1 = c0 + c1;
63 let b0_plus_b2 = c0.clone();
64
65 let c0 = (&a1_plus_a2 * &b1_plus_b2 - &v1) * P::NONRESIDUE + &v0;
66
67 let c1 = a0_plus_a1 * &b0_plus_b1 - &v0 - &v1;
68
69 let c2 = a0_plus_a2 * &b0_plus_b2 - &v0 + &v1;
70
71 Ok(Self::new(c0, c1, c2))
72 }
73}
74
75impl<P: Fp6Parameters> MulAssign<Fp2<P::Fp2Params>> for Fp6Var<P> {
76 fn mul_assign(&mut self, other: Fp2<P::Fp2Params>) {
77 self.c0 *= other;
78 self.c1 *= other;
79 self.c2 *= other;
80 }
81}