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.

198 lines
4.2 KiB

  1. package fields
  2. import (
  3. "bytes"
  4. "math/big"
  5. )
  6. // Fq6 is Field 6
  7. type Fq6 struct {
  8. F Fq2
  9. NonResidue [2]*big.Int
  10. }
  11. // NewFq6 generates a new Fq6
  12. func NewFq6(f Fq2, nonResidue [2]*big.Int) Fq6 {
  13. fq6 := Fq6{
  14. f,
  15. nonResidue,
  16. }
  17. return fq6
  18. }
  19. // Zero returns a Zero value on the Fq6
  20. func (fq6 Fq6) Zero() [3][2]*big.Int {
  21. return [3][2]*big.Int{fq6.F.Zero(), fq6.F.Zero(), fq6.F.Zero()}
  22. }
  23. // One returns a One value on the Fq6
  24. func (fq6 Fq6) One() [3][2]*big.Int {
  25. return [3][2]*big.Int{fq6.F.One(), fq6.F.Zero(), fq6.F.Zero()}
  26. }
  27. func (fq6 Fq6) mulByNonResidue(a [2]*big.Int) [2]*big.Int {
  28. return fq6.F.Mul(fq6.NonResidue, a)
  29. }
  30. // Add performs an addition on the Fq6
  31. func (fq6 Fq6) Add(a, b [3][2]*big.Int) [3][2]*big.Int {
  32. return [3][2]*big.Int{
  33. fq6.F.Add(a[0], b[0]),
  34. fq6.F.Add(a[1], b[1]),
  35. fq6.F.Add(a[2], b[2]),
  36. }
  37. }
  38. // Double is ...
  39. func (fq6 Fq6) Double(a [3][2]*big.Int) [3][2]*big.Int {
  40. return fq6.Add(a, a)
  41. }
  42. // Sub performs a subtraction on the Fq6
  43. func (fq6 Fq6) Sub(a, b [3][2]*big.Int) [3][2]*big.Int {
  44. return [3][2]*big.Int{
  45. fq6.F.Sub(a[0], b[0]),
  46. fq6.F.Sub(a[1], b[1]),
  47. fq6.F.Sub(a[2], b[2]),
  48. }
  49. }
  50. // Neg performs a negation on the Fq6
  51. func (fq6 Fq6) Neg(a [3][2]*big.Int) [3][2]*big.Int {
  52. return fq6.Sub(fq6.Zero(), a)
  53. }
  54. // Mul performs a multiplication on the Fq6
  55. func (fq6 Fq6) Mul(a, b [3][2]*big.Int) [3][2]*big.Int {
  56. v0 := fq6.F.Mul(a[0], b[0])
  57. v1 := fq6.F.Mul(a[1], b[1])
  58. v2 := fq6.F.Mul(a[2], b[2])
  59. return [3][2]*big.Int{
  60. fq6.F.Add(
  61. v0,
  62. fq6.mulByNonResidue(
  63. fq6.F.Sub(
  64. fq6.F.Mul(
  65. fq6.F.Add(a[1], a[2]),
  66. fq6.F.Add(b[1], b[2])),
  67. fq6.F.Add(v1, v2)))),
  68. fq6.F.Add(
  69. fq6.F.Sub(
  70. fq6.F.Mul(
  71. fq6.F.Add(a[0], a[1]),
  72. fq6.F.Add(b[0], b[1])),
  73. fq6.F.Add(v0, v1)),
  74. fq6.mulByNonResidue(v2)),
  75. fq6.F.Add(
  76. fq6.F.Sub(
  77. fq6.F.Mul(
  78. fq6.F.Add(a[0], a[2]),
  79. fq6.F.Add(b[0], b[2])),
  80. fq6.F.Add(v0, v2)),
  81. v1),
  82. }
  83. }
  84. // MulScalar is ...
  85. func (fq6 Fq6) MulScalar(base [3][2]*big.Int, e *big.Int) [3][2]*big.Int {
  86. // for more possible implementations see g2.go file, at the function g2.MulScalar()
  87. res := fq6.Zero()
  88. rem := e
  89. exp := base
  90. for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
  91. // if rem % 2 == 1
  92. if bytes.Equal(new(big.Int).Rem(rem, big.NewInt(int64(2))).Bytes(), big.NewInt(int64(1)).Bytes()) {
  93. res = fq6.Add(res, exp)
  94. }
  95. exp = fq6.Double(exp)
  96. rem = rem.Rsh(rem, 1) // rem = rem >> 1
  97. }
  98. return res
  99. }
  100. // Inverse returns the inverse on the Fq6
  101. func (fq6 Fq6) Inverse(a [3][2]*big.Int) [3][2]*big.Int {
  102. t0 := fq6.F.Square(a[0])
  103. t1 := fq6.F.Square(a[1])
  104. t2 := fq6.F.Square(a[2])
  105. t3 := fq6.F.Mul(a[0], a[1])
  106. t4 := fq6.F.Mul(a[0], a[2])
  107. t5 := fq6.F.Mul(a[1], a[2])
  108. c0 := fq6.F.Sub(t0, fq6.mulByNonResidue(t5))
  109. c1 := fq6.F.Sub(fq6.mulByNonResidue(t2), t3)
  110. c2 := fq6.F.Sub(t1, t4)
  111. t6 := fq6.F.Inverse(
  112. fq6.F.Add(
  113. fq6.F.Mul(a[0], c0),
  114. fq6.mulByNonResidue(
  115. fq6.F.Add(
  116. fq6.F.Mul(a[2], c1),
  117. fq6.F.Mul(a[1], c2)))))
  118. return [3][2]*big.Int{
  119. fq6.F.Mul(t6, c0),
  120. fq6.F.Mul(t6, c1),
  121. fq6.F.Mul(t6, c2),
  122. }
  123. }
  124. // Div performs a division on the Fq6
  125. func (fq6 Fq6) Div(a, b [3][2]*big.Int) [3][2]*big.Int {
  126. return fq6.Mul(a, fq6.Inverse(b))
  127. }
  128. // Square performs a square operation on the Fq6
  129. func (fq6 Fq6) Square(a [3][2]*big.Int) [3][2]*big.Int {
  130. s0 := fq6.F.Square(a[0])
  131. ab := fq6.F.Mul(a[0], a[1])
  132. s1 := fq6.F.Add(ab, ab)
  133. s2 := fq6.F.Square(
  134. fq6.F.Add(
  135. fq6.F.Sub(a[0], a[1]),
  136. a[2]))
  137. bc := fq6.F.Mul(a[1], a[2])
  138. s3 := fq6.F.Add(bc, bc)
  139. s4 := fq6.F.Square(a[2])
  140. return [3][2]*big.Int{
  141. fq6.F.Add(
  142. s0,
  143. fq6.mulByNonResidue(s3)),
  144. fq6.F.Add(
  145. s1,
  146. fq6.mulByNonResidue(s4)),
  147. fq6.F.Sub(
  148. fq6.F.Add(
  149. fq6.F.Add(s1, s2),
  150. s3),
  151. fq6.F.Add(s0, s4)),
  152. }
  153. }
  154. // Affine is ...
  155. func (fq6 Fq6) Affine(a [3][2]*big.Int) [3][2]*big.Int {
  156. return [3][2]*big.Int{
  157. fq6.F.Affine(a[0]),
  158. fq6.F.Affine(a[1]),
  159. fq6.F.Affine(a[2]),
  160. }
  161. }
  162. // Equal is ...
  163. func (fq6 Fq6) Equal(a, b [3][2]*big.Int) bool {
  164. return fq6.F.Equal(a[0], b[0]) && fq6.F.Equal(a[1], b[1]) && fq6.F.Equal(a[2], b[2])
  165. }
  166. // Copy is ...
  167. func (fq6 Fq6) Copy(a [3][2]*big.Int) [3][2]*big.Int {
  168. return [3][2]*big.Int{
  169. fq6.F.Copy(a[0]),
  170. fq6.F.Copy(a[1]),
  171. fq6.F.Copy(a[2]),
  172. }
  173. }