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.

160 lines
3.5 KiB

  1. package fields
  2. import (
  3. "math/big"
  4. )
  5. // Fq2 is Field 2
  6. type Fq2 struct {
  7. F Fq
  8. NonResidue *big.Int
  9. }
  10. // NewFq2 generates a new Fq2
  11. func NewFq2(f Fq, nonResidue *big.Int) Fq2 {
  12. fq2 := Fq2{
  13. f,
  14. nonResidue,
  15. }
  16. return fq2
  17. }
  18. // Zero returns a Zero value on the Fq2
  19. func (fq2 Fq2) Zero() [2]*big.Int {
  20. return [2]*big.Int{fq2.F.Zero(), fq2.F.Zero()}
  21. }
  22. // One returns a One value on the Fq2
  23. func (fq2 Fq2) One() [2]*big.Int {
  24. return [2]*big.Int{fq2.F.One(), fq2.F.Zero()}
  25. }
  26. func (fq2 Fq2) mulByNonResidue(a *big.Int) *big.Int {
  27. return fq2.F.Mul(fq2.NonResidue, a)
  28. }
  29. // Add performs an addition on the Fq2
  30. func (fq2 Fq2) Add(a, b [2]*big.Int) [2]*big.Int {
  31. return [2]*big.Int{
  32. fq2.F.Add(a[0], b[0]),
  33. fq2.F.Add(a[1], b[1]),
  34. }
  35. }
  36. // Double performs a doubling on the Fq2
  37. func (fq2 Fq2) Double(a [2]*big.Int) [2]*big.Int {
  38. return fq2.Add(a, a)
  39. }
  40. // Sub performs a subtraction on the Fq2
  41. func (fq2 Fq2) Sub(a, b [2]*big.Int) [2]*big.Int {
  42. return [2]*big.Int{
  43. fq2.F.Sub(a[0], b[0]),
  44. fq2.F.Sub(a[1], b[1]),
  45. }
  46. }
  47. // Neg performs a negation on the Fq2
  48. func (fq2 Fq2) Neg(a [2]*big.Int) [2]*big.Int {
  49. return fq2.Sub(fq2.Zero(), a)
  50. }
  51. // Mul performs a multiplication on the Fq2
  52. func (fq2 Fq2) Mul(a, b [2]*big.Int) [2]*big.Int {
  53. // Multiplication and Squaring on Pairing-Friendly.pdf; Section 3 (Karatsuba)
  54. // https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf
  55. v0 := fq2.F.Mul(a[0], b[0])
  56. v1 := fq2.F.Mul(a[1], b[1])
  57. return [2]*big.Int{
  58. fq2.F.Add(v0, fq2.mulByNonResidue(v1)),
  59. fq2.F.Sub(
  60. fq2.F.Mul(
  61. fq2.F.Add(a[0], a[1]),
  62. fq2.F.Add(b[0], b[1])),
  63. fq2.F.Add(v0, v1)),
  64. }
  65. }
  66. // MulScalar is ...
  67. func (fq2 Fq2) MulScalar(p [2]*big.Int, e *big.Int) [2]*big.Int {
  68. // for more possible implementations see g2.go file, at the function g2.MulScalar()
  69. q := fq2.Zero()
  70. d := fq2.F.Copy(e)
  71. r := p
  72. foundone := false
  73. for i := d.BitLen(); i >= 0; i-- {
  74. if foundone {
  75. q = fq2.Double(q)
  76. }
  77. if d.Bit(i) == 1 {
  78. foundone = true
  79. q = fq2.Add(q, r)
  80. }
  81. }
  82. return q
  83. }
  84. // Inverse returns the inverse on the Fq2
  85. func (fq2 Fq2) Inverse(a [2]*big.Int) [2]*big.Int {
  86. // High-Speed Software Implementation of the Optimal Ate Pairing over Barreto–Naehrig Curves .pdf
  87. // https://eprint.iacr.org/2010/354.pdf , algorithm 8
  88. t0 := fq2.F.Square(a[0])
  89. t1 := fq2.F.Square(a[1])
  90. t2 := fq2.F.Sub(t0, fq2.mulByNonResidue(t1))
  91. t3 := fq2.F.Inverse(t2)
  92. return [2]*big.Int{
  93. fq2.F.Mul(a[0], t3),
  94. fq2.F.Neg(fq2.F.Mul(a[1], t3)),
  95. }
  96. }
  97. // Div performs a division on the Fq2
  98. func (fq2 Fq2) Div(a, b [2]*big.Int) [2]*big.Int {
  99. return fq2.Mul(a, fq2.Inverse(b))
  100. }
  101. // Square performs a square operation on the Fq2
  102. func (fq2 Fq2) Square(a [2]*big.Int) [2]*big.Int {
  103. // https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf , complex squaring
  104. ab := fq2.F.Mul(a[0], a[1])
  105. return [2]*big.Int{
  106. fq2.F.Sub(
  107. fq2.F.Mul(
  108. fq2.F.Add(a[0], a[1]),
  109. fq2.F.Add(
  110. a[0],
  111. fq2.mulByNonResidue(a[1]))),
  112. fq2.F.Add(
  113. ab,
  114. fq2.mulByNonResidue(ab))),
  115. fq2.F.Add(ab, ab),
  116. }
  117. }
  118. // IsZero is ...
  119. func (fq2 Fq2) IsZero(a [2]*big.Int) bool {
  120. return fq2.F.IsZero(a[0]) && fq2.F.IsZero(a[1])
  121. }
  122. // Affine is ...
  123. func (fq2 Fq2) Affine(a [2]*big.Int) [2]*big.Int {
  124. return [2]*big.Int{
  125. fq2.F.Affine(a[0]),
  126. fq2.F.Affine(a[1]),
  127. }
  128. }
  129. // Equal is ...
  130. func (fq2 Fq2) Equal(a, b [2]*big.Int) bool {
  131. return fq2.F.Equal(a[0], b[0]) && fq2.F.Equal(a[1], b[1])
  132. }
  133. // Copy is ...
  134. func (fq2 Fq2) Copy(a [2]*big.Int) [2]*big.Int {
  135. return [2]*big.Int{
  136. fq2.F.Copy(a[0]),
  137. fq2.F.Copy(a[1]),
  138. }
  139. }