github.com/0xsequence/ethkit@v1.25.0/go-ethereum/crypto/bls12381/fp.go (about) 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 17 package bls12381 18 19 import ( 20 "errors" 21 "math/big" 22 ) 23 24 func fromBytes(in []byte) (*fe, error) { 25 fe := &fe{} 26 if len(in) != 48 { 27 return nil, errors.New("input string should be equal 48 bytes") 28 } 29 fe.setBytes(in) 30 if !fe.isValid() { 31 return nil, errors.New("must be less than modulus") 32 } 33 toMont(fe, fe) 34 return fe, nil 35 } 36 37 func fromBig(in *big.Int) (*fe, error) { 38 fe := new(fe).setBig(in) 39 if !fe.isValid() { 40 return nil, errors.New("invalid input string") 41 } 42 toMont(fe, fe) 43 return fe, nil 44 } 45 46 func fromString(in string) (*fe, error) { 47 fe, err := new(fe).setString(in) 48 if err != nil { 49 return nil, err 50 } 51 if !fe.isValid() { 52 return nil, errors.New("invalid input string") 53 } 54 toMont(fe, fe) 55 return fe, nil 56 } 57 58 func toBytes(e *fe) []byte { 59 e2 := new(fe) 60 fromMont(e2, e) 61 return e2.bytes() 62 } 63 64 func toBig(e *fe) *big.Int { 65 e2 := new(fe) 66 fromMont(e2, e) 67 return e2.big() 68 } 69 70 func toString(e *fe) (s string) { 71 e2 := new(fe) 72 fromMont(e2, e) 73 return e2.string() 74 } 75 76 func toMont(c, a *fe) { 77 mul(c, a, r2) 78 } 79 80 func fromMont(c, a *fe) { 81 mul(c, a, &fe{1}) 82 } 83 84 func exp(c, a *fe, e *big.Int) { 85 z := new(fe).set(r1) 86 for i := e.BitLen(); i >= 0; i-- { 87 mul(z, z, z) 88 if e.Bit(i) == 1 { 89 mul(z, z, a) 90 } 91 } 92 c.set(z) 93 } 94 95 func inverse(inv, e *fe) { 96 if e.isZero() { 97 inv.zero() 98 return 99 } 100 u := new(fe).set(&modulus) 101 v := new(fe).set(e) 102 s := &fe{1} 103 r := &fe{0} 104 var k int 105 var z uint64 106 var found = false 107 // Phase 1 108 for i := 0; i < 768; i++ { 109 if v.isZero() { 110 found = true 111 break 112 } 113 if u.isEven() { 114 u.div2(0) 115 s.mul2() 116 } else if v.isEven() { 117 v.div2(0) 118 z += r.mul2() 119 } else if u.cmp(v) == 1 { 120 lsubAssign(u, v) 121 u.div2(0) 122 laddAssign(r, s) 123 s.mul2() 124 } else { 125 lsubAssign(v, u) 126 v.div2(0) 127 laddAssign(s, r) 128 z += r.mul2() 129 } 130 k += 1 131 } 132 133 if !found { 134 inv.zero() 135 return 136 } 137 138 if k < 381 || k > 381+384 { 139 inv.zero() 140 return 141 } 142 143 if r.cmp(&modulus) != -1 || z > 0 { 144 lsubAssign(r, &modulus) 145 } 146 u.set(&modulus) 147 lsubAssign(u, r) 148 149 // Phase 2 150 for i := k; i < 384*2; i++ { 151 double(u, u) 152 } 153 inv.set(u) 154 } 155 156 func sqrt(c, a *fe) bool { 157 u, v := new(fe).set(a), new(fe) 158 exp(c, a, pPlus1Over4) 159 square(v, c) 160 return u.equal(v) 161 } 162 163 func isQuadraticNonResidue(elem *fe) bool { 164 result := new(fe) 165 exp(result, elem, pMinus1Over2) 166 return !result.isOne() 167 }