arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/bn128/fq2.go
bn128/fq2.goRaw
  1package bn128
  2
  3import (
  4	"bytes"
  5	"math/big"
  6)
  7
  8// Fq2 is Field 2
  9type Fq2 struct {
 10	F          Fq
 11	NonResidue *big.Int
 12}
 13
 14// NewFq2 generates a new Fq2
 15func NewFq2(f Fq, nonResidue *big.Int) Fq2 {
 16	fq2 := Fq2{
 17		f,
 18		nonResidue,
 19	}
 20	return fq2
 21}
 22
 23// Zero returns a Zero value on the Fq2
 24func (fq2 Fq2) Zero() [2]*big.Int {
 25	return [2]*big.Int{fq2.F.Zero(), fq2.F.Zero()}
 26}
 27
 28// One returns a One value on the Fq2
 29func (fq2 Fq2) One() [2]*big.Int {
 30	return [2]*big.Int{fq2.F.One(), fq2.F.One()}
 31}
 32
 33func (fq2 Fq2) mulByNonResidue(a *big.Int) *big.Int {
 34	return fq2.F.Mul(fq2.NonResidue, a)
 35}
 36
 37// Add performs an addition on the Fq2
 38func (fq2 Fq2) Add(a, b [2]*big.Int) [2]*big.Int {
 39	return [2]*big.Int{
 40		fq2.F.Add(a[0], b[0]),
 41		fq2.F.Add(a[1], b[1]),
 42	}
 43}
 44
 45// Double performs a doubling on the Fq2
 46func (fq2 Fq2) Double(a [2]*big.Int) [2]*big.Int {
 47	return fq2.Add(a, a)
 48}
 49
 50// Sub performs a substraction on the Fq2
 51func (fq2 Fq2) Sub(a, b [2]*big.Int) [2]*big.Int {
 52	return [2]*big.Int{
 53		fq2.F.Sub(a[0], b[0]),
 54		fq2.F.Sub(a[1], b[1]),
 55	}
 56}
 57
 58// Neg performs a negation on the Fq2
 59func (fq2 Fq2) Neg(a [2]*big.Int) [2]*big.Int {
 60	return fq2.Sub(fq2.Zero(), a)
 61}
 62
 63// Mul performs a multiplication on the Fq2
 64func (fq2 Fq2) Mul(a, b [2]*big.Int) [2]*big.Int {
 65	// Multiplication and Squaring on Pairing-Friendly.pdf; Section 3 (Karatsuba)
 66	v0 := fq2.F.Mul(a[0], b[0])
 67	v1 := fq2.F.Mul(a[1], b[1])
 68	return [2]*big.Int{
 69		fq2.F.Add(v0, fq2.mulByNonResidue(v1)),
 70		fq2.F.Sub(
 71			fq2.F.Mul(
 72				fq2.F.Add(a[0], a[1]),
 73				fq2.F.Add(b[0], b[1])),
 74			fq2.F.Add(v0, v1)),
 75	}
 76}
 77func (fq2 Fq2) MulScalar(base [2]*big.Int, e *big.Int) [2]*big.Int {
 78	res := fq2.Zero()
 79	rem := e
 80	exp := base
 81
 82	for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
 83		// if rem % 2 == 1
 84		if bytes.Equal(new(big.Int).Rem(rem, big.NewInt(int64(2))).Bytes(), big.NewInt(int64(1)).Bytes()) {
 85			res = fq2.Add(res, exp)
 86		}
 87		exp = fq2.Double(exp)
 88		rem = rem.Rsh(rem, 1) // rem = rem >> 1
 89	}
 90	return res
 91}
 92
 93// Inverse returns the inverse on the Fq2
 94func (fq2 Fq2) Inverse(a [2]*big.Int) [2]*big.Int {
 95	t0 := fq2.F.Square(a[0])
 96	t1 := fq2.F.Square(a[1])
 97	t2 := fq2.F.Sub(t0, fq2.mulByNonResidue(t1))
 98	t3 := fq2.F.Inverse(t2)
 99	return [2]*big.Int{
100		fq2.F.Mul(a[0], t3),
101		fq2.F.Neg(fq2.F.Mul(a[1], t3)),
102	}
103}
104
105// Div performs a division on the Fq2
106func (fq2 Fq2) Div(a, b [2]*big.Int) [2]*big.Int {
107	return fq2.Mul(a, fq2.Inverse(b))
108}
109
110// Square performs a square operation on the Fq2
111func (fq2 Fq2) Square(a [2]*big.Int) [2]*big.Int {
112	ab := fq2.F.Mul(a[0], a[1])
113
114	return [2]*big.Int{
115		fq2.F.Sub(
116			fq2.F.Mul(
117				fq2.F.Add(a[0], a[1]),
118				fq2.F.Add(
119					a[0],
120					fq2.mulByNonResidue(a[1]))),
121			fq2.F.Add(
122				ab,
123				fq2.mulByNonResidue(ab))),
124		fq2.F.Add(ab, ab),
125	}
126}
127
128func (fq2 Fq2) IsZero(a [2]*big.Int) bool {
129	return fq2.F.IsZero(a[0]) && fq2.F.IsZero(a[1])
130}
131
132func (fq2 Fq2) Affine(a [2]*big.Int) [2]*big.Int {
133	return [2]*big.Int{
134		fq2.F.Affine(a[0]),
135		fq2.F.Affine(a[1]),
136	}
137}