github.com/amazechain/amc@v0.1.3/common/crypto/bn256/cloudflare/gfp.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package bn256 18 19 import ( 20 "errors" 21 "fmt" 22 ) 23 24 type gfP [4]uint64 25 26 func newGFp(x int64) (out *gfP) { 27 if x >= 0 { 28 out = &gfP{uint64(x)} 29 } else { 30 out = &gfP{uint64(-x)} 31 gfpNeg(out, out) 32 } 33 34 montEncode(out, out) 35 return out 36 } 37 38 func (e *gfP) String() string { 39 return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) 40 } 41 42 func (e *gfP) Set(f *gfP) { 43 e[0] = f[0] 44 e[1] = f[1] 45 e[2] = f[2] 46 e[3] = f[3] 47 } 48 49 func (e *gfP) Invert(f *gfP) { 50 bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} 51 52 sum, power := &gfP{}, &gfP{} 53 sum.Set(rN1) 54 power.Set(f) 55 56 for word := 0; word < 4; word++ { 57 for bit := uint(0); bit < 64; bit++ { 58 if (bits[word]>>bit)&1 == 1 { 59 gfpMul(sum, sum, power) 60 } 61 gfpMul(power, power, power) 62 } 63 } 64 65 gfpMul(sum, sum, r3) 66 e.Set(sum) 67 } 68 69 func (e *gfP) Marshal(out []byte) { 70 for w := uint(0); w < 4; w++ { 71 for b := uint(0); b < 8; b++ { 72 out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) 73 } 74 } 75 } 76 77 func (e *gfP) Unmarshal(in []byte) error { 78 // Unmarshal the bytes into little endian form 79 for w := uint(0); w < 4; w++ { 80 for b := uint(0); b < 8; b++ { 81 e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) 82 } 83 } 84 // Ensure the point respects the curve modulus 85 for i := 3; i >= 0; i-- { 86 if e[i] < p2[i] { 87 return nil 88 } 89 if e[i] > p2[i] { 90 return errors.New("bn256: coordinate exceeds modulus") 91 } 92 } 93 return errors.New("bn256: coordinate equals modulus") 94 } 95 96 func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 97 func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) }