arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/bn128/fq12.go
bn128/fq12.goRaw
  1package bn128
  2
  3import (
  4	"math/big"
  5)
  6
  7// Fq12 uses the same algorithms than Fq2, but with [2][3][2]*big.Int data structure
  8
  9// Fq12 is Field 12
 10type Fq12 struct {
 11	F          Fq6
 12	Fq2        Fq2
 13	NonResidue [2]*big.Int
 14}
 15
 16// NewFq12 generates a new Fq12
 17func NewFq12(f Fq6, fq2 Fq2, nonResidue [2]*big.Int) Fq12 {
 18	fq12 := Fq12{
 19		f,
 20		fq2,
 21		nonResidue,
 22	}
 23	return fq12
 24}
 25
 26// Zero returns a Zero value on the Fq12
 27func (fq12 Fq12) Zero() [2][3][2]*big.Int {
 28	return [2][3][2]*big.Int{fq12.F.Zero(), fq12.F.Zero()}
 29}
 30
 31// One returns a One value on the Fq12
 32func (fq12 Fq12) One() [2][3][2]*big.Int {
 33	return [2][3][2]*big.Int{fq12.F.One(), fq12.F.One()}
 34}
 35
 36func (fq12 Fq12) mulByNonResidue(a [3][2]*big.Int) [3][2]*big.Int {
 37	return [3][2]*big.Int{
 38		fq12.Fq2.Mul(fq12.NonResidue, a[2]),
 39		a[0],
 40		a[1],
 41	}
 42}
 43
 44// Add performs an addition on the Fq12
 45func (fq12 Fq12) Add(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
 46	return [2][3][2]*big.Int{
 47		fq12.F.Add(a[0], b[0]),
 48		fq12.F.Add(a[1], b[1]),
 49	}
 50}
 51
 52// Double performs a doubling on the Fq12
 53func (fq12 Fq12) Double(a [2][3][2]*big.Int) [2][3][2]*big.Int {
 54	return fq12.Add(a, a)
 55}
 56
 57// Sub performs a substraction on the Fq12
 58func (fq12 Fq12) Sub(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
 59	return [2][3][2]*big.Int{
 60		fq12.F.Sub(a[0], b[0]),
 61		fq12.F.Sub(a[1], b[1]),
 62	}
 63}
 64
 65// Neg performs a negation on the Fq12
 66func (fq12 Fq12) Neg(a [2][3][2]*big.Int) [2][3][2]*big.Int {
 67	return fq12.Sub(fq12.Zero(), a)
 68}
 69
 70// Mul performs a multiplication on the Fq12
 71func (fq12 Fq12) Mul(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
 72	// Multiplication and Squaring on Pairing-Friendly [2]*big.Ints.pdf; Section 3 (Karatsuba)
 73	v0 := fq12.F.Mul(a[0], b[0])
 74	v1 := fq12.F.Mul(a[1], b[1])
 75	return [2][3][2]*big.Int{
 76		fq12.F.Add(v0, fq12.mulByNonResidue(v1)),
 77		fq12.F.Sub(
 78			fq12.F.Mul(
 79				fq12.F.Add(a[0], a[1]),
 80				fq12.F.Add(b[0], b[1])),
 81			fq12.F.Add(v0, v1)),
 82	}
 83}
 84
 85// Inverse returns the inverse on the Fq12
 86func (fq12 Fq12) Inverse(a [2][3][2]*big.Int) [2][3][2]*big.Int {
 87	t0 := fq12.F.Square(a[0])
 88	t1 := fq12.F.Square(a[1])
 89	t2 := fq12.F.Sub(t0, fq12.mulByNonResidue(t1))
 90	t3 := fq12.F.Inverse(t2)
 91	return [2][3][2]*big.Int{
 92		fq12.F.Mul(a[0], t3),
 93		fq12.F.Neg(fq12.F.Mul(a[1], t3)),
 94	}
 95}
 96
 97// Div performs a division on the Fq12
 98func (fq12 Fq12) Div(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
 99	return fq12.Mul(a, fq12.Inverse(b))
100}
101
102// Square performs a square operation on the Fq12
103func (fq12 Fq12) Square(a [2][3][2]*big.Int) [2][3][2]*big.Int {
104	ab := fq12.F.Mul(a[0], a[1])
105
106	return [2][3][2]*big.Int{
107		fq12.F.Sub(
108			fq12.F.Mul(
109				fq12.F.Add(a[0], a[1]),
110				fq12.F.Add(
111					a[0],
112					fq12.mulByNonResidue(a[1]))),
113			fq12.F.Add(
114				ab,
115				fq12.mulByNonResidue(ab))),
116		fq12.F.Add(ab, ab),
117	}
118}