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.

150 lines
3.1 KiB

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