github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/gfp.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:36</date> 10 //</624342624811094016> 11 12 package bn256 13 14 import ( 15 "errors" 16 "fmt" 17 ) 18 19 type gfP [4]uint64 20 21 func newGFp(x int64) (out *gfP) { 22 if x >= 0 { 23 out = &gfP{uint64(x)} 24 } else { 25 out = &gfP{uint64(-x)} 26 gfpNeg(out, out) 27 } 28 29 montEncode(out, out) 30 return out 31 } 32 33 func (e *gfP) String() string { 34 return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) 35 } 36 37 func (e *gfP) Set(f *gfP) { 38 e[0] = f[0] 39 e[1] = f[1] 40 e[2] = f[2] 41 e[3] = f[3] 42 } 43 44 func (e *gfP) Invert(f *gfP) { 45 bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} 46 47 sum, power := &gfP{}, &gfP{} 48 sum.Set(rN1) 49 power.Set(f) 50 51 for word := 0; word < 4; word++ { 52 for bit := uint(0); bit < 64; bit++ { 53 if (bits[word]>>bit)&1 == 1 { 54 gfpMul(sum, sum, power) 55 } 56 gfpMul(power, power, power) 57 } 58 } 59 60 gfpMul(sum, sum, r3) 61 e.Set(sum) 62 } 63 64 func (e *gfP) Marshal(out []byte) { 65 for w := uint(0); w < 4; w++ { 66 for b := uint(0); b < 8; b++ { 67 out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) 68 } 69 } 70 } 71 72 func (e *gfP) Unmarshal(in []byte) error { 73 //将字节解编为小尾数形式 74 for w := uint(0); w < 4; w++ { 75 for b := uint(0); b < 8; b++ { 76 e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) 77 } 78 } 79 //确保点符合曲线模量 80 for i := 3; i >= 0; i-- { 81 if e[i] < p2[i] { 82 return nil 83 } 84 if e[i] > p2[i] { 85 return errors.New("bn256: coordinate exceeds modulus") 86 } 87 } 88 return errors.New("bn256: coordinate equals modulus") 89 } 90 91 func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 92 func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) } 93