init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+200
View File
@@ -0,0 +1,200 @@
package sm9
import (
"fmt"
"io"
"math/big"
"strings"
"xdx.jelly/xgcl/gerrors"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm3"
"xdx.jelly/xgcl/sm/sm9/errors"
)
// 38635打印数据
const PrintIntermediaDataForSTD38635 = false
// Signature 签名数据结构
type Signature struct {
H big.Int
S G1
}
// NewSignature returns a new Signature.
//
// Deprecated, use `&Signature{}` or `new(Signature)`.
func NewSignature() *Signature {
return &Signature{}
}
// MarshalBinary implements the encoding.BinaryMarshaler interface. It returns the byte slice of H || X || Y.
func (s *Signature) MarshalBinary() ([]byte, error) {
data := make([]byte, 3*Sm9RefMaxLen)
if err := gmath.FillBytes(&s.H, data[:Sm9RefMaxLen]); err != nil {
return nil, err
}
s.S.FillBytes(data[Sm9RefMaxLen:])
return data, nil
}
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
// if return error, s will remain
func (s *Signature) UnmarshalBinary(data []byte) error {
if len(data) != 3*Sm9RefMaxLen {
return gerrors.WithAnnotating(errors.ErrInvalidInput, "input data too short")
}
s.H.SetBytes(data[:Sm9RefMaxLen])
if s.H.Cmp(Order()) >= 0 || s.H.Sign() == 0 {
return gerrors.WithAnnotating(errors.ErrInvalidInput, "Signature.H is zero or bigger than order N")
}
_, err := s.S.Unmarshal(data[Sm9RefMaxLen:])
if err != nil {
return gerrors.WithMessage(err, "Signature.S Unmarshal failed")
}
return nil
}
// String 实现Stringer接口
func (s *Signature) String() string {
return fmt.Sprintf("SM9 Signature{\n\tH: %s,\n\tS: %s\n}", s.H.Text(16), s.S.String())
}
// Bytes output H || X || Y
func (s *Signature) Bytes() []byte {
buf := make([]byte, 3*byteSize)
copy(buf[:byteSize], gmath.BigIntToNByte(&s.H, byteSize))
copy(buf[byteSize:], s.S.Marshal())
return buf
}
func (s *Signature) Set(t *Signature) {
s.H.Set(&t.H)
s.S.Set(&t.S)
}
// SetBytes set signature from a byte slice
func (s *Signature) SetBytes(data []byte) error {
if len(data) < 3*byteSize {
return gerrors.WithAnnotating(errors.ErrInvalidInput, "input data too short")
}
data = data[:3*byteSize]
s.H.SetBytes(data[:byteSize])
s.S.Unmarshal(data[byteSize:])
return nil
}
// Sign 签名
//
// rnd输入随机字节串或随机数发生器,可以为:
// - []byte, 并且len(rnd)= 32
// - io.Reader, 随机数发生器, 如crypto/rand.Reader, 也可以是包装的硬件随机数发生器
// - nil, 则会使用默认的软件随机数发生器
func Sign(msg []byte, ds *UserSignKey, pubs *MastSignPublicKey, rnd interface{}) (*Signature, error) {
if rnd == nil {
rnd = grand.Reader
}
if b, ok := rnd.([]byte); ok {
return sign(msg, ds, pubs, b)
} else if reader, ok := rnd.(io.Reader); ok {
b := make([]byte, numBytes)
if _, err := reader.Read(b); err != nil {
return nil, gerrors.ChainErrors(errors.ErrSignFailed, err)
}
return sign(msg, ds, pubs, b)
} else {
return nil, gerrors.WithAnnotating(errors.ErrSignFailed, "input rnd can only be nil, []byte or io.Reader")
}
}
func sign(msg []byte, ds *UserSignKey, pubs *MastSignPublicKey, rnd []byte) (*Signature, error) {
if len(rnd) != byteSize {
return nil, gerrors.WithAnnotating(errors.ErrInvalidInput, "input rnd too short")
}
signature := &Signature{}
r := new(big.Int)
h := new(big.Int)
g := &GT{}
for {
r.SetBytes(rnd[:byteSize])
if pubs.e != nil {
g.ScalarMult(pubs.e, r)
} else {
mulG1BaseThenPairing(g, &pubs.G2, r)
}
h = H2(msg, g.Marshal())
r.Sub(r, h)
r.Mod(r, Order())
if PrintIntermediaDataForSTD38635 {
fmt.Printf("计算群GT中的元素g = e (P1 , Ppub-s): %s\n", pubs.e.String())
fmt.Printf("计算群GT中的元素w = g^r: %s\n", g.String())
fmt.Printf("h: %s\n", strings.ToUpper(h.Text(16)))
fmt.Printf("计算l = ( r - h ) mod N: %s\n", strings.ToUpper(r.Text(16)))
}
if r.Sign() != 0 {
break
}
d := sm3.Sum(rnd)
copy(rnd, d[:])
}
// Issues 5
// s := ds.G1.ScalarMult(&ds.G1, r) //ds changed!
s := (&G1{}).ScalarMult(&ds.G1, r)
if PrintIntermediaDataForSTD38635 {
fmt.Printf("计算群G1中的元素S: %s\n", s.String())
fmt.Printf("消息M的签名为(h, S):\n")
fmt.Printf("h: %s\n", strings.ToUpper(h.Text(16)))
fmt.Printf("S: %s\n", s.String())
}
signature.H.Set(h)
signature.S.Set(s)
return signature, nil
}
// Verify 签名验证
func Verify(sig *Signature, uid, msg []byte, pubs *MastSignPublicKey) bool {
h := new(big.Int).Set(&sig.H)
if gmath.IsBigInt0(h) || h.Cmp(Order()) >= 0 {
return false
}
if !sig.S.IsValid() || sig.S.IsZero() {
return false
}
t := &GT{}
mulG1BaseThenPairing(t, &pubs.G2, h)
h1 := H1(uid, []byte{hidSign})
p := new(G2).ScalarBaseMult(h1)
p.Add(p, &pubs.G2)
u := &GT{}
pairing(u, &sig.S, p)
if PrintIntermediaDataForSTD38635 {
fmt.Printf("计算群GT中的元素g = e (P1 , Ppub-s): %s\n", pubs.e.String())
fmt.Printf("计算群GT中的元素t = g^h: %s\n", t.String())
fmt.Printf("计算h1 = H1(IDA||hid, N)\n")
fmt.Printf("h1: %s\n", strings.ToUpper(h1.Text(16)))
fmt.Printf("计算群G2中的元素P = [h1]P2 + Ppub-s = (xP , yP): %s\n", p.String())
fmt.Printf("计算群GT中的元素u = e (S , P): %s\n", u.String())
}
u.Add(u, t) // In GT, Add is the same with Mul
h2 := H2(msg, u.Marshal())
if PrintIntermediaDataForSTD38635 {
fmt.Printf("计算群GT中的元素w' = u*t: %s\n", u.String())
fmt.Printf("计算h2 = H2(M||w, N): %s\n", strings.ToUpper(h.Text(16)))
}
return h2.Cmp(h) == 0
}