@ -0,0 +1,74 @@ |
|||||
|
package bn128 |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
) |
||||
|
|
||||
|
// Fq is the Z field over modulus Q
|
||||
|
type Fq struct { |
||||
|
Q *big.Int // Q
|
||||
|
} |
||||
|
|
||||
|
// NewFq generates a new Fq
|
||||
|
func NewFq(q *big.Int) Fq { |
||||
|
return Fq{ |
||||
|
q, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Zero returns a Zero value on the Fq
|
||||
|
func (fq Fq) Zero() *big.Int { |
||||
|
return big.NewInt(int64(0)) |
||||
|
} |
||||
|
|
||||
|
// One returns a One value on the Fq
|
||||
|
func (fq Fq) One() *big.Int { |
||||
|
return big.NewInt(int64(1)) |
||||
|
} |
||||
|
|
||||
|
// Add performs an addition on the Fq
|
||||
|
func (fq Fq) Add(a, b *big.Int) *big.Int { |
||||
|
sum := new(big.Int).Add(a, b) |
||||
|
return new(big.Int).Mod(sum, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Double performs a doubling on the Fq
|
||||
|
func (fq Fq) Double(a *big.Int) *big.Int { |
||||
|
sum := new(big.Int).Add(a, a) |
||||
|
return new(big.Int).Mod(sum, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Sub performs a substraction on the Fq
|
||||
|
func (fq Fq) Sub(a, b *big.Int) *big.Int { |
||||
|
sum := new(big.Int).Sub(a, b) |
||||
|
return new(big.Int).Mod(sum, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Neg performs a negation on the Fq
|
||||
|
func (fq Fq) Neg(a *big.Int) *big.Int { |
||||
|
m := new(big.Int).Neg(a) |
||||
|
return new(big.Int).Mod(m, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Mul performs a multiplication on the Fq
|
||||
|
func (fq Fq) Mul(a, b *big.Int) *big.Int { |
||||
|
m := new(big.Int).Mul(a, b) |
||||
|
return new(big.Int).Mod(m, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Inverse returns the inverse on the Fq
|
||||
|
func (fq Fq) Inverse(a *big.Int) *big.Int { |
||||
|
return new(big.Int).ModInverse(a, fq.Q) |
||||
|
} |
||||
|
|
||||
|
// Div performs a division on the Fq
|
||||
|
func (fq Fq) Div(a, b *big.Int) *big.Int { |
||||
|
// not used in fq1, method added to fit the interface
|
||||
|
return a |
||||
|
} |
||||
|
|
||||
|
// Square performs a square operation on the Fq
|
||||
|
func (fq Fq) Square(a *big.Int) *big.Int { |
||||
|
m := new(big.Int).Mul(a, a) |
||||
|
return new(big.Int).Mod(m, fq.Q) |
||||
|
} |
@ -0,0 +1,118 @@ |
|||||
|
package bn128 |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
) |
||||
|
|
||||
|
// Fq12 uses the same algorithms than Fq2, but with [2][3][2]*big.Int data structure
|
||||
|
|
||||
|
// Fq12 is Field 12
|
||||
|
type Fq12 struct { |
||||
|
F Fq6 |
||||
|
Fq2 Fq2 |
||||
|
NonResidue [2]*big.Int |
||||
|
} |
||||
|
|
||||
|
// NewFq12 generates a new Fq12
|
||||
|
func NewFq12(f Fq6, fq2 Fq2, nonResidue [2]*big.Int) Fq12 { |
||||
|
fq12 := Fq12{ |
||||
|
f, |
||||
|
fq2, |
||||
|
nonResidue, |
||||
|
} |
||||
|
return fq12 |
||||
|
} |
||||
|
|
||||
|
// Zero returns a Zero value on the Fq12
|
||||
|
func (fq12 Fq12) Zero() [2][3][2]*big.Int { |
||||
|
return [2][3][2]*big.Int{fq12.F.Zero(), fq12.F.Zero()} |
||||
|
} |
||||
|
|
||||
|
// One returns a One value on the Fq12
|
||||
|
func (fq12 Fq12) One() [2][3][2]*big.Int { |
||||
|
return [2][3][2]*big.Int{fq12.F.One(), fq12.F.One()} |
||||
|
} |
||||
|
|
||||
|
func (fq12 Fq12) mulByNonResidue(a [3][2]*big.Int) [3][2]*big.Int { |
||||
|
return [3][2]*big.Int{ |
||||
|
fq12.Fq2.Mul(fq12.NonResidue, a[2]), |
||||
|
a[0], |
||||
|
a[1], |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Add performs an addition on the Fq12
|
||||
|
func (fq12 Fq12) Add(a, b [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
return [2][3][2]*big.Int{ |
||||
|
fq12.F.Add(a[0], b[0]), |
||||
|
fq12.F.Add(a[1], b[1]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Double performs a doubling on the Fq12
|
||||
|
func (fq12 Fq12) Double(a [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
return fq12.Add(a, a) |
||||
|
} |
||||
|
|
||||
|
// Sub performs a substraction on the Fq12
|
||||
|
func (fq12 Fq12) Sub(a, b [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
return [2][3][2]*big.Int{ |
||||
|
fq12.F.Sub(a[0], b[0]), |
||||
|
fq12.F.Sub(a[1], b[1]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Neg performs a negation on the Fq12
|
||||
|
func (fq12 Fq12) Neg(a [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
return fq12.Sub(fq12.Zero(), a) |
||||
|
} |
||||
|
|
||||
|
// Mul performs a multiplication on the Fq12
|
||||
|
func (fq12 Fq12) Mul(a, b [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
// Multiplication and Squaring on Pairing-Friendly [2]*big.Ints.pdf; Section 3 (Karatsuba)
|
||||
|
v0 := fq12.F.Mul(a[0], b[0]) |
||||
|
v1 := fq12.F.Mul(a[1], b[1]) |
||||
|
return [2][3][2]*big.Int{ |
||||
|
fq12.F.Add(v0, fq12.mulByNonResidue(v1)), |
||||
|
fq12.F.Sub( |
||||
|
fq12.F.Mul( |
||||
|
fq12.F.Add(a[0], a[1]), |
||||
|
fq12.F.Add(b[0], b[1])), |
||||
|
fq12.F.Add(v0, v1)), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Inverse returns the inverse on the Fq12
|
||||
|
func (fq12 Fq12) Inverse(a [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
t0 := fq12.F.Square(a[0]) |
||||
|
t1 := fq12.F.Square(a[1]) |
||||
|
t2 := fq12.F.Sub(t0, fq12.mulByNonResidue(t1)) |
||||
|
t3 := fq12.F.Inverse(t2) |
||||
|
return [2][3][2]*big.Int{ |
||||
|
fq12.F.Mul(a[0], t3), |
||||
|
fq12.F.Neg(fq12.F.Mul(a[1], t3)), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Div performs a division on the Fq12
|
||||
|
func (fq12 Fq12) Div(a, b [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
return fq12.Mul(a, fq12.Inverse(b)) |
||||
|
} |
||||
|
|
||||
|
// Square performs a square operation on the Fq12
|
||||
|
func (fq12 Fq12) Square(a [2][3][2]*big.Int) [2][3][2]*big.Int { |
||||
|
ab := fq12.F.Mul(a[0], a[1]) |
||||
|
|
||||
|
return [2][3][2]*big.Int{ |
||||
|
fq12.F.Sub( |
||||
|
fq12.F.Mul( |
||||
|
fq12.F.Add(a[0], a[1]), |
||||
|
fq12.F.Add( |
||||
|
a[0], |
||||
|
fq12.mulByNonResidue(a[1]))), |
||||
|
fq12.F.Add( |
||||
|
ab, |
||||
|
fq12.mulByNonResidue(ab))), |
||||
|
fq12.F.Add(ab, ab), |
||||
|
} |
||||
|
} |
@ -0,0 +1,110 @@ |
|||||
|
package bn128 |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
) |
||||
|
|
||||
|
// Fq2 is Field 2
|
||||
|
type Fq2 struct { |
||||
|
F Fq |
||||
|
NonResidue *big.Int |
||||
|
} |
||||
|
|
||||
|
// NewFq2 generates a new Fq2
|
||||
|
func NewFq2(f Fq, nonResidue *big.Int) Fq2 { |
||||
|
fq2 := Fq2{ |
||||
|
f, |
||||
|
nonResidue, |
||||
|
} |
||||
|
return fq2 |
||||
|
} |
||||
|
|
||||
|
// Zero returns a Zero value on the Fq2
|
||||
|
func (fq2 Fq2) Zero() [2]*big.Int { |
||||
|
return [2]*big.Int{fq2.F.Zero(), fq2.F.Zero()} |
||||
|
} |
||||
|
|
||||
|
// One returns a One value on the Fq2
|
||||
|
func (fq2 Fq2) One() [2]*big.Int { |
||||
|
return [2]*big.Int{fq2.F.One(), fq2.F.One()} |
||||
|
} |
||||
|
|
||||
|
func (fq2 Fq2) mulByNonResidue(a *big.Int) *big.Int { |
||||
|
return fq2.F.Mul(fq2.NonResidue, a) |
||||
|
} |
||||
|
|
||||
|
// Add performs an addition on the Fq2
|
||||
|
func (fq2 Fq2) Add(a, b [2]*big.Int) [2]*big.Int { |
||||
|
return [2]*big.Int{ |
||||
|
fq2.F.Add(a[0], b[0]), |
||||
|
fq2.F.Add(a[1], b[1]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Double performs a doubling on the Fq2
|
||||
|
func (fq2 Fq2) Double(a [2]*big.Int) [2]*big.Int { |
||||
|
return fq2.Add(a, a) |
||||
|
} |
||||
|
|
||||
|
// Sub performs a substraction on the Fq2
|
||||
|
func (fq2 Fq2) Sub(a, b [2]*big.Int) [2]*big.Int { |
||||
|
return [2]*big.Int{ |
||||
|
fq2.F.Sub(a[0], b[0]), |
||||
|
fq2.F.Sub(a[1], b[1]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Neg performs a negation on the Fq2
|
||||
|
func (fq2 Fq2) Neg(a [2]*big.Int) [2]*big.Int { |
||||
|
return fq2.Sub(fq2.Zero(), a) |
||||
|
} |
||||
|
|
||||
|
// Mul performs a multiplication on the Fq2
|
||||
|
func (fq2 Fq2) Mul(a, b [2]*big.Int) [2]*big.Int { |
||||
|
// Multiplication and Squaring on Pairing-Friendly.pdf; Section 3 (Karatsuba)
|
||||
|
v0 := fq2.F.Mul(a[0], b[0]) |
||||
|
v1 := fq2.F.Mul(a[1], b[1]) |
||||
|
return [2]*big.Int{ |
||||
|
fq2.F.Add(v0, fq2.mulByNonResidue(v1)), |
||||
|
fq2.F.Sub( |
||||
|
fq2.F.Mul( |
||||
|
fq2.F.Add(a[0], a[1]), |
||||
|
fq2.F.Add(b[0], b[1])), |
||||
|
fq2.F.Add(v0, v1)), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Inverse returns the inverse on the Fq2
|
||||
|
func (fq2 Fq2) Inverse(a [2]*big.Int) [2]*big.Int { |
||||
|
t0 := fq2.F.Square(a[0]) |
||||
|
t1 := fq2.F.Square(a[1]) |
||||
|
t2 := fq2.F.Sub(t0, fq2.mulByNonResidue(t1)) |
||||
|
t3 := fq2.F.Inverse(t2) |
||||
|
return [2]*big.Int{ |
||||
|
fq2.F.Mul(a[0], t3), |
||||
|
fq2.F.Neg(fq2.F.Mul(a[1], t3)), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Div performs a division on the Fq2
|
||||
|
func (fq2 Fq2) Div(a, b [2]*big.Int) [2]*big.Int { |
||||
|
return fq2.Mul(a, fq2.Inverse(b)) |
||||
|
} |
||||
|
|
||||
|
// Square performs a square operation on the Fq2
|
||||
|
func (fq2 Fq2) Square(a [2]*big.Int) [2]*big.Int { |
||||
|
ab := fq2.F.Mul(a[0], a[1]) |
||||
|
|
||||
|
return [2]*big.Int{ |
||||
|
fq2.F.Sub( |
||||
|
fq2.F.Mul( |
||||
|
fq2.F.Add(a[0], a[1]), |
||||
|
fq2.F.Add( |
||||
|
a[0], |
||||
|
fq2.mulByNonResidue(a[1]))), |
||||
|
fq2.F.Add( |
||||
|
ab, |
||||
|
fq2.mulByNonResidue(ab))), |
||||
|
fq2.F.Add(ab, ab), |
||||
|
} |
||||
|
} |
@ -0,0 +1,150 @@ |
|||||
|
package bn128 |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
) |
||||
|
|
||||
|
// Fq6 is Field 6
|
||||
|
type Fq6 struct { |
||||
|
F Fq2 |
||||
|
NonResidue [2]*big.Int |
||||
|
} |
||||
|
|
||||
|
// NewFq6 generates a new Fq6
|
||||
|
func NewFq6(f Fq2, nonResidue [2]*big.Int) Fq6 { |
||||
|
fq6 := Fq6{ |
||||
|
f, |
||||
|
nonResidue, |
||||
|
} |
||||
|
return fq6 |
||||
|
} |
||||
|
|
||||
|
// Zero returns a Zero value on the Fq6
|
||||
|
func (fq6 Fq6) Zero() [3][2]*big.Int { |
||||
|
return [3][2]*big.Int{fq6.F.Zero(), fq6.F.Zero(), fq6.F.Zero()} |
||||
|
} |
||||
|
|
||||
|
// One returns a One value on the Fq6
|
||||
|
func (fq6 Fq6) One() [3][2]*big.Int { |
||||
|
return [3][2]*big.Int{fq6.F.One(), fq6.F.One(), fq6.F.One()} |
||||
|
} |
||||
|
|
||||
|
func (fq6 Fq6) mulByNonResidue(a [2]*big.Int) [2]*big.Int { |
||||
|
return fq6.F.Mul(fq6.NonResidue, a) |
||||
|
} |
||||
|
|
||||
|
// Add performs an addition on the Fq6
|
||||
|
func (fq6 Fq6) Add(a, b [3][2]*big.Int) [3][2]*big.Int { |
||||
|
return [3][2]*big.Int{ |
||||
|
fq6.F.Add(a[0], b[0]), |
||||
|
fq6.F.Add(a[1], b[1]), |
||||
|
fq6.F.Add(a[2], b[2]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Sub performs a substraction on the Fq6
|
||||
|
func (fq6 Fq6) Sub(a, b [3][2]*big.Int) [3][2]*big.Int { |
||||
|
return [3][2]*big.Int{ |
||||
|
fq6.F.Sub(a[0], b[0]), |
||||
|
fq6.F.Sub(a[1], b[1]), |
||||
|
fq6.F.Sub(a[2], b[2]), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Neg performs a negation on the Fq6
|
||||
|
func (fq6 Fq6) Neg(a [3][2]*big.Int) [3][2]*big.Int { |
||||
|
return fq6.Sub(fq6.Zero(), a) |
||||
|
} |
||||
|
|
||||
|
// Mul performs a multiplication on the Fq6
|
||||
|
func (fq6 Fq6) Mul(a, b [3][2]*big.Int) [3][2]*big.Int { |
||||
|
v0 := fq6.F.Mul(a[0], b[0]) |
||||
|
v1 := fq6.F.Mul(a[1], b[1]) |
||||
|
v2 := fq6.F.Mul(a[2], b[2]) |
||||
|
return [3][2]*big.Int{ |
||||
|
fq6.F.Add( |
||||
|
v0, |
||||
|
fq6.mulByNonResidue( |
||||
|
fq6.F.Sub( |
||||
|
fq6.F.Mul( |
||||
|
fq6.F.Add(a[1], a[2]), |
||||
|
fq6.F.Add(b[1], b[2])), |
||||
|
fq6.F.Add(v1, v2)))), |
||||
|
|
||||
|
fq6.F.Add( |
||||
|
fq6.F.Sub( |
||||
|
fq6.F.Mul( |
||||
|
fq6.F.Add(a[0], a[1]), |
||||
|
fq6.F.Add(b[0], b[1])), |
||||
|
fq6.F.Add(v0, v1)), |
||||
|
fq6.mulByNonResidue(v2)), |
||||
|
|
||||
|
fq6.F.Add( |
||||
|
fq6.F.Sub( |
||||
|
fq6.F.Mul( |
||||
|
fq6.F.Add(a[0], a[2]), |
||||
|
fq6.F.Add(b[0], b[2])), |
||||
|
fq6.F.Add(v0, v2)), |
||||
|
v1), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Inverse returns the inverse on the Fq6
|
||||
|
func (fq6 Fq6) Inverse(a [3][2]*big.Int) [3][2]*big.Int { |
||||
|
t0 := fq6.F.Square(a[0]) |
||||
|
t1 := fq6.F.Square(a[1]) |
||||
|
t2 := fq6.F.Square(a[2]) |
||||
|
t3 := fq6.F.Mul(a[0], a[1]) |
||||
|
t4 := fq6.F.Mul(a[0], a[2]) |
||||
|
t5 := fq6.F.Mul(a[1], a[2]) |
||||
|
|
||||
|
c0 := fq6.F.Sub(t0, fq6.mulByNonResidue(t5)) |
||||
|
c1 := fq6.F.Sub(fq6.mulByNonResidue(t2), t3) |
||||
|
c2 := fq6.F.Sub(t1, t4) |
||||
|
|
||||
|
t6 := fq6.F.Inverse( |
||||
|
fq6.F.Add( |
||||
|
fq6.F.Mul(a[0], c0), |
||||
|
fq6.mulByNonResidue( |
||||
|
fq6.F.Add( |
||||
|
fq6.F.Mul(a[2], c1), |
||||
|
fq6.F.Mul(a[1], c2))))) |
||||
|
return [3][2]*big.Int{ |
||||
|
fq6.F.Mul(t6, c0), |
||||
|
fq6.F.Mul(t6, c1), |
||||
|
fq6.F.Mul(t6, c2), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Div performs a division on the Fq6
|
||||
|
func (fq6 Fq6) Div(a, b [3][2]*big.Int) [3][2]*big.Int { |
||||
|
return fq6.Mul(a, fq6.Inverse(b)) |
||||
|
} |
||||
|
|
||||
|
// Square performs a square operation on the Fq6
|
||||
|
func (fq6 Fq6) Square(a [3][2]*big.Int) [3][2]*big.Int { |
||||
|
s0 := fq6.F.Square(a[0]) |
||||
|
ab := fq6.F.Mul(a[0], a[1]) |
||||
|
s1 := fq6.F.Add(ab, ab) |
||||
|
s2 := fq6.F.Square( |
||||
|
fq6.F.Add( |
||||
|
fq6.F.Sub(a[0], a[1]), |
||||
|
a[2])) |
||||
|
bc := fq6.F.Mul(a[1], a[2]) |
||||
|
s3 := fq6.F.Add(bc, bc) |
||||
|
s4 := fq6.F.Square(a[2]) |
||||
|
|
||||
|
return [3][2]*big.Int{ |
||||
|
fq6.F.Add( |
||||
|
s0, |
||||
|
fq6.mulByNonResidue(s3)), |
||||
|
fq6.F.Add( |
||||
|
s1, |
||||
|
fq6.mulByNonResidue(s4)), |
||||
|
fq6.F.Sub( |
||||
|
fq6.F.Add( |
||||
|
fq6.F.Add(s1, s2), |
||||
|
s3), |
||||
|
fq6.F.Add(s0, s4)), |
||||
|
} |
||||
|
} |
@ -0,0 +1,190 @@ |
|||||
|
package bn128 |
||||
|
|
||||
|
import ( |
||||
|
"math/big" |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
) |
||||
|
|
||||
|
func iToBig(a int) *big.Int { |
||||
|
return big.NewInt(int64(a)) |
||||
|
} |
||||
|
|
||||
|
func iiToBig(a, b int) [2]*big.Int { |
||||
|
return [2]*big.Int{iToBig(a), iToBig(b)} |
||||
|
} |
||||
|
|
||||
|
func iiiToBig(a, b int) [2]*big.Int { |
||||
|
return [2]*big.Int{iToBig(a), iToBig(b)} |
||||
|
} |
||||
|
|
||||
|
func TestFq1(t *testing.T) { |
||||
|
fq1 := NewFq(iToBig(7)) |
||||
|
|
||||
|
res := fq1.Add(iToBig(4), iToBig(4)) |
||||
|
assert.Equal(t, iToBig(1), res) |
||||
|
|
||||
|
res = fq1.Double(iToBig(5)) |
||||
|
assert.Equal(t, iToBig(3), res) |
||||
|
|
||||
|
res = fq1.Sub(iToBig(5), iToBig(7)) |
||||
|
assert.Equal(t, iToBig(5), res) |
||||
|
|
||||
|
res = fq1.Neg(iToBig(5)) |
||||
|
assert.Equal(t, iToBig(2), res) |
||||
|
|
||||
|
res = fq1.Mul(iToBig(5), iToBig(11)) |
||||
|
assert.Equal(t, iToBig(6), res) |
||||
|
|
||||
|
res = fq1.Inverse(iToBig(4)) |
||||
|
assert.Equal(t, iToBig(2), res) |
||||
|
|
||||
|
res = fq1.Square(iToBig(5)) |
||||
|
assert.Equal(t, iToBig(4), res) |
||||
|
} |
||||
|
|
||||
|
func TestFq2(t *testing.T) { |
||||
|
fq1 := NewFq(iToBig(7)) |
||||
|
nonResidueFq2str := "-1" // i / Beta
|
||||
|
nonResidueFq2, ok := new(big.Int).SetString(nonResidueFq2str, 10) |
||||
|
assert.True(t, ok) |
||||
|
assert.Equal(t, nonResidueFq2.String(), nonResidueFq2str) |
||||
|
|
||||
|
fq2 := Fq2{fq1, nonResidueFq2} |
||||
|
|
||||
|
res := fq2.Add(iiToBig(4, 4), iiToBig(3, 4)) |
||||
|
assert.Equal(t, iiToBig(0, 1), res) |
||||
|
|
||||
|
res = fq2.Double(iiToBig(5, 3)) |
||||
|
assert.Equal(t, iiToBig(3, 6), res) |
||||
|
|
||||
|
res = fq2.Sub(iiToBig(5, 3), iiToBig(7, 2)) |
||||
|
assert.Equal(t, iiToBig(5, 1), res) |
||||
|
|
||||
|
res = fq2.Neg(iiToBig(4, 4)) |
||||
|
assert.Equal(t, iiToBig(3, 3), res) |
||||
|
|
||||
|
res = fq2.Mul(iiToBig(4, 4), iiToBig(3, 4)) |
||||
|
assert.Equal(t, iiToBig(3, 0), res) |
||||
|
|
||||
|
res = fq2.Inverse(iiToBig(4, 4)) |
||||
|
assert.Equal(t, iiToBig(1, 6), res) |
||||
|
|
||||
|
res = fq2.Div(iiToBig(4, 4), iiToBig(3, 4)) |
||||
|
assert.Equal(t, iiToBig(0, 6), res) |
||||
|
|
||||
|
res = fq2.Square(iiToBig(4, 4)) |
||||
|
assert.Equal(t, iiToBig(0, 4), res) |
||||
|
res2 := fq2.Mul(iiToBig(4, 4), iiToBig(4, 4)) |
||||
|
assert.Equal(t, res, res2) |
||||
|
|
||||
|
res = fq2.Square(iiToBig(3, 5)) |
||||
|
assert.Equal(t, iiToBig(5, 2), res) |
||||
|
res2 = fq2.Mul(iiToBig(3, 5), iiToBig(3, 5)) |
||||
|
assert.Equal(t, res, res2) |
||||
|
} |
||||
|
|
||||
|
func TestFq6(t *testing.T) { |
||||
|
fq1 := NewFq(big.NewInt(int64(7))) |
||||
|
nonResidueFq2, ok := new(big.Int).SetString("-1", 10) // i
|
||||
|
assert.True(t, ok) |
||||
|
nonResidueFq6 := iiToBig(9, 1) // TODO
|
||||
|
|
||||
|
fq2 := Fq2{fq1, nonResidueFq2} |
||||
|
fq6 := Fq6{fq2, nonResidueFq6} |
||||
|
a := [3][2]*big.Int{ |
||||
|
iiToBig(1, 2), |
||||
|
iiToBig(3, 4), |
||||
|
iiToBig(5, 6)} |
||||
|
b := [3][2]*big.Int{ |
||||
|
iiToBig(12, 11), |
||||
|
iiToBig(10, 9), |
||||
|
iiToBig(8, 7)} |
||||
|
|
||||
|
res := fq6.Add(a, b) |
||||
|
assert.Equal(t, |
||||
|
[3][2]*big.Int{ |
||||
|
iiToBig(6, 6), |
||||
|
iiToBig(6, 6), |
||||
|
iiToBig(6, 6)}, |
||||
|
res) |
||||
|
|
||||
|
res = fq6.Sub(a, b) |
||||
|
assert.Equal(t, |
||||
|
[3][2]*big.Int{ |
||||
|
iiToBig(3, 5), |
||||
|
iiToBig(0, 2), |
||||
|
iiToBig(4, 6)}, |
||||
|
res) |
||||
|
|
||||
|
res = fq6.Mul(a, b) |
||||
|
assert.Equal(t, |
||||
|
[3][2]*big.Int{ |
||||
|
iiToBig(5, 0), |
||||
|
iiToBig(2, 1), |
||||
|
iiToBig(3, 0)}, |
||||
|
res) |
||||
|
|
||||
|
mulRes := fq6.Mul(a, b) |
||||
|
divRes := fq6.Div(mulRes, b) |
||||
|
assert.Equal(t, a, divRes) |
||||
|
} |
||||
|
|
||||
|
func TestFq12(t *testing.T) { |
||||
|
q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) // i
|
||||
|
assert.True(t, ok) |
||||
|
fq1 := NewFq(q) |
||||
|
nonResidueFq2, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i
|
||||
|
assert.True(t, ok) |
||||
|
nonResidueFq6 := iiToBig(9, 1) |
||||
|
|
||||
|
fq2 := Fq2{fq1, nonResidueFq2} |
||||
|
fq6 := Fq6{fq2, nonResidueFq6} |
||||
|
fq12 := Fq12{fq6, fq2, nonResidueFq6} |
||||
|
|
||||
|
a := [2][3][2]*big.Int{ |
||||
|
{ |
||||
|
iiToBig(1, 2), |
||||
|
iiToBig(3, 4), |
||||
|
iiToBig(5, 6), |
||||
|
}, |
||||
|
{ |
||||
|
iiToBig(7, 8), |
||||
|
iiToBig(9, 10), |
||||
|
iiToBig(11, 12), |
||||
|
}, |
||||
|
} |
||||
|
b := [2][3][2]*big.Int{ |
||||
|
{ |
||||
|
iiToBig(12, 11), |
||||
|
iiToBig(10, 9), |
||||
|
iiToBig(8, 7), |
||||
|
}, |
||||
|
{ |
||||
|
iiToBig(6, 5), |
||||
|
iiToBig(4, 3), |
||||
|
iiToBig(2, 1), |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
res := fq12.Add(a, b) |
||||
|
assert.Equal(t, |
||||
|
[2][3][2]*big.Int{ |
||||
|
{ |
||||
|
iiToBig(13, 13), |
||||
|
iiToBig(13, 13), |
||||
|
iiToBig(13, 13), |
||||
|
}, |
||||
|
{ |
||||
|
iiToBig(13, 13), |
||||
|
iiToBig(13, 13), |
||||
|
iiToBig(13, 13), |
||||
|
}, |
||||
|
}, |
||||
|
res) |
||||
|
|
||||
|
mulRes := fq12.Mul(a, b) |
||||
|
divRes := fq12.Div(mulRes, b) |
||||
|
assert.Equal(t, a, divRes) |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package utils |
||||
|
|
||||
|
import "encoding/hex" |
||||
|
|
||||
|
// BytesToHex converts from an array of bytes to a hex encoded string
|
||||
|
func BytesToHex(bytesArray []byte) string { |
||||
|
r := "0x" |
||||
|
h := hex.EncodeToString(bytesArray) |
||||
|
r = r + h |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
// HexToBytes converts from a hex string into an array of bytes
|
||||
|
func HexToBytes(h string) ([]byte, error) { |
||||
|
b, err := hex.DecodeString(h[2:]) |
||||
|
return b, err |
||||
|
} |