github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/gfp.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 package bn256 10 11 import ( 12 "errors" 13 "fmt" 14 ) 15 16 type gfP [4]uint64 17 18 func newGFp(x int64) (out *gfP) { 19 if x >= 0 { 20 out = &gfP{uint64(x)} 21 } else { 22 out = &gfP{uint64(-x)} 23 gfpNeg(out, out) 24 } 25 26 montEncode(out, out) 27 return out 28 } 29 30 func (e *gfP) String() string { 31 return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) 32 } 33 34 func (e *gfP) Set(f *gfP) { 35 e[0] = f[0] 36 e[1] = f[1] 37 e[2] = f[2] 38 e[3] = f[3] 39 } 40 41 func (e *gfP) Invert(f *gfP) { 42 bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} 43 44 sum, power := &gfP{}, &gfP{} 45 sum.Set(rN1) 46 power.Set(f) 47 48 for word := 0; word < 4; word++ { 49 for bit := uint(0); bit < 64; bit++ { 50 if (bits[word]>>bit)&1 == 1 { 51 gfpMul(sum, sum, power) 52 } 53 gfpMul(power, power, power) 54 } 55 } 56 57 gfpMul(sum, sum, r3) 58 e.Set(sum) 59 } 60 61 func (e *gfP) Marshal(out []byte) { 62 for w := uint(0); w < 4; w++ { 63 for b := uint(0); b < 8; b++ { 64 out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) 65 } 66 } 67 } 68 69 func (e *gfP) Unmarshal(in []byte) error { 70 //将字节解编为小尾数形式 71 for w := uint(0); w < 4; w++ { 72 for b := uint(0); b < 8; b++ { 73 e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) 74 } 75 } 76 //确保点符合曲线模量 77 for i := 3; i >= 0; i-- { 78 if e[i] < p2[i] { 79 return nil 80 } 81 if e[i] > p2[i] { 82 return errors.New("bn256: coordinate exceeds modulus") 83 } 84 } 85 return errors.New("bn256: coordinate equals modulus") 86 } 87 88 func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 89 func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) }