arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/bn128/fq6.go
bn128/fq6.goRaw
  1package bn128
  2
  3import (
  4	"math/big"
  5)
  6
  7// Fq6 is Field 6
  8type Fq6 struct {
  9	F          Fq2
 10	NonResidue [2]*big.Int
 11}
 12
 13// NewFq6 generates a new Fq6
 14func NewFq6(f Fq2, nonResidue [2]*big.Int) Fq6 {
 15	fq6 := Fq6{
 16		f,
 17		nonResidue,
 18	}
 19	return fq6
 20}
 21
 22// Zero returns a Zero value on the Fq6
 23func (fq6 Fq6) Zero() [3][2]*big.Int {
 24	return [3][2]*big.Int{fq6.F.Zero(), fq6.F.Zero(), fq6.F.Zero()}
 25}
 26
 27// One returns a One value on the Fq6
 28func (fq6 Fq6) One() [3][2]*big.Int {
 29	return [3][2]*big.Int{fq6.F.One(), fq6.F.One(), fq6.F.One()}
 30}
 31
 32func (fq6 Fq6) mulByNonResidue(a [2]*big.Int) [2]*big.Int {
 33	return fq6.F.Mul(fq6.NonResidue, a)
 34}
 35
 36// Add performs an addition on the Fq6
 37func (fq6 Fq6) Add(a, b [3][2]*big.Int) [3][2]*big.Int {
 38	return [3][2]*big.Int{
 39		fq6.F.Add(a[0], b[0]),
 40		fq6.F.Add(a[1], b[1]),
 41		fq6.F.Add(a[2], b[2]),
 42	}
 43}
 44
 45// Sub performs a substraction on the Fq6
 46func (fq6 Fq6) Sub(a, b [3][2]*big.Int) [3][2]*big.Int {
 47	return [3][2]*big.Int{
 48		fq6.F.Sub(a[0], b[0]),
 49		fq6.F.Sub(a[1], b[1]),
 50		fq6.F.Sub(a[2], b[2]),
 51	}
 52}
 53
 54// Neg performs a negation on the Fq6
 55func (fq6 Fq6) Neg(a [3][2]*big.Int) [3][2]*big.Int {
 56	return fq6.Sub(fq6.Zero(), a)
 57}
 58
 59// Mul performs a multiplication on the Fq6
 60func (fq6 Fq6) Mul(a, b [3][2]*big.Int) [3][2]*big.Int {
 61	v0 := fq6.F.Mul(a[0], b[0])
 62	v1 := fq6.F.Mul(a[1], b[1])
 63	v2 := fq6.F.Mul(a[2], b[2])
 64	return [3][2]*big.Int{
 65		fq6.F.Add(
 66			v0,
 67			fq6.mulByNonResidue(
 68				fq6.F.Sub(
 69					fq6.F.Mul(
 70						fq6.F.Add(a[1], a[2]),
 71						fq6.F.Add(b[1], b[2])),
 72					fq6.F.Add(v1, v2)))),
 73
 74		fq6.F.Add(
 75			fq6.F.Sub(
 76				fq6.F.Mul(
 77					fq6.F.Add(a[0], a[1]),
 78					fq6.F.Add(b[0], b[1])),
 79				fq6.F.Add(v0, v1)),
 80			fq6.mulByNonResidue(v2)),
 81
 82		fq6.F.Add(
 83			fq6.F.Sub(
 84				fq6.F.Mul(
 85					fq6.F.Add(a[0], a[2]),
 86					fq6.F.Add(b[0], b[2])),
 87				fq6.F.Add(v0, v2)),
 88			v1),
 89	}
 90}
 91
 92// Inverse returns the inverse on the Fq6
 93func (fq6 Fq6) Inverse(a [3][2]*big.Int) [3][2]*big.Int {
 94	t0 := fq6.F.Square(a[0])
 95	t1 := fq6.F.Square(a[1])
 96	t2 := fq6.F.Square(a[2])
 97	t3 := fq6.F.Mul(a[0], a[1])
 98	t4 := fq6.F.Mul(a[0], a[2])
 99	t5 := fq6.F.Mul(a[1], a[2])
100
101	c0 := fq6.F.Sub(t0, fq6.mulByNonResidue(t5))
102	c1 := fq6.F.Sub(fq6.mulByNonResidue(t2), t3)
103	c2 := fq6.F.Sub(t1, t4)
104
105	t6 := fq6.F.Inverse(
106		fq6.F.Add(
107			fq6.F.Mul(a[0], c0),
108			fq6.mulByNonResidue(
109				fq6.F.Add(
110					fq6.F.Mul(a[2], c1),
111					fq6.F.Mul(a[1], c2)))))
112	return [3][2]*big.Int{
113		fq6.F.Mul(t6, c0),
114		fq6.F.Mul(t6, c1),
115		fq6.F.Mul(t6, c2),
116	}
117}
118
119// Div performs a division on the Fq6
120func (fq6 Fq6) Div(a, b [3][2]*big.Int) [3][2]*big.Int {
121	return fq6.Mul(a, fq6.Inverse(b))
122}
123
124// Square performs a square operation on the Fq6
125func (fq6 Fq6) Square(a [3][2]*big.Int) [3][2]*big.Int {
126	s0 := fq6.F.Square(a[0])
127	ab := fq6.F.Mul(a[0], a[1])
128	s1 := fq6.F.Add(ab, ab)
129	s2 := fq6.F.Square(
130		fq6.F.Add(
131			fq6.F.Sub(a[0], a[1]),
132			a[2]))
133	bc := fq6.F.Mul(a[1], a[2])
134	s3 := fq6.F.Add(bc, bc)
135	s4 := fq6.F.Square(a[2])
136
137	return [3][2]*big.Int{
138		fq6.F.Add(
139			s0,
140			fq6.mulByNonResidue(s3)),
141		fq6.F.Add(
142			s1,
143			fq6.mulByNonResidue(s4)),
144		fq6.F.Sub(
145			fq6.F.Add(
146				fq6.F.Add(s1, s2),
147				s3),
148			fq6.F.Add(s0, s4)),
149	}
150}