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