gfp12.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package bn256
  5. // For details of the algorithms used, see "Multiplication and Squaring on
  6. // Pairing-Friendly Fields, Devegili et al.
  7. // http://eprint.iacr.org/2006/471.pdf.
  8. import (
  9. "math/big"
  10. )
  11. // gfP12 implements the field of size p¹² as a quadratic extension of gfP6
  12. // where ω²=τ.
  13. type gfP12 struct {
  14. x, y *gfP6 // value is xω + y
  15. }
  16. func newGFp12(pool *bnPool) *gfP12 {
  17. return &gfP12{newGFp6(pool), newGFp6(pool)}
  18. }
  19. func (e *gfP12) String() string {
  20. return "(" + e.x.String() + "," + e.y.String() + ")"
  21. }
  22. func (e *gfP12) Put(pool *bnPool) {
  23. e.x.Put(pool)
  24. e.y.Put(pool)
  25. }
  26. func (e *gfP12) Set(a *gfP12) *gfP12 {
  27. e.x.Set(a.x)
  28. e.y.Set(a.y)
  29. return e
  30. }
  31. func (e *gfP12) SetZero() *gfP12 {
  32. e.x.SetZero()
  33. e.y.SetZero()
  34. return e
  35. }
  36. func (e *gfP12) SetOne() *gfP12 {
  37. e.x.SetZero()
  38. e.y.SetOne()
  39. return e
  40. }
  41. func (e *gfP12) Minimal() {
  42. e.x.Minimal()
  43. e.y.Minimal()
  44. }
  45. func (e *gfP12) IsZero() bool {
  46. e.Minimal()
  47. return e.x.IsZero() && e.y.IsZero()
  48. }
  49. func (e *gfP12) IsOne() bool {
  50. e.Minimal()
  51. return e.x.IsZero() && e.y.IsOne()
  52. }
  53. func (e *gfP12) Conjugate(a *gfP12) *gfP12 {
  54. e.x.Negative(a.x)
  55. e.y.Set(a.y)
  56. return a
  57. }
  58. func (e *gfP12) Negative(a *gfP12) *gfP12 {
  59. e.x.Negative(a.x)
  60. e.y.Negative(a.y)
  61. return e
  62. }
  63. // Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p
  64. func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 {
  65. e.x.Frobenius(a.x, pool)
  66. e.y.Frobenius(a.y, pool)
  67. e.x.MulScalar(e.x, xiToPMinus1Over6, pool)
  68. return e
  69. }
  70. // FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p²
  71. func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 {
  72. e.x.FrobeniusP2(a.x)
  73. e.x.MulGFP(e.x, xiToPSquaredMinus1Over6)
  74. e.y.FrobeniusP2(a.y)
  75. return e
  76. }
  77. func (e *gfP12) Add(a, b *gfP12) *gfP12 {
  78. e.x.Add(a.x, b.x)
  79. e.y.Add(a.y, b.y)
  80. return e
  81. }
  82. func (e *gfP12) Sub(a, b *gfP12) *gfP12 {
  83. e.x.Sub(a.x, b.x)
  84. e.y.Sub(a.y, b.y)
  85. return e
  86. }
  87. func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 {
  88. tx := newGFp6(pool)
  89. tx.Mul(a.x, b.y, pool)
  90. t := newGFp6(pool)
  91. t.Mul(b.x, a.y, pool)
  92. tx.Add(tx, t)
  93. ty := newGFp6(pool)
  94. ty.Mul(a.y, b.y, pool)
  95. t.Mul(a.x, b.x, pool)
  96. t.MulTau(t, pool)
  97. e.y.Add(ty, t)
  98. e.x.Set(tx)
  99. tx.Put(pool)
  100. ty.Put(pool)
  101. t.Put(pool)
  102. return e
  103. }
  104. func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
  105. e.x.Mul(a.x, b, pool)
  106. e.y.Mul(a.y, b, pool)
  107. return e
  108. }
  109. func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
  110. sum := newGFp12(pool)
  111. sum.SetOne()
  112. t := newGFp12(pool)
  113. for i := power.BitLen() - 1; i >= 0; i-- {
  114. t.Square(sum, pool)
  115. if power.Bit(i) != 0 {
  116. sum.Mul(t, a, pool)
  117. } else {
  118. sum.Set(t)
  119. }
  120. }
  121. c.Set(sum)
  122. sum.Put(pool)
  123. t.Put(pool)
  124. return c
  125. }
  126. func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 {
  127. // Complex squaring algorithm
  128. v0 := newGFp6(pool)
  129. v0.Mul(a.x, a.y, pool)
  130. t := newGFp6(pool)
  131. t.MulTau(a.x, pool)
  132. t.Add(a.y, t)
  133. ty := newGFp6(pool)
  134. ty.Add(a.x, a.y)
  135. ty.Mul(ty, t, pool)
  136. ty.Sub(ty, v0)
  137. t.MulTau(v0, pool)
  138. ty.Sub(ty, t)
  139. e.y.Set(ty)
  140. e.x.Double(v0)
  141. v0.Put(pool)
  142. t.Put(pool)
  143. ty.Put(pool)
  144. return e
  145. }
  146. func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 {
  147. // See "Implementing cryptographic pairings", M. Scott, section 3.2.
  148. // ftp://136.206.11.249/pub/crypto/pairings.pdf
  149. t1 := newGFp6(pool)
  150. t2 := newGFp6(pool)
  151. t1.Square(a.x, pool)
  152. t2.Square(a.y, pool)
  153. t1.MulTau(t1, pool)
  154. t1.Sub(t2, t1)
  155. t2.Invert(t1, pool)
  156. e.x.Negative(a.x)
  157. e.y.Set(a.y)
  158. e.MulScalar(e, t2, pool)
  159. t1.Put(pool)
  160. t2.Put(pool)
  161. return e
  162. }