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.

140 lines
3.0 KiB

5 years ago
  1. package bn128
  2. import (
  3. "bytes"
  4. "math/big"
  5. )
  6. // Fq2 is Field 2
  7. type Fq2 struct {
  8. F Fq
  9. NonResidue *big.Int
  10. }
  11. // NewFq2 generates a new Fq2
  12. func NewFq2(f Fq, nonResidue *big.Int) Fq2 {
  13. fq2 := Fq2{
  14. f,
  15. nonResidue,
  16. }
  17. return fq2
  18. }
  19. // Zero returns a Zero value on the Fq2
  20. func (fq2 Fq2) Zero() [2]*big.Int {
  21. return [2]*big.Int{fq2.F.Zero(), fq2.F.Zero()}
  22. }
  23. // One returns a One value on the Fq2
  24. func (fq2 Fq2) One() [2]*big.Int {
  25. return [2]*big.Int{fq2.F.One(), fq2.F.One()}
  26. }
  27. func (fq2 Fq2) mulByNonResidue(a *big.Int) *big.Int {
  28. return fq2.F.Mul(fq2.NonResidue, a)
  29. }
  30. // Add performs an addition on the Fq2
  31. func (fq2 Fq2) Add(a, b [2]*big.Int) [2]*big.Int {
  32. return [2]*big.Int{
  33. fq2.F.Add(a[0], b[0]),
  34. fq2.F.Add(a[1], b[1]),
  35. }
  36. }
  37. // Double performs a doubling on the Fq2
  38. func (fq2 Fq2) Double(a [2]*big.Int) [2]*big.Int {
  39. return fq2.Add(a, a)
  40. }
  41. // Sub performs a substraction on the Fq2
  42. func (fq2 Fq2) Sub(a, b [2]*big.Int) [2]*big.Int {
  43. return [2]*big.Int{
  44. fq2.F.Sub(a[0], b[0]),
  45. fq2.F.Sub(a[1], b[1]),
  46. }
  47. }
  48. // Neg performs a negation on the Fq2
  49. func (fq2 Fq2) Neg(a [2]*big.Int) [2]*big.Int {
  50. return fq2.Sub(fq2.Zero(), a)
  51. }
  52. // Mul performs a multiplication on the Fq2
  53. func (fq2 Fq2) Mul(a, b [2]*big.Int) [2]*big.Int {
  54. // Multiplication and Squaring on Pairing-Friendly.pdf; Section 3 (Karatsuba)
  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. func (fq2 Fq2) MulScalar(base [2]*big.Int, e *big.Int) [2]*big.Int {
  67. res := fq2.Zero()
  68. rem := e
  69. exp := base
  70. for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
  71. // if rem % 2 == 1
  72. if bytes.Equal(new(big.Int).Rem(rem, big.NewInt(int64(2))).Bytes(), big.NewInt(int64(1)).Bytes()) {
  73. res = fq2.Add(res, exp)
  74. }
  75. exp = fq2.Double(exp)
  76. rem = rem.Rsh(rem, 1) // rem = rem >> 1
  77. }
  78. return res
  79. }
  80. // Inverse returns the inverse on the Fq2
  81. func (fq2 Fq2) Inverse(a [2]*big.Int) [2]*big.Int {
  82. t0 := fq2.F.Square(a[0])
  83. t1 := fq2.F.Square(a[1])
  84. t2 := fq2.F.Sub(t0, fq2.mulByNonResidue(t1))
  85. t3 := fq2.F.Inverse(t2)
  86. return [2]*big.Int{
  87. fq2.F.Mul(a[0], t3),
  88. fq2.F.Neg(fq2.F.Mul(a[1], t3)),
  89. }
  90. }
  91. // Div performs a division on the Fq2
  92. func (fq2 Fq2) Div(a, b [2]*big.Int) [2]*big.Int {
  93. return fq2.Mul(a, fq2.Inverse(b))
  94. }
  95. // Square performs a square operation on the Fq2
  96. func (fq2 Fq2) Square(a [2]*big.Int) [2]*big.Int {
  97. ab := fq2.F.Mul(a[0], a[1])
  98. return [2]*big.Int{
  99. fq2.F.Sub(
  100. fq2.F.Mul(
  101. fq2.F.Add(a[0], a[1]),
  102. fq2.F.Add(
  103. a[0],
  104. fq2.mulByNonResidue(a[1]))),
  105. fq2.F.Add(
  106. ab,
  107. fq2.mulByNonResidue(ab))),
  108. fq2.F.Add(ab, ab),
  109. }
  110. }
  111. func (fq2 Fq2) IsZero(a [2]*big.Int) bool {
  112. return fq2.F.IsZero(a[0]) && fq2.F.IsZero(a[1])
  113. }
  114. func (fq2 Fq2) Affine(a [2]*big.Int) [2]*big.Int {
  115. return [2]*big.Int{
  116. fq2.F.Affine(a[0]),
  117. fq2.F.Affine(a[1]),
  118. }
  119. }
  120. func (fq2 Fq2) Equal(a, b [2]*big.Int) bool {
  121. return fq2.F.Equal(a[0], b[0]) && fq2.F.Equal(a[1], b[1])
  122. }