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 }