You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.7 KiB

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