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}) }