github.com/cloudflare/circl@v1.5.0/ecc/bls12381/ff/fp4.go (about) 1 package ff 2 3 import "fmt" 4 5 // Fp4Size is the size of an Fp4 element 6 const Fp4Size = 4 * FpSize 7 8 // Fp4 is obtained by adjoining t, the square root of u+1 to Fp2 9 type Fp4 [2]Fp2 10 11 func (z Fp4) String() string { return fmt.Sprintf("%s + ( %s )*t", z[0], z[1]) } 12 13 func (z *Fp4) SetOne() { 14 z[0].SetOne() 15 z[1] = Fp2{} 16 } 17 18 func (z *Fp4) IsZero() int { 19 return z.IsEqual(&Fp4{}) 20 } 21 22 func (z *Fp4) IsEqual(x *Fp4) int { 23 return z[0].IsEqual(&x[0]) & z[1].IsEqual(&x[1]) 24 } 25 26 func (z *Fp4) Cjg() { z[1].Neg() } 27 28 func (z *Fp4) Neg() { 29 z[0].Neg() 30 z[1].Neg() 31 } 32 33 func (z *Fp4) Add(x *Fp4, y *Fp4) { 34 z[0].Add(&x[0], &y[0]) 35 z[1].Add(&x[1], &y[1]) 36 } 37 38 func (z *Fp4) Sub(x *Fp4, y *Fp4) { 39 z[0].Sub(&x[0], &y[0]) 40 z[1].Sub(&x[1], &y[1]) 41 } 42 43 func (z *Fp4) Mul(x *Fp4, y *Fp4) { 44 var x0y0, x1y1, sx, sy, k Fp2 45 x0y0.Mul(&x[0], &y[0]) 46 x1y1.Mul(&x[1], &y[1]) 47 sx.Add(&x[0], &x[1]) 48 sy.Add(&y[0], &y[1]) 49 k.Mul(&sx, &sy) 50 k.Sub(&k, &x0y0) 51 k.Sub(&k, &x1y1) 52 // k is x0y1+x1y0 computed as (x0+x1)(y0+y1)-x0y0-x1y1 53 z[1] = k 54 // Multiply x1y1 by u+1 55 z[0][1].Add(&x1y1[0], &x1y1[1]) 56 z[0][0].Sub(&x1y1[0], &x1y1[1]) 57 z[0].Add(&z[0], &x0y0) 58 } 59 60 func (z *Fp4) Sqr(x *Fp4) { 61 var x0s, x1s, sx, k Fp2 62 x0s.Sqr(&x[0]) 63 x1s.Sqr(&x[1]) 64 sx.Add(&x[0], &x[1]) 65 k.Sqr(&sx) 66 k.Sub(&k, &x0s) 67 k.Sub(&k, &x1s) 68 69 z[1] = k 70 // Multiplying x1s by u+1 71 z[0][1].Add(&x1s[0], &x1s[1]) 72 z[0][0].Sub(&x1s[0], &x1s[1]) 73 z[0].Add(&z[0], &x0s) 74 } 75 76 func (z *Fp4) Inv(x *Fp4) { 77 // Compute the inverse via conjugation 78 var denom, x0sqr, x1sqr Fp2 79 x0sqr.Sqr(&x[0]) 80 x1sqr.Sqr(&x[1]) 81 denom[1].Add(&x1sqr[0], &x1sqr[1]) 82 denom[0].Sub(&x1sqr[0], &x1sqr[1]) 83 denom.Sub(&x0sqr, &denom) 84 denom.Inv(&denom) 85 z[0] = x[0] 86 z[1].Sub(&z[1], &x[1]) 87 z.mulSubfield(z, &denom) 88 } 89 90 func (z *Fp4) mulSubfield(x *Fp4, y *Fp2) { 91 z[0].Mul(&x[0], y) 92 z[1].Mul(&x[1], y) 93 } 94 95 func (z *Fp4) mulT(x *Fp4) { 96 var t Fp4 97 t[1] = x[0] 98 t[0][1].Add(&x[1][0], &x[1][1]) 99 t[0][0].Sub(&x[1][0], &x[1][1]) 100 *z = t 101 }