117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package sm2m
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"math/big"
|
||
|
||
"xdx.jelly/xgcl/gerrors"
|
||
"xdx.jelly/xgcl/gmath"
|
||
"xdx.jelly/xgcl/grand"
|
||
"xdx.jelly/xgcl/sm/sm2"
|
||
)
|
||
|
||
/*
|
||
服务端和用户端的秘钥生成
|
||
秘钥关系式: (1 + d)^(-1)= d1 * d2
|
||
|
||
签名(加密)秘钥双方生成流程
|
||
a0 客户端初始化context
|
||
a1 客户端(), 向服务端发送数据。
|
||
|
||
b1 服务端结收数据计算并发回数据()
|
||
|
||
a2 客户端接收数据并计算,输出签名
|
||
a3 客户端清理context
|
||
*/
|
||
|
||
// clientKey = d1
|
||
// clientTempPublicKey = [d1^(-1)]*G
|
||
func ClientGenSignKey_one(rnd any) (clientKey *sm2.PrivateKey, clientTempPublicKey *sm2.PublicKey, err error) {
|
||
if rnd == nil {
|
||
rnd = grand.Reader
|
||
}
|
||
switch rnd := rnd.(type) {
|
||
case io.Reader:
|
||
clientKey, err := sm2.GenerateKey(sm2.Curve(), rnd)
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
clientTempPublicKey := &clientKey.PublicKey
|
||
clientKey.D.ModInverse(clientKey.D, sm2.OrderN())
|
||
return clientKey, clientTempPublicKey, nil
|
||
case []byte:
|
||
if rnd == nil || len(rnd) < 32 {
|
||
return nil, nil, gerrors.WithAnnotating(ErrInvalidInput, "input rnd must be as 32 bytes")
|
||
}
|
||
clientKey = sm2.NewPrivateKey()
|
||
_ = clientKey.SetBytes(rnd)
|
||
clientTempPublicKey = sm2.GenPublicKey(clientKey)
|
||
clientKey.D.ModInverse(clientKey.D, sm2.OrderN())
|
||
err = nil
|
||
return
|
||
default:
|
||
return nil, nil, errors.New("parameter rnd can only be nil, io.Reader or []byte (with length >= 32)")
|
||
}
|
||
}
|
||
|
||
/*
|
||
serverkey = d2 in [1, n - 1],
|
||
publicKey = [d2^(-1)]clientTempPublicKey - G,用户签名公钥P
|
||
serverTempPublicKey = [d2^(-1)]G,
|
||
*/
|
||
func ServerGenSignKey(clientTempPublicKey *sm2.PublicKey, rnd []byte) (
|
||
serverKey *sm2.PrivateKey,
|
||
serverTempPublicKey *sm2.PublicKey,
|
||
publicKey *sm2.PublicKey,
|
||
err error) {
|
||
|
||
if rnd == nil || len(rnd) < 32 {
|
||
return nil, nil, nil, gerrors.WithAnnotating(ErrInvalidInput, "input rnd must be as 32 bytes")
|
||
}
|
||
|
||
serverKey = sm2.NewPrivateKey()
|
||
_ = serverKey.SetBytes(rnd)
|
||
|
||
serverTempPublicKey = sm2.GenPublicKey(serverKey)
|
||
x, y := sm2.Curve256.ScalarMult(clientTempPublicKey.X, clientTempPublicKey.Y, serverKey.D.Bytes())
|
||
y.Sub(sm2.Curve().Params().P, y)
|
||
x, y = sm2.Curve().Add(x, y, sm2.Curve().Params().Gx, sm2.Curve().Params().Gy)
|
||
y.Sub(sm2.Curve().Params().P, y)
|
||
publicKey = &sm2.PublicKey{X: x, Y: y}
|
||
serverKey.D.ModInverse(serverKey.D, sm2.OrderN())
|
||
err = nil
|
||
return
|
||
}
|
||
|
||
// ClientGenSignKey_two 客户端对服务端发送来的公钥publicKey和根据clientKey,serverTempPublicKey计算出来的公钥比较。
|
||
// 若两者一致,则秘钥生成成功。
|
||
func ClientGenSignKey_two(clientKey *sm2.PrivateKey, serverTempPublicKey *sm2.PublicKey, publicKey *sm2.PublicKey) error {
|
||
|
||
d1Inv := new(big.Int).ModInverse(clientKey.D, sm2.OrderN())
|
||
x, y := sm2.Curve256.ScalarMult(serverTempPublicKey.X, serverTempPublicKey.Y, d1Inv.Bytes())
|
||
y.Sub(sm2.Curve().Params().P, y)
|
||
x, y = sm2.Curve().Add(x, y, sm2.Curve().Params().Gx, sm2.Curve().Params().Gy)
|
||
y.Sub(sm2.Curve().Params().P, y)
|
||
|
||
if x.Cmp(publicKey.X) != 0 || y.Cmp(publicKey.Y) != 0 {
|
||
return fmt.Errorf("generate key failed")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// realPrivateKey compute the real private key, for test
|
||
func realPrivateKey(clientKey, serverKey *sm2.PrivateKey) *sm2.PrivateKey {
|
||
|
||
d := new(big.Int).Mul(serverKey.D, clientKey.D)
|
||
d.ModInverse(d, sm2.OrderN())
|
||
d.Sub(d, gmath.BigInt1)
|
||
sk := &sm2.PrivateKey{
|
||
D: d,
|
||
}
|
||
sm2.GenPublicKey(sk)
|
||
return sk
|
||
}
|