init: v1.0.0
This commit is contained in:
+200
@@ -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 := >{}
|
||||
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 := >{}
|
||||
mulG1BaseThenPairing(t, &pubs.G2, h)
|
||||
|
||||
h1 := H1(uid, []byte{hidSign})
|
||||
p := new(G2).ScalarBaseMult(h1)
|
||||
p.Add(p, &pubs.G2)
|
||||
|
||||
u := >{}
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user