87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package implicitcert
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"math/big"
|
|
|
|
"xdx.jelly/xgcl/sm/sm2"
|
|
"xdx.jelly/xgcl/sm/sm3"
|
|
)
|
|
|
|
var (
|
|
ErrClientGenerateAgreementData = fmt.Errorf("client GenerateAgreementData error")
|
|
errZeroPrivateKey = fmt.Errorf("private key got zero")
|
|
)
|
|
|
|
type UserKey struct {
|
|
d *sm2.PrivateKey // user's private key
|
|
// w sm2.PublicKey // declare public key
|
|
}
|
|
|
|
func NewUserKey() *UserKey {
|
|
return &UserKey{}
|
|
}
|
|
|
|
// GeneratePartialKey generate UserKey.d and partial public key U.
|
|
// Then user should send ID and U to kgc.
|
|
// The Input r should be a random number Reader.
|
|
// r could use grand.Reader, or a wrapper of random generator from hard ware.
|
|
// If want pass in a b of []byte slice, use grand.NewReaderFromBytes(b) to turn b to a
|
|
// Reader:
|
|
// b := []byte{...}
|
|
// pk,err := u.GeneratePartialKey(grand.NewReaderFromBytes(b))
|
|
func (uk *UserKey) GeneratePartialKey(r io.Reader) (*sm2.PublicKey, error) {
|
|
rnd := make([]byte, sm2.ByteSize())
|
|
_, err := r.Read(rnd)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
uk.d, _ = sm2.GenPrivateKey(rnd)
|
|
u := sm2.GenPublicKey(uk.d)
|
|
return u, nil
|
|
}
|
|
|
|
// GeneratePrivateKey generate user's privatekey and the declare public key
|
|
// t - KGC generated partial private key for user
|
|
func (uk *UserKey) GeneratePrivateKey(kgcGeneratedUserPartialPrivateKey *sm2.PrivateKey) (userPrivateKey *sm2.PrivateKey, err error) {
|
|
d := new(big.Int)
|
|
d.Add(uk.d.D, kgcGeneratedUserPartialPrivateKey.D)
|
|
ret := d.Cmp(sm2.OrderN())
|
|
if ret == 0 {
|
|
return nil, errZeroPrivateKey
|
|
}
|
|
if ret > 0 {
|
|
d.Sub(d, sm2.OrderN())
|
|
}
|
|
|
|
return &sm2.PrivateKey{D: d}, nil
|
|
|
|
}
|
|
|
|
// VerifyUserKeyPair verify the private key and declare public key are correct
|
|
func VerifyUserKeyPair(
|
|
id []byte,
|
|
userPrivateKey *sm2.PrivateKey,
|
|
userDeclarePublicKey *sm2.PublicKey,
|
|
kgcPublicKey *sm2.PublicKey) bool {
|
|
|
|
return sm2.VerifyKeyPair(userPrivateKey, RestoreUserPublicKey(id, userDeclarePublicKey, kgcPublicKey))
|
|
}
|
|
|
|
// RestoreUserPublicKey restore user's public key from id, kgc's public key and user's
|
|
// declare public key
|
|
func RestoreUserPublicKey(
|
|
id []byte,
|
|
userDeclarePublicKey *sm2.PublicKey,
|
|
kgcPublicKey *sm2.PublicKey) *sm2.PublicKey {
|
|
|
|
h := sm2.PreComputeWithIdAndPubkey(id, kgcPublicKey)
|
|
lambda := sm3.Sum(userDeclarePublicKey.Bytes(), h)
|
|
|
|
x1, y1 := sm2.Curve().ScalarMult(kgcPublicKey.X, kgcPublicKey.Y, lambda[:])
|
|
x1, y1 = sm2.Curve().Add(x1, y1, userDeclarePublicKey.X, userDeclarePublicKey.Y)
|
|
|
|
return &sm2.PublicKey{X: x1, Y: y1}
|
|
}
|