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.

178 lines
3.8 KiB

  1. package fields
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "math/big"
  6. )
  7. // Fq is the Z field over modulus Q
  8. type Fq struct {
  9. Q *big.Int // Q
  10. }
  11. // NewFq generates a new Fq
  12. func NewFq(q *big.Int) Fq {
  13. return Fq{
  14. q,
  15. }
  16. }
  17. // Zero returns a Zero value on the Fq
  18. func (fq Fq) Zero() *big.Int {
  19. return big.NewInt(int64(0))
  20. }
  21. // One returns a One value on the Fq
  22. func (fq Fq) One() *big.Int {
  23. return big.NewInt(int64(1))
  24. }
  25. // Add performs an addition on the Fq
  26. func (fq Fq) Add(a, b *big.Int) *big.Int {
  27. r := new(big.Int).Add(a, b)
  28. return new(big.Int).Mod(r, fq.Q)
  29. }
  30. // Double performs a doubling on the Fq
  31. func (fq Fq) Double(a *big.Int) *big.Int {
  32. r := new(big.Int).Add(a, a)
  33. return new(big.Int).Mod(r, fq.Q)
  34. }
  35. // Sub performs a subtraction on the Fq
  36. func (fq Fq) Sub(a, b *big.Int) *big.Int {
  37. r := new(big.Int).Sub(a, b)
  38. return new(big.Int).Mod(r, fq.Q)
  39. }
  40. // Neg performs a negation on the Fq
  41. func (fq Fq) Neg(a *big.Int) *big.Int {
  42. m := new(big.Int).Neg(a)
  43. return new(big.Int).Mod(m, fq.Q)
  44. }
  45. // Mul performs a multiplication on the Fq
  46. func (fq Fq) Mul(a, b *big.Int) *big.Int {
  47. m := new(big.Int).Mul(a, b)
  48. return new(big.Int).Mod(m, fq.Q)
  49. }
  50. // MulScalar is ...
  51. func (fq Fq) MulScalar(base, e *big.Int) *big.Int {
  52. return fq.Mul(base, e)
  53. }
  54. // Inverse returns the inverse on the Fq
  55. func (fq Fq) Inverse(a *big.Int) *big.Int {
  56. return new(big.Int).ModInverse(a, fq.Q)
  57. // q := bigCopy(fq.Q)
  58. // t := big.NewInt(int64(0))
  59. // r := fq.Q
  60. // newt := big.NewInt(int64(0))
  61. // newr := fq.Affine(a)
  62. // for !bytes.Equal(newr.Bytes(), big.NewInt(int64(0)).Bytes()) {
  63. // q := new(big.Int).Div(bigCopy(r), bigCopy(newr))
  64. //
  65. // t = bigCopy(newt)
  66. // newt = fq.Sub(t, fq.Mul(q, newt))
  67. //
  68. // r = bigCopy(newr)
  69. // newr = fq.Sub(r, fq.Mul(q, newr))
  70. // }
  71. // if t.Cmp(big.NewInt(0)) == -1 { // t< 0
  72. // t = fq.Add(t, q)
  73. // }
  74. // return t
  75. }
  76. // Div performs the division over the finite field
  77. func (fq Fq) Div(a, b *big.Int) *big.Int {
  78. d := fq.Mul(a, fq.Inverse(b))
  79. return new(big.Int).Mod(d, fq.Q)
  80. }
  81. // Square performs a square operation on the Fq
  82. func (fq Fq) Square(a *big.Int) *big.Int {
  83. m := new(big.Int).Mul(a, a)
  84. return new(big.Int).Mod(m, fq.Q)
  85. }
  86. // Exp performs the exponential over Fq
  87. func (fq Fq) Exp(base *big.Int, e *big.Int) *big.Int {
  88. res := fq.One()
  89. rem := fq.Copy(e)
  90. exp := base
  91. for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
  92. if BigIsOdd(rem) {
  93. res = fq.Mul(res, exp)
  94. }
  95. exp = fq.Square(exp)
  96. rem = new(big.Int).Rsh(rem, 1)
  97. }
  98. return res
  99. }
  100. // Rand is ...
  101. func (fq Fq) Rand() (*big.Int, error) {
  102. // twoexp := new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(maxbits)), nil)
  103. // max := new(big.Int).Sub(twoexp, big.NewInt(1))
  104. maxbits := fq.Q.BitLen()
  105. b := make([]byte, (maxbits/8)-1)
  106. _, err := rand.Read(b)
  107. if err != nil {
  108. return nil, err
  109. }
  110. r := new(big.Int).SetBytes(b)
  111. rq := new(big.Int).Mod(r, fq.Q)
  112. // r over q, nil
  113. return rq, nil
  114. }
  115. // IsZero is ...
  116. func (fq Fq) IsZero(a *big.Int) bool {
  117. return bytes.Equal(a.Bytes(), fq.Zero().Bytes())
  118. }
  119. // Copy is ...
  120. func (fq Fq) Copy(a *big.Int) *big.Int {
  121. return new(big.Int).SetBytes(a.Bytes())
  122. }
  123. // Affine is ...
  124. func (fq Fq) Affine(a *big.Int) *big.Int {
  125. nq := fq.Neg(fq.Q)
  126. aux := a
  127. if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
  128. if aux.Cmp(nq) != 1 { // aux less or equal nq
  129. aux = new(big.Int).Mod(aux, fq.Q)
  130. }
  131. if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
  132. aux = new(big.Int).Add(aux, fq.Q)
  133. }
  134. } else {
  135. if aux.Cmp(fq.Q) != -1 { // aux greater or equal nq
  136. aux = new(big.Int).Mod(aux, fq.Q)
  137. }
  138. }
  139. return aux
  140. }
  141. // Equal is ...
  142. func (fq Fq) Equal(a, b *big.Int) bool {
  143. aAff := fq.Affine(a)
  144. bAff := fq.Affine(b)
  145. return bytes.Equal(aAff.Bytes(), bAff.Bytes())
  146. }
  147. // BigIsOdd is ...
  148. func BigIsOdd(n *big.Int) bool {
  149. one := big.NewInt(int64(1))
  150. and := new(big.Int).And(n, one)
  151. return bytes.Equal(and.Bytes(), big.NewInt(int64(1)).Bytes())
  152. }