init: v1.0.0
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
package sm9m
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/gerrors"
|
||||
"xdx.jelly/xgcl/gmath"
|
||||
"xdx.jelly/xgcl/sm/sm9"
|
||||
)
|
||||
|
||||
// 一、签名密钥分割方式,ds= [Ks] * Kc,
|
||||
// 客户端掌握Kc, 服务端掌握 Ks \in G1
|
||||
|
||||
// SignKeyClient 客户端部分签名密钥
|
||||
type SignKeyClient struct {
|
||||
p sm9.G1
|
||||
}
|
||||
|
||||
// SignKeyServer 服务端部分签名密钥
|
||||
type SignKeyServer struct {
|
||||
k big.Int
|
||||
}
|
||||
|
||||
// GenerateKeys 从完整的SM9用户密钥ds生成客户端和服务端部分密钥。
|
||||
// ds为KGC下发的用户密钥,应在调用完成后清除。
|
||||
func GenerateSignKeys(ds *sm9.UserSignKey, rnd io.Reader) (*SignKeyClient, *SignKeyServer, error) {
|
||||
i, j, err := generatePairInt(rnd, sm9.N)
|
||||
if err != nil {
|
||||
return nil, nil, gerrors.WithAnnotating(err, "GenerateSignKeys failed")
|
||||
}
|
||||
kc := &SignKeyClient{}
|
||||
ks := &SignKeyServer{}
|
||||
ks.k.Set(i)
|
||||
kc.p.ScalarMult(&ds.G1, j)
|
||||
return kc, ks, nil
|
||||
}
|
||||
|
||||
// 二、加密密钥分割方式,de= Kc + Ks,
|
||||
// 客户端掌握Kc, 服务端掌握 Ks
|
||||
|
||||
// EncKeyClient 客户端部分签名密钥
|
||||
type EncKeyClient struct {
|
||||
p sm9.G2
|
||||
}
|
||||
|
||||
// EncKeyServer 服务端部分签名密钥
|
||||
type EncKeyServer struct {
|
||||
p sm9.G2
|
||||
}
|
||||
|
||||
// GenerateEncKeys 从完整的SM9用户密钥de生成客户端和服务端部分密钥。
|
||||
// de为KGC下发的用户密钥,应在调用完成后清除。
|
||||
func GenerateEncKeys(de *sm9.UserEncKey, rnd io.Reader) (*EncKeyClient, *EncKeyServer, error) {
|
||||
var k *big.Int
|
||||
var err error
|
||||
for {
|
||||
k, err = rand.Int(rnd, sm9.N)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if k.Sign() > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
kc := &EncKeyClient{}
|
||||
ks := &EncKeyServer{}
|
||||
kc.p.ScalarBaseMult(k)
|
||||
ks.p.Neg(&kc.p)
|
||||
ks.p.Add(&de.G2, &ks.p)
|
||||
return kc, ks, nil
|
||||
}
|
||||
|
||||
// generatePairInt 生成k,s满足k * s = 1 mod n, 0 < k,s < n.
|
||||
func generatePairInt(rnd io.Reader, n *big.Int) (k *big.Int, s *big.Int, err error) {
|
||||
for {
|
||||
k, err = rand.Int(rnd, n)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if k.Sign() > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
s = new(big.Int).ModInverse(k, n)
|
||||
return k, s, nil
|
||||
}
|
||||
|
||||
var _ encoding.BinaryMarshaler = &EncKeyClient{}
|
||||
var _ encoding.BinaryUnmarshaler = &EncKeyClient{}
|
||||
var _ encoding.BinaryMarshaler = &EncKeyServer{}
|
||||
var _ encoding.BinaryUnmarshaler = &EncKeyServer{}
|
||||
|
||||
var _ encoding.BinaryMarshaler = &SignKeyClient{}
|
||||
var _ encoding.BinaryUnmarshaler = &SignKeyClient{}
|
||||
var _ encoding.BinaryMarshaler = &SignKeyServer{}
|
||||
var _ encoding.BinaryUnmarshaler = &SignKeyServer{}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler
|
||||
func (k *EncKeyServer) UnmarshalBinary(data []byte) error {
|
||||
_, err := k.p.Unmarshal(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (k *EncKeyServer) MarshalBinary() (data []byte, err error) {
|
||||
return k.p.Marshal(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler
|
||||
func (k *EncKeyClient) UnmarshalBinary(data []byte) error {
|
||||
_, err := k.p.Unmarshal(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (k *EncKeyClient) MarshalBinary() (data []byte, err error) {
|
||||
return k.p.Marshal(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler
|
||||
func (k *SignKeyClient) UnmarshalBinary(data []byte) error {
|
||||
_, err := k.p.Unmarshal(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (k *SignKeyClient) MarshalBinary() (data []byte, err error) {
|
||||
return k.p.Marshal(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler
|
||||
func (k *SignKeyServer) UnmarshalBinary(data []byte) error {
|
||||
if len(data) > sm9.ByteSize() {
|
||||
return ErrInvalidInput
|
||||
}
|
||||
k.k.SetBytes(data)
|
||||
if k.k.Cmp(sm9.N) >= 0 {
|
||||
return ErrKeyTooBig
|
||||
}
|
||||
if k.k.Sign() == 0 {
|
||||
return ErrKeyIsZero
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (k *SignKeyServer) MarshalBinary() (data []byte, err error) {
|
||||
data = make([]byte, sm9.ByteSize())
|
||||
if err := gmath.FillBytes(&k.k, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
Reference in New Issue
Block a user