Files
xgcl/tpc/sm2/sm2m/outsource/os_authkey.go
T
2026-05-27 23:03:00 +08:00

55 lines
1.7 KiB
Go

package outsource
import (
"crypto/rand"
"errors"
"io"
"math/big"
"xdx.jelly/xgcl/gerrors"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/he/paillier"
"xdx.jelly/xgcl/sm/sm2"
)
/*
============================= 生成授权密钥 ===============================
客户端 服务端
---------------------------request-------------------------->
Enc(pailliar, dc'),
虎符服务端公钥pk加密R: Enc(SM4GCM, k, R), Enc(SM2, pk, k)
<------------------------------------------------------------
解密dc'
组合授权包
*/
// OSGenerateAuthKey 外包服务根据用户的授权密钥密文生成授权密钥密文,以及给虎符服务端的授权因子R
// R由外包服务加密. (注,不能把R明文发给用户, 否则用户可以还原出自己的授权密钥)
func OSGenerateAuthKey(encryptedKey *paillier.Cipher, evalKey *paillier.PublicKey, rnd io.Reader) (*paillier.Cipher, []byte, error) {
var r *big.Int
var err error
for r == nil || gmath.IsBigInt0(r) {
r, err = rand.Int(rnd, sm2.OrderN())
if err != nil {
return nil, nil, errors.New("generate random number failed")
}
}
c := (&paillier.Cipher{}).HomomorphicScalarMul(encryptedKey, r, evalKey)
rBytes := make([]byte, sm2.ByteSize())
r.FillBytes(rBytes)
return c, rBytes, nil
}
// ClientDecryptAuthKey 客户端解密授权密钥密文, 小程序中实现.
func ClientDecryptAuthKey(encryptedAuthKey *paillier.Cipher, decKey *paillier.PrivateKey) (*sm2.PrivateKey, error) {
d, err := decKey.Decrypt(encryptedAuthKey)
if err != nil {
return nil, gerrors.WithAnnotating(err, "ClientDecryptAuthKey decrypt failed")
}
d.Mod(d, sm2.OrderN())
return (&sm2.PrivateKey{}).SetBigInt(d), nil
}