fp.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package bls12381
  17. import (
  18. "errors"
  19. "math/big"
  20. )
  21. func fromBytes(in []byte) (*fe, error) {
  22. fe := &fe{}
  23. if len(in) != 48 {
  24. return nil, errors.New("input string should be equal 48 bytes")
  25. }
  26. fe.setBytes(in)
  27. if !fe.isValid() {
  28. return nil, errors.New("must be less than modulus")
  29. }
  30. toMont(fe, fe)
  31. return fe, nil
  32. }
  33. func fromBig(in *big.Int) (*fe, error) {
  34. fe := new(fe).setBig(in)
  35. if !fe.isValid() {
  36. return nil, errors.New("invalid input string")
  37. }
  38. toMont(fe, fe)
  39. return fe, nil
  40. }
  41. func fromString(in string) (*fe, error) {
  42. fe, err := new(fe).setString(in)
  43. if err != nil {
  44. return nil, err
  45. }
  46. if !fe.isValid() {
  47. return nil, errors.New("invalid input string")
  48. }
  49. toMont(fe, fe)
  50. return fe, nil
  51. }
  52. func toBytes(e *fe) []byte {
  53. e2 := new(fe)
  54. fromMont(e2, e)
  55. return e2.bytes()
  56. }
  57. func toBig(e *fe) *big.Int {
  58. e2 := new(fe)
  59. fromMont(e2, e)
  60. return e2.big()
  61. }
  62. func toString(e *fe) (s string) {
  63. e2 := new(fe)
  64. fromMont(e2, e)
  65. return e2.string()
  66. }
  67. func toMont(c, a *fe) {
  68. mul(c, a, r2)
  69. }
  70. func fromMont(c, a *fe) {
  71. mul(c, a, &fe{1})
  72. }
  73. func exp(c, a *fe, e *big.Int) {
  74. z := new(fe).set(r1)
  75. for i := e.BitLen(); i >= 0; i-- {
  76. mul(z, z, z)
  77. if e.Bit(i) == 1 {
  78. mul(z, z, a)
  79. }
  80. }
  81. c.set(z)
  82. }
  83. func inverse(inv, e *fe) {
  84. if e.isZero() {
  85. inv.zero()
  86. return
  87. }
  88. u := new(fe).set(&modulus)
  89. v := new(fe).set(e)
  90. s := &fe{1}
  91. r := &fe{0}
  92. var k int
  93. var z uint64
  94. var found = false
  95. // Phase 1
  96. for i := 0; i < 768; i++ {
  97. if v.isZero() {
  98. found = true
  99. break
  100. }
  101. if u.isEven() {
  102. u.div2(0)
  103. s.mul2()
  104. } else if v.isEven() {
  105. v.div2(0)
  106. z += r.mul2()
  107. } else if u.cmp(v) == 1 {
  108. lsubAssign(u, v)
  109. u.div2(0)
  110. laddAssign(r, s)
  111. s.mul2()
  112. } else {
  113. lsubAssign(v, u)
  114. v.div2(0)
  115. laddAssign(s, r)
  116. z += r.mul2()
  117. }
  118. k += 1
  119. }
  120. if !found {
  121. inv.zero()
  122. return
  123. }
  124. if k < 381 || k > 381+384 {
  125. inv.zero()
  126. return
  127. }
  128. if r.cmp(&modulus) != -1 || z > 0 {
  129. lsubAssign(r, &modulus)
  130. }
  131. u.set(&modulus)
  132. lsubAssign(u, r)
  133. // Phase 2
  134. for i := k; i < 384*2; i++ {
  135. double(u, u)
  136. }
  137. inv.set(u)
  138. }
  139. func sqrt(c, a *fe) bool {
  140. u, v := new(fe).set(a), new(fe)
  141. exp(c, a, pPlus1Over4)
  142. square(v, c)
  143. return u.equal(v)
  144. }
  145. func isQuadraticNonResidue(elem *fe) bool {
  146. result := new(fe)
  147. exp(result, elem, pMinus1Over2)
  148. return !result.isOne()
  149. }