gfp2.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package bn256
  2. // For details of the algorithms used, see "Multiplication and Squaring on
  3. // Pairing-Friendly Fields, Devegili et al.
  4. // http://eprint.iacr.org/2006/471.pdf.
  5. // gfP2 implements a field of size p² as a quadratic extension of the base field
  6. // where i²=-1.
  7. type gfP2 struct {
  8. x, y gfP // value is xi+y.
  9. }
  10. func gfP2Decode(in *gfP2) *gfP2 {
  11. out := &gfP2{}
  12. montDecode(&out.x, &in.x)
  13. montDecode(&out.y, &in.y)
  14. return out
  15. }
  16. func (e *gfP2) String() string {
  17. return "(" + e.x.String() + ", " + e.y.String() + ")"
  18. }
  19. func (e *gfP2) Set(a *gfP2) *gfP2 {
  20. e.x.Set(&a.x)
  21. e.y.Set(&a.y)
  22. return e
  23. }
  24. func (e *gfP2) SetZero() *gfP2 {
  25. e.x = gfP{0}
  26. e.y = gfP{0}
  27. return e
  28. }
  29. func (e *gfP2) SetOne() *gfP2 {
  30. e.x = gfP{0}
  31. e.y = *newGFp(1)
  32. return e
  33. }
  34. func (e *gfP2) IsZero() bool {
  35. zero := gfP{0}
  36. return e.x == zero && e.y == zero
  37. }
  38. func (e *gfP2) IsOne() bool {
  39. zero, one := gfP{0}, *newGFp(1)
  40. return e.x == zero && e.y == one
  41. }
  42. func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
  43. e.y.Set(&a.y)
  44. gfpNeg(&e.x, &a.x)
  45. return e
  46. }
  47. func (e *gfP2) Neg(a *gfP2) *gfP2 {
  48. gfpNeg(&e.x, &a.x)
  49. gfpNeg(&e.y, &a.y)
  50. return e
  51. }
  52. func (e *gfP2) Add(a, b *gfP2) *gfP2 {
  53. gfpAdd(&e.x, &a.x, &b.x)
  54. gfpAdd(&e.y, &a.y, &b.y)
  55. return e
  56. }
  57. func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
  58. gfpSub(&e.x, &a.x, &b.x)
  59. gfpSub(&e.y, &a.y, &b.y)
  60. return e
  61. }
  62. // See "Multiplication and Squaring in Pairing-Friendly Fields",
  63. // http://eprint.iacr.org/2006/471.pdf
  64. func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
  65. tx, t := &gfP{}, &gfP{}
  66. gfpMul(tx, &a.x, &b.y)
  67. gfpMul(t, &b.x, &a.y)
  68. gfpAdd(tx, tx, t)
  69. ty := &gfP{}
  70. gfpMul(ty, &a.y, &b.y)
  71. gfpMul(t, &a.x, &b.x)
  72. gfpSub(ty, ty, t)
  73. e.x.Set(tx)
  74. e.y.Set(ty)
  75. return e
  76. }
  77. func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 {
  78. gfpMul(&e.x, &a.x, b)
  79. gfpMul(&e.y, &a.y, b)
  80. return e
  81. }
  82. // MulXi sets e=ξa where ξ=i+9 and then returns e.
  83. func (e *gfP2) MulXi(a *gfP2) *gfP2 {
  84. // (xi+y)(i+9) = (9x+y)i+(9y-x)
  85. tx := &gfP{}
  86. gfpAdd(tx, &a.x, &a.x)
  87. gfpAdd(tx, tx, tx)
  88. gfpAdd(tx, tx, tx)
  89. gfpAdd(tx, tx, &a.x)
  90. gfpAdd(tx, tx, &a.y)
  91. ty := &gfP{}
  92. gfpAdd(ty, &a.y, &a.y)
  93. gfpAdd(ty, ty, ty)
  94. gfpAdd(ty, ty, ty)
  95. gfpAdd(ty, ty, &a.y)
  96. gfpSub(ty, ty, &a.x)
  97. e.x.Set(tx)
  98. e.y.Set(ty)
  99. return e
  100. }
  101. func (e *gfP2) Square(a *gfP2) *gfP2 {
  102. // Complex squaring algorithm:
  103. // (xi+y)² = (x+y)(y-x) + 2*i*x*y
  104. tx, ty := &gfP{}, &gfP{}
  105. gfpSub(tx, &a.y, &a.x)
  106. gfpAdd(ty, &a.x, &a.y)
  107. gfpMul(ty, tx, ty)
  108. gfpMul(tx, &a.x, &a.y)
  109. gfpAdd(tx, tx, tx)
  110. e.x.Set(tx)
  111. e.y.Set(ty)
  112. return e
  113. }
  114. func (e *gfP2) Invert(a *gfP2) *gfP2 {
  115. // See "Implementing cryptographic pairings", M. Scott, section 3.2.
  116. // ftp://136.206.11.249/pub/crypto/pairings.pdf
  117. t1, t2 := &gfP{}, &gfP{}
  118. gfpMul(t1, &a.x, &a.x)
  119. gfpMul(t2, &a.y, &a.y)
  120. gfpAdd(t1, t1, t2)
  121. inv := &gfP{}
  122. inv.Invert(t1)
  123. gfpNeg(t1, &a.x)
  124. gfpMul(&e.x, t1, inv)
  125. gfpMul(&e.y, &a.y, inv)
  126. return e
  127. }