github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/crypto/bn256/cloudflare/gfp.go (about)

     1  package bn256
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  type gfP [4]uint64
     9  
    10  func newGFp(x int64) (out *gfP) {
    11  	if x >= 0 {
    12  		out = &gfP{uint64(x)}
    13  	} else {
    14  		out = &gfP{uint64(-x)}
    15  		gfpNeg(out, out)
    16  	}
    17  
    18  	montEncode(out, out)
    19  	return out
    20  }
    21  
    22  func (e *gfP) String() string {
    23  	return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0])
    24  }
    25  
    26  func (e *gfP) Set(f *gfP) {
    27  	e[0] = f[0]
    28  	e[1] = f[1]
    29  	e[2] = f[2]
    30  	e[3] = f[3]
    31  }
    32  
    33  func (e *gfP) Invert(f *gfP) {
    34  	bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029}
    35  
    36  	sum, power := &gfP{}, &gfP{}
    37  	sum.Set(rN1)
    38  	power.Set(f)
    39  
    40  	for word := 0; word < 4; word++ {
    41  		for bit := uint(0); bit < 64; bit++ {
    42  			if (bits[word]>>bit)&1 == 1 {
    43  				gfpMul(sum, sum, power)
    44  			}
    45  			gfpMul(power, power, power)
    46  		}
    47  	}
    48  
    49  	gfpMul(sum, sum, r3)
    50  	e.Set(sum)
    51  }
    52  
    53  func (e *gfP) Marshal(out []byte) {
    54  	for w := uint(0); w < 4; w++ {
    55  		for b := uint(0); b < 8; b++ {
    56  			out[8*w+b] = byte(e[3-w] >> (56 - 8*b))
    57  		}
    58  	}
    59  }
    60  
    61  func (e *gfP) Unmarshal(in []byte) error {
    62  	// Unmarshal the bytes into little endian form
    63  	for w := uint(0); w < 4; w++ {
    64  		e[3-w] = 0
    65  		for b := uint(0); b < 8; b++ {
    66  			e[3-w] += uint64(in[8*w+b]) << (56 - 8*b)
    67  		}
    68  	}
    69  	// Ensure the point respects the curve modulus
    70  	for i := 3; i >= 0; i-- {
    71  		if e[i] < p2[i] {
    72  			return nil
    73  		}
    74  		if e[i] > p2[i] {
    75  			return errors.New("bn256: coordinate exceeds modulus")
    76  		}
    77  	}
    78  	return errors.New("bn256: coordinate equals modulus")
    79  }
    80  
    81  func montEncode(c, a *gfP) { gfpMul(c, a, r2) }
    82  func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) }