1 Star 1 Fork 0

emmansun / gmsm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
gfp.go 3.54 KB
一键复制 编辑 原始数据 按行查看 历史
emmansun 提交于 2022-08-13 11:14 . sync code from github
package bn256
import (
"encoding/binary"
"errors"
"fmt"
"math/big"
)
type gfP [4]uint64
var zero = newGFp(0)
var one = newGFp(1)
var two = newGFp(2)
func newGFp(x int64) (out *gfP) {
if x >= 0 {
out = &gfP{uint64(x)}
} else {
out = &gfP{uint64(-x)}
gfpNeg(out, out)
}
montEncode(out, out)
return out
}
func fromBigInt(x *big.Int) (out *gfP) {
out = &gfP{}
var a *big.Int
if x.Sign() >= 0 {
a = x
} else {
a = new(big.Int).Neg(x)
}
bytes := a.Bytes()
if len(bytes) > 32 {
panic("sm9: invalid byte length")
} else if len(bytes) < 32 {
fixedBytes := make([]byte, 32)
copy(fixedBytes[32-len(bytes):], bytes)
bytes = fixedBytes
}
for i := 0; i < 4; i++ {
start := len(bytes) - 8
out[i] = binary.BigEndian.Uint64(bytes[start:])
bytes = bytes[:start]
}
if x.Sign() < 0 {
gfpNeg(out, out)
}
if x.Sign() != 0 {
montEncode(out, out)
}
return out
}
func (e *gfP) String() string {
return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0])
}
func (e *gfP) Set(f *gfP) {
e[0] = f[0]
e[1] = f[1]
e[2] = f[2]
e[3] = f[3]
}
func (e *gfP) exp(f *gfP, bits [4]uint64) {
sum, power := &gfP{}, &gfP{}
sum.Set(rN1)
power.Set(f)
for word := 0; word < 4; word++ {
for bit := uint(0); bit < 64; bit++ {
if (bits[word]>>bit)&1 == 1 {
gfpMul(sum, sum, power)
}
gfpMul(power, power, power)
}
}
gfpMul(sum, sum, r3)
e.Set(sum)
}
func (e *gfP) Invert(f *gfP) {
e.exp(f, pMinus2)
}
func (e *gfP) Sqrt(f *gfP) {
// Since p = 8k+5,
// Atkin algorithm
// https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.896.6057&rep=rep1&type=pdf
// https://eprint.iacr.org/2012/685.pdf
//
a1, b, i := &gfP{}, &gfP{}, &gfP{}
a1.exp(f, pMinus5Over8)
gfpMul(b, twoExpPMinus5Over8, a1) // b=ta1
gfpMul(a1, f, b) // a1=fb
gfpMul(i, two, a1) // i=2(fb)
gfpMul(i, i, b) // i=2(fb)b
gfpSub(i, i, one) // i=2(fb)b-1
gfpMul(i, a1, i) // i=(fb)(2(fb)b-1)
e.Set(i)
}
func (e *gfP) Marshal(out []byte) {
for w := uint(0); w < 4; w++ {
for b := uint(0); b < 8; b++ {
out[8*w+b] = byte(e[3-w] >> (56 - 8*b))
}
}
}
func (e *gfP) Unmarshal(in []byte) error {
// Unmarshal the bytes into little endian form
for w := uint(0); w < 4; w++ {
e[3-w] = 0
for b := uint(0); b < 8; b++ {
e[3-w] += uint64(in[8*w+b]) << (56 - 8*b)
}
}
// Ensure the point respects the curve modulus
for i := 3; i >= 0; i-- {
if e[i] < p2[i] {
return nil
}
if e[i] > p2[i] {
return errors.New("sm9: coordinate exceeds modulus")
}
}
return errors.New("sm9: coordinate equals modulus")
}
func montEncode(c, a *gfP) { gfpMul(c, a, r2) }
func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) }
// cmovznzU64 is a single-word conditional move.
//
// Postconditions:
// out1 = (if arg1 = 0 then arg2 else arg3)
//
// Input Bounds:
// arg1: [0x0 ~> 0x1]
// arg2: [0x0 ~> 0xffffffffffffffff]
// arg3: [0x0 ~> 0xffffffffffffffff]
// Output Bounds:
// out1: [0x0 ~> 0xffffffffffffffff]
func cmovznzU64(out1 *uint64, arg1 uint64, arg2 uint64, arg3 uint64) {
x1 := (uint64(arg1) * 0xffffffffffffffff)
x2 := ((x1 & arg3) | ((^x1) & arg2))
*out1 = x2
}
// Select sets e to p1 if cond == 1, and to p2 if cond == 0.
func (e *gfP) Select(p1, p2 *gfP, cond int) *gfP {
var x1 uint64
cmovznzU64(&x1, uint64(cond), p2[0], p1[0])
var x2 uint64
cmovznzU64(&x2, uint64(cond), p2[1], p1[1])
var x3 uint64
cmovznzU64(&x3, uint64(cond), p2[2], p1[2])
var x4 uint64
cmovznzU64(&x4, uint64(cond), p2[3], p1[3])
e[0] = x1
e[1] = x2
e[2] = x3
e[3] = x4
return e
}
Go
1
https://gitee.com/emmansun/gmsm.git
git@gitee.com:emmansun/gmsm.git
emmansun
gmsm
gmsm
v0.13.6

搜索帮助