init: v1.0.0
This commit is contained in:
@@ -0,0 +1 @@
|
||||
# This package is move to xdx.jelly/gmpki/certless/sm2certless
|
||||
@@ -0,0 +1,40 @@
|
||||
package implicitcert_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"xdx.jelly/xgcl/grand"
|
||||
"xdx.jelly/xgcl/implicitcert"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
func TestKeyGen(t *testing.T) {
|
||||
id := []byte("alice")
|
||||
randReader := grand.Reader
|
||||
|
||||
kgcPrivateKey, kgcPublicKey, _ := sm2.GenerateKeyPairs(randReader)
|
||||
t.Log("kgcPrivateKey:", kgcPrivateKey)
|
||||
t.Log("kgcPublicKey:", kgcPublicKey)
|
||||
userKey := implicitcert.NewUserKey()
|
||||
u, err := userKey.GeneratePartialKey(randReader)
|
||||
if err != nil {
|
||||
t.Log("userKey.GeneratePartialKey failed")
|
||||
t.Fail()
|
||||
}
|
||||
kgcGeneratedUserPartialPrivateKey, declarPublicKey, err := implicitcert.KGCComputeUserKey(id, u, kgcPrivateKey, kgcPublicKey, randReader)
|
||||
if err != nil {
|
||||
t.Log("implicitcert.KGCComputeUserKey failed")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
userPrivateKey, err := userKey.GeneratePrivateKey(kgcGeneratedUserPartialPrivateKey)
|
||||
if err != nil {
|
||||
t.Log("implicitcert.KGCComputeUserKey failed")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
t.Log("userPrivateKey: ", userPrivateKey)
|
||||
t.Log("declarPublicKey: ", declarPublicKey)
|
||||
|
||||
t.Log("VerifyUserKeyPair: ", implicitcert.VerifyUserKeyPair(id, userPrivateKey, declarPublicKey, kgcPublicKey))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package implicitcert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/gmath"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
"xdx.jelly/xgcl/sm/sm2/ec256"
|
||||
"xdx.jelly/xgcl/sm/sm3"
|
||||
)
|
||||
|
||||
var errRandomReader = fmt.Errorf("Random Reader reads error")
|
||||
|
||||
// KGCComputeUserKey compute user's partial private key and declare public key
|
||||
// TODO if r is nil, then w=KDF(H_A‖x_U‖y_U‖ks, 8×⌈(5×(log2n))/32⌉) mod n
|
||||
func KGCComputeUserKey(id []byte,
|
||||
userPartialPublickey *sm2.PublicKey,
|
||||
kgcPrivateKey *sm2.PrivateKey,
|
||||
kgcPublicKey *sm2.PublicKey,
|
||||
r io.Reader) (kgcGeneratedUserPartialPrivateKey *sm2.PrivateKey, kgcGeneratedUserDeclarePublicKey *sm2.PublicKey, err error) {
|
||||
|
||||
h := sm2.PreComputeWithIdAndPubkey(id, kgcPublicKey)
|
||||
w := make([]byte, sm2.ByteSize())
|
||||
if n, err := r.Read(w); n < sm2.ByteSize() || err != nil {
|
||||
return nil, nil, errRandomReader
|
||||
}
|
||||
// x, y := sm2.Curve().CombinedMult(userPartialPublickey.X, userPartialPublickey.Y, w, []byte{1})
|
||||
x, y := ec256.CombinedMult(userPartialPublickey.X, userPartialPublickey.Y, w, []byte{1})
|
||||
|
||||
digest := sm3.Sum(gmath.BigIntToNByte(x, sm2.ByteSize()), gmath.BigIntToNByte(y, sm2.ByteSize()), h)
|
||||
t := new(big.Int)
|
||||
t.SetBytes(digest[:])
|
||||
t.Mul(t, kgcPrivateKey.Get())
|
||||
t.Mod(t, sm2.OrderN())
|
||||
t.Add(t, new(big.Int).SetBytes(w))
|
||||
t.Mod(t, sm2.OrderN())
|
||||
sk := &sm2.PrivateKey{PublicKey: sm2.PublicKey{X: x, Y: y}, D: t}
|
||||
return sk, &sk.PublicKey, nil
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package implicitcert
|
||||
|
||||
/*
|
||||
The Signature genaration and Encryption is the same with the sm2.
|
||||
*/
|
||||
@@ -0,0 +1,86 @@
|
||||
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}
|
||||
}
|
||||
Reference in New Issue
Block a user