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 }