Files
xgcl/sm/sm9/key.go
T
2026-05-27 23:03:00 +08:00

377 lines
9.5 KiB
Go

package sm9
import (
"encoding/hex"
"io"
"math/big"
"xdx.jelly/xgcl/gerrors"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/sm/sm3"
"xdx.jelly/xgcl/sm/sm9/errors"
)
// MastSignPublicKey 签名主公钥
type MastSignPublicKey struct {
G2
e *GT // Precomputed. If e != nil, then e = e(pubs, g2).
}
// MastSignPrivateKey 签名主私钥。主公钥使用.Public()方法获得。
type MastSignPrivateKey struct {
public *MastSignPublicKey
big.Int
}
// MastEncPublicKey 加密主公钥
type MastEncPublicKey struct {
G1
e *GT // if e != nil, then e = e(g1, pube)
}
// MastEncPrivateKey 加密主私钥,主公钥使用.Public()方法获得
type MastEncPrivateKey struct {
public *MastEncPublicKey
big.Int
}
// UserSignKey 用户签名私钥
type UserSignKey struct {
G1
}
// UserEncKey 用户加密私钥
type UserEncKey struct {
G2
}
// BytesCount return how many bytes an UserSignKey need.
func (k *UserSignKey) BytesCount() int {
return 2 * 256 / 8
}
// BytesCount return how many bytes an UserEncKey need.
func (k *UserEncKey) BytesCount() int {
return 4 * 256 / 8
}
// Clear set the memory to zeros.
func (k *MastSignPrivateKey) Clear() {
gmath.ClearBigInt(&k.Int)
k.public.G2.SetInfinity()
}
// Clear set the memory to zeros.
func (k *MastEncPrivateKey) Clear() {
gmath.ClearBigInt(&k.Int)
k.public.G1.SetInfinity()
}
// Clear set the user's sign key to const g1.
func (k *UserSignKey) Clear() {
k.G1.SetInfinity()
}
// Clear set the user's encryption key to const g2.
func (k *UserEncKey) Clear() {
k.G2.SetInfinity()
}
// Bytes 主签名私钥转化为32字节串
func (k *MastSignPrivateKey) Bytes() []byte {
k.Int.Mod(&k.Int, Order())
ret := make([]byte, byteSize)
_ = gmath.FillBytes(&k.Int, ret)
return ret
}
// fillBytes 主签名私钥转化为32字节串, b 必须为32字节
func (k *MastSignPrivateKey) fillBytes(b []byte) {
k.Int.Mod(&k.Int, Order())
_ = gmath.FillBytes(&k.Int, b)
}
// Bytes 主签名公钥转化为128字节串 X0||X1||Y0||Y1
func (k *MastSignPublicKey) Bytes() []byte {
return k.G2.Marshal()
}
// fillBytes 主签名公钥转化为128字节串 X0||X1||Y0||Y1, b必须为128字节
func (k *MastSignPublicKey) fillBytes(b []byte) {
k.G2.FillBytes(b)
}
// Bytes 主加密私钥转化为32字节串
func (k *MastEncPrivateKey) Bytes() []byte {
k.Int.Mod(&k.Int, Order())
return gmath.BigIntToNByte(&k.Int, byteSize)
}
// fillBytes 主加密私钥转化为32字节串
func (k *MastEncPrivateKey) fillBytes(b []byte) {
k.Int.Mod(&k.Int, Order())
gmath.FillBytes(&k.Int, b)
}
// Bytes 主加密公钥转化为64字节串X||Y
func (k *MastEncPublicKey) Bytes() []byte {
return k.G1.Marshal()
}
// fillBytes 主加密公钥转化为64字节串X||Y, len(b) must be 64
func (k *MastEncPublicKey) fillBytes(b []byte) {
k.G1.FillBytes(b)
}
// Bytes 用户签名私钥转化为64字节串X||Y
func (k *UserSignKey) Bytes() []byte {
return k.G1.Marshal()
}
// fillBytes 用户签名私钥转化为64字节串X||Y
func (k *UserSignKey) fillBytes(b []byte) {
k.G1.FillBytes(b)
}
// Bytes 用户加密私钥转换为128字节串X0||X1||Y0||Y1
func (k *UserEncKey) Bytes() []byte {
return k.G2.Marshal()
}
// fillBytes 用户加密私钥转换为128字节串X0||X1||Y0||Y1
func (k *UserEncKey) fillBytes(b []byte) {
k.G2.FillBytes(b)
}
// SetBytes 从字节串转换为主签名私钥
func (k *MastSignPrivateKey) SetBytes(buf []byte) (*MastSignPrivateKey, error) {
k.Int.SetBytes(buf)
k.Int.Mod(&k.Int, Order())
k.computePublic()
return k, nil
}
// SetBytes 从字节串转换为主签名公钥
func (k *MastSignPublicKey) SetBytes(buf []byte) (*MastSignPublicKey, error) {
if len(buf) < 4*byteSize {
return nil, gerrors.WithAnnotating(errors.ErrInvalidInput, "input data too short")
}
_, err := k.G2.Unmarshal(buf)
if err != nil {
return nil, err
}
k.ComputePairing()
return k, nil
}
// SetBytes 从字节串转换为主加密私钥
func (k *MastEncPrivateKey) SetBytes(buf []byte) (*MastEncPrivateKey, error) {
k.Int.SetBytes(buf)
k.Int.Mod(&k.Int, Order())
k.computePublic()
return k, nil
}
// SetBytes 从字节串转换为主加密公钥
func (k *MastEncPublicKey) SetBytes(buf []byte) (*MastEncPublicKey, error) {
if len(buf) < 2*byteSize {
return nil, gerrors.WithAnnotating(errors.ErrInvalidInput, "input data too short")
}
_, err := k.G1.Unmarshal(buf)
if err != nil {
return nil, err
}
k.ComputePairing()
return k, nil
}
// SetBytes 从字节串转换为用户签名私钥
func (k *UserSignKey) SetBytes(src []byte) (err error) {
_, err = k.G1.Unmarshal(src)
return
}
// SetBytes 从字节串转换为用户加密私钥
func (k *UserEncKey) SetBytes(src []byte) (err error) {
_, err = k.G2.Unmarshal(src)
return
}
// String implements the Stringer interface.
func (k *MastSignPrivateKey) String() string {
return hex.EncodeToString(k.Bytes())
}
// String implements the Stringer interface.
func (k *MastSignPublicKey) String() string {
return hex.EncodeToString(k.Bytes())
}
// String implements the Stringer interface.
func (k *MastEncPrivateKey) String() string {
return hex.EncodeToString(k.Bytes())
}
// String implements the Stringer interface.
func (k *MastEncPublicKey) String() string {
return hex.EncodeToString(k.Bytes())
}
// ComputePairing computes k.e = (g1, Ppubs) if k.e == nil.
// 注意,不要对k主密钥重新赋值,否则这里的预计算值不能更新。
func (k *MastSignPublicKey) ComputePairing() {
if k.e != nil {
return
}
k.e = Pairing(g1Gen, &k.G2)
}
// ComputePairing computes k.e = (Ppube, g2)
// 注意,不要对k主密钥重新赋值,否则这里的预计算值不能更新。
func (k *MastEncPublicKey) ComputePairing() {
if k.e != nil {
return
}
k.e = Pairing(&k.G1, g2Gen)
}
// randOrder returns a number in [1, N-1].
//
// It returns an nil error unless the random number generator r reads 0 bytes and got an error.
func randOrder(r io.Reader) (*big.Int, error) {
b := make([]byte, numBytes)
ret := new(big.Int)
_, err := r.Read(b)
if err != nil {
return nil, errors.ErrGenerateRandomFailed
}
for {
ret.SetBytes(b)
if ret.Sign() > 0 && ret.Cmp(Order()) < 0 {
return ret, nil
}
d := sm3.Sum(b)
b = d[:]
}
}
// GenerateMastSignPrivateKey 生成签名主私钥
func GenerateMastSignPrivateKey(r io.Reader) (*MastSignPrivateKey, *MastSignPublicKey, error) {
ks := &MastSignPrivateKey{}
d, err := randOrder(r)
if err != nil {
return nil, nil, err
}
ks.Int = *d
ks.computePublic()
return ks, ks.public, nil
}
// GenerateMastEncPrivateKey 生成加密主私钥
func GenerateMastEncPrivateKey(r io.Reader) (*MastEncPrivateKey, *MastEncPublicKey, error) {
ke := &MastEncPrivateKey{}
d, err := randOrder(r)
if err != nil {
return nil, nil, err
}
ke.Int = *d
ke.computePublic()
return ke, ke.public, nil
}
// GenerateUserSignKey 生成用户私钥。
//
// 注意: 有极小可能返回error。但一旦返回error,则需要更换主签名密钥以及重新生成所有用户密钥。
// 一般来说,这个概率非常……非常低。但一旦返回error,如果KGC可以改变uid的值(比如uid内的时间等参数)
// 则用新uid重新计算。否则若uid完全由用户提交上来,则必须更换主签名密钥以及重新生成所有用户密钥。
// 因为此时该用户可以根据此uid计算出主私钥。
func GenerateUserSignKey(uid []byte, ks *MastSignPrivateKey) (*UserSignKey, error) {
return ks.GenerateUserSignKey(uid)
}
// GenerateUserEncKey 生成用户加密私钥
//
// 注: 见GenerateUserSignKey说明
func GenerateUserEncKey(uid []byte, ke *MastEncPrivateKey) (*UserEncKey, error) {
return ke.GenerateUserEncKey(uid)
}
func (k *MastSignPrivateKey) computePublic() {
if k.public == nil {
k.public = &MastSignPublicKey{}
}
k.public.G2.ScalarBaseMult(&k.Int)
k.public.ComputePairing()
}
func (k *MastEncPrivateKey) computePublic() {
if k.public == nil {
k.public = &MastEncPublicKey{}
}
k.public.G1.ScalarBaseMult(&k.Int)
k.public.ComputePairing()
}
// GenerateUserSignKey 生成用户私钥。注意如果返回错误ErrKGCRebuildKey,则需要重建主密钥。
//
// k,err:= k.GenerateUserSignKey(uid)
// if err.Is(ErrKGCRebuildKey){...}
//
// - 也可以更改uid中某些项,比如uid如果是ASN.1编码的identity,则可以通过改变时间等参数来重新计算。
// - 如果uid是用户提交的不能更改,则必须重建主密钥,否则用户可以推算出主密钥。
// - 返回ErrKGCRebuildKey错误的几率非常低,以致可以忽略。
func (k *MastSignPrivateKey) GenerateUserSignKey(uid []byte) (*UserSignKey, error) {
t1 := H1(uid, []byte{hidSign})
t1.Add(t1, &k.Int)
t1.Mod(t1, Order())
if gmath.IsBigInt0(t1) {
return nil, errors.ErrKGCRebuildKey
}
t1.ModInverse(t1, Order())
t1.Mul(t1, &k.Int)
t1.Mod(t1, Order())
return &UserSignKey{
*new(G1).ScalarBaseMult(t1),
}, nil
}
// GenerateUserEncKey 生成用户加密私钥
//
// 注: 见GenerateUserSignKey说明
func (k *MastEncPrivateKey) GenerateUserEncKey(uid []byte) (*UserEncKey, error) {
t1 := H1(uid, []byte{hidEncryption})
t1.Add(t1, &k.Int)
t1.Mod(t1, Order())
if gmath.IsBigInt0(t1) {
return nil, errors.ErrKGCRebuildKey
}
t1.ModInverse(t1, Order())
t1.Mul(t1, &k.Int)
t1.Mod(t1, Order())
return &UserEncKey{
*new(G2).ScalarBaseMult(t1),
}, nil
}
// Public 返回主签名公钥
func (k *MastSignPrivateKey) Public() *MastSignPublicKey {
if k.public == nil {
k.computePublic()
}
k.public.ComputePairing()
return k.public
}
// Public 返回主加密公钥
func (k *MastEncPrivateKey) Public() *MastEncPublicKey {
if k.public == nil {
k.computePublic()
}
k.public.ComputePairing()
return k.public
}