123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- // Copyright 2020 The go-ethereum Authors
- // This file is part of the go-ethereum library.
- //
- // The go-ethereum library is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // The go-ethereum library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
- package bls12381
- import (
- "errors"
- "math/big"
- )
- func fromBytes(in []byte) (*fe, error) {
- fe := &fe{}
- if len(in) != 48 {
- return nil, errors.New("input string should be equal 48 bytes")
- }
- fe.setBytes(in)
- if !fe.isValid() {
- return nil, errors.New("must be less than modulus")
- }
- toMont(fe, fe)
- return fe, nil
- }
- func fromBig(in *big.Int) (*fe, error) {
- fe := new(fe).setBig(in)
- if !fe.isValid() {
- return nil, errors.New("invalid input string")
- }
- toMont(fe, fe)
- return fe, nil
- }
- func fromString(in string) (*fe, error) {
- fe, err := new(fe).setString(in)
- if err != nil {
- return nil, err
- }
- if !fe.isValid() {
- return nil, errors.New("invalid input string")
- }
- toMont(fe, fe)
- return fe, nil
- }
- func toBytes(e *fe) []byte {
- e2 := new(fe)
- fromMont(e2, e)
- return e2.bytes()
- }
- func toBig(e *fe) *big.Int {
- e2 := new(fe)
- fromMont(e2, e)
- return e2.big()
- }
- func toString(e *fe) (s string) {
- e2 := new(fe)
- fromMont(e2, e)
- return e2.string()
- }
- func toMont(c, a *fe) {
- mul(c, a, r2)
- }
- func fromMont(c, a *fe) {
- mul(c, a, &fe{1})
- }
- func exp(c, a *fe, e *big.Int) {
- z := new(fe).set(r1)
- for i := e.BitLen(); i >= 0; i-- {
- mul(z, z, z)
- if e.Bit(i) == 1 {
- mul(z, z, a)
- }
- }
- c.set(z)
- }
- func inverse(inv, e *fe) {
- if e.isZero() {
- inv.zero()
- return
- }
- u := new(fe).set(&modulus)
- v := new(fe).set(e)
- s := &fe{1}
- r := &fe{0}
- var k int
- var z uint64
- var found = false
- // Phase 1
- for i := 0; i < 768; i++ {
- if v.isZero() {
- found = true
- break
- }
- if u.isEven() {
- u.div2(0)
- s.mul2()
- } else if v.isEven() {
- v.div2(0)
- z += r.mul2()
- } else if u.cmp(v) == 1 {
- lsubAssign(u, v)
- u.div2(0)
- laddAssign(r, s)
- s.mul2()
- } else {
- lsubAssign(v, u)
- v.div2(0)
- laddAssign(s, r)
- z += r.mul2()
- }
- k += 1
- }
- if !found {
- inv.zero()
- return
- }
- if k < 381 || k > 381+384 {
- inv.zero()
- return
- }
- if r.cmp(&modulus) != -1 || z > 0 {
- lsubAssign(r, &modulus)
- }
- u.set(&modulus)
- lsubAssign(u, r)
- // Phase 2
- for i := k; i < 384*2; i++ {
- double(u, u)
- }
- inv.set(u)
- }
- func sqrt(c, a *fe) bool {
- u, v := new(fe).set(a), new(fe)
- exp(c, a, pPlus1Over4)
- square(v, c)
- return u.equal(v)
- }
- func isQuadraticNonResidue(elem *fe) bool {
- result := new(fe)
- exp(result, elem, pMinus1Over2)
- return !result.isOne()
- }
|