Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release2.2 add gm bccsp show demo #12

Open
wants to merge 1 commit into
base: bccsp-gm
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bccsp/idemix/handlers/revocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"crypto/x509"
"github.com/Hyperledger-TWGC/ccs-gm/x509"
"encoding/pem"
"fmt"
"reflect"
Expand Down
114 changes: 114 additions & 0 deletions bccsp/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ const (
// ECDSAReRand ECDSA key re-randomization
ECDSAReRand = "ECDSA_RERAND"

SM2 = "SM2"
SM3 = "SM3"
// This is used for indicating hashopts while doing sm3 before sm2 signature
// through which hash will actually do nothing
SM3SIG = "SM3SIG"
// SM2ReRand SM2 key re-randomization
SM2ReRand = "SM2"

// AES Advanced Encryption Standard at the default security level.
// Each BCCSP may or may not support default security level. If not supported than
// an error will be returned.
Expand Down Expand Up @@ -264,3 +272,109 @@ func (opts *X509PublicKeyImportOpts) Algorithm() string {
func (opts *X509PublicKeyImportOpts) Ephemeral() bool {
return opts.Temporary
}

// SM2ReRandKeyOpts contains options for SM2 key re-randomization.
type SM2ReRandKeyOpts struct {
Temporary bool
Expansion []byte
}

// Algorithm returns the key derivation algorithm identifier (to be used).
func (opts *SM2ReRandKeyOpts) Algorithm() string {
return SM2ReRand
}

// Ephemeral returns true if the key to generate has to be ephemeral,
// false otherwise.
func (opts *SM2ReRandKeyOpts) Ephemeral() bool {
return opts.Temporary
}

// ExpansionValue returns the re-randomization factor
func (opts *SM2ReRandKeyOpts) ExpansionValue() []byte {
return opts.Expansion
}


// SHA256Opts contains options relating to SHA-256.
type SM3Opts struct {
}

// Algorithm returns the hash algorithm identifier (to be used).
func (opts *SM3Opts) Algorithm() string {
return SM3
}

// SHA256Opts contains options relating to SHA-256.
type SM3SIGOpts struct {
}

// Algorithm returns the hash algorithm identifier (to be used).
func (opts *SM3SIGOpts) Algorithm() string {
return SM3SIG
}

// SM2KeyGenOpts contains options for SM2 key generation.
type SM2KeyGenOpts struct {
Temporary bool
}

// Algorithm returns the key generation algorithm identifier (to be used).
func (opts *SM2KeyGenOpts) Algorithm() string {
return SM2
}

// Ephemeral returns true if the key to generate has to be ephemeral,
// false otherwise.
func (opts *SM2KeyGenOpts) Ephemeral() bool {
return opts.Temporary
}

// SM2PKIXPublicKeyImportOpts contains options for SM2 public key importation in PKIX format
type SM2PKIXPublicKeyImportOpts struct {
Temporary bool
}

// Algorithm returns the key importation algorithm identifier (to be used).
func (opts *SM2PKIXPublicKeyImportOpts) Algorithm() string {
return SM2
}

// Ephemeral returns true if the key to generate has to be ephemeral,
// false otherwise.
func (opts *SM2PKIXPublicKeyImportOpts) Ephemeral() bool {
return opts.Temporary
}

// SM2PrivateKeyImportOpts contains options for SM2 secret key importation in DER format
// or PKCS#8 format.
type SM2PrivateKeyImportOpts struct {
Temporary bool
}

// Algorithm returns the key importation algorithm identifier (to be used).
func (opts *SM2PrivateKeyImportOpts) Algorithm() string {
return SM2
}

// Ephemeral returns true if the key to generate has to be ephemeral,
// false otherwise.
func (opts *SM2PrivateKeyImportOpts) Ephemeral() bool {
return opts.Temporary
}

// SM2GoPublicKeyImportOpts contains options for SM2 key importation from ecdsa.PublicKey
type SM2GoPublicKeyImportOpts struct {
Temporary bool
}

// Algorithm returns the key importation algorithm identifier (to be used).
func (opts *SM2GoPublicKeyImportOpts) Algorithm() string {
return SM2
}

// Ephemeral returns true if the key to generate has to be ephemeral,
// false otherwise.
func (opts *SM2GoPublicKeyImportOpts) Ephemeral() bool {
return opts.Temporary
}
3 changes: 2 additions & 1 deletion bccsp/signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ package signer

import (
"crypto"
"crypto/x509"
//"crypto/x509"
"github.com/Hyperledger-TWGC/ccs-gm/x509"
"io"

"github.com/hyperledger/fabric/bccsp"
Expand Down
19 changes: 19 additions & 0 deletions bccsp/sw/fileks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package sw
import (
"bytes"
"crypto/ecdsa"
"github.com/Hyperledger-TWGC/ccs-gm/sm2"
"encoding/hex"
"errors"
"fmt"
Expand Down Expand Up @@ -142,6 +143,8 @@ func (ks *fileBasedKeyStore) GetKey(ski []byte) (bccsp.Key, error) {
switch k := key.(type) {
case *ecdsa.PrivateKey:
return &ecdsaPrivateKey{k}, nil
case *sm2.PrivateKey:
return &sm2PrivateKey{key.(*sm2.PrivateKey)}, nil
default:
return nil, errors.New("secret key type not recognized")
}
Expand All @@ -155,6 +158,8 @@ func (ks *fileBasedKeyStore) GetKey(ski []byte) (bccsp.Key, error) {
switch k := key.(type) {
case *ecdsa.PublicKey:
return &ecdsaPublicKey{k}, nil
case *sm2.PublicKey:
return &sm2PublicKey{key.(*sm2.PublicKey)}, nil
default:
return nil, errors.New("public key type not recognized")
}
Expand Down Expand Up @@ -192,6 +197,18 @@ func (ks *fileBasedKeyStore) StoreKey(k bccsp.Key) (err error) {
return fmt.Errorf("failed storing AES key [%s]", err)
}

case *sm2PrivateKey:
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing SM2 private key [%s]", err)
}

case *sm2PublicKey:
err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
if err != nil {
return fmt.Errorf("Failed storing SM2 public key [%s]", err)
}

default:
return fmt.Errorf("key type not reconigned [%s]", k)
}
Expand Down Expand Up @@ -224,6 +241,8 @@ func (ks *fileBasedKeyStore) searchKeystoreForSKI(ski []byte) (k bccsp.Key, err
switch kk := key.(type) {
case *ecdsa.PrivateKey:
k = &ecdsaPrivateKey{kk}
case *sm2.PrivateKey:
k = &sm2PrivateKey{key.(*sm2.PrivateKey)}
default:
continue
}
Expand Down
96 changes: 96 additions & 0 deletions bccsp/sw/keyderiv.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/hmac"
"errors"
"fmt"
"github.com/Hyperledger-TWGC/ccs-gm/sm2"
"math/big"

"github.com/hyperledger/fabric/bccsp"
Expand Down Expand Up @@ -148,3 +149,98 @@ func (kd *aesPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts
return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
}
}

type sm2PublicKeyKeyDeriver struct{}

func (kd *sm2PublicKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (bccsp.Key, error) {
// Validate opts
if opts == nil {
return nil, errors.New("Invalid opts parameter. It must not be nil.")
}

sm2K := k.(*sm2PublicKey)

switch opts.(type) {
// Re-randomized an SM2 public key
case *bccsp.SM2ReRandKeyOpts:
reRandOpts := opts.(*bccsp.SM2ReRandKeyOpts)
tempSK := &sm2.PublicKey{
Curve: sm2K.pubKey.Curve,
X: new(big.Int),
Y: new(big.Int),
}

var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
var one = new(big.Int).SetInt64(1)
n := new(big.Int).Sub(sm2K.pubKey.Params().N, one)
k.Mod(k, n)
k.Add(k, one)

// Compute temporary public key
tempX, tempY := sm2K.pubKey.ScalarBaseMult(k.Bytes())
tempSK.X, tempSK.Y = tempSK.Add(
sm2K.pubKey.X, sm2K.pubKey.Y,
tempX, tempY,
)

// Verify temporary public key is a valid point on the reference curve
isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y)
if !isOn {
return nil, errors.New("Failed temporary public key IsOnCurve check.")
}
return &sm2PublicKey{tempSK}, nil
default:
return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
}
}

type sm2PrivateKeyKeyDeriver struct{}

func (kd *sm2PrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (bccsp.Key, error) {
// Validate opts
if opts == nil {
return nil, errors.New("Invalid opts parameter. It must not be nil.")
}

sm2K := k.(*sm2PrivateKey)

switch opts.(type) {
// Re-randomized an ECDSA private key
case *bccsp.SM2ReRandKeyOpts:
reRandOpts := opts.(*bccsp.SM2ReRandKeyOpts)
tempSK := &sm2.PrivateKey{
PublicKey: sm2.PublicKey{
Curve: sm2K.privKey.Curve,
X: new(big.Int),
Y: new(big.Int),
},
D: new(big.Int),
}

var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
var one = new(big.Int).SetInt64(1)
n := new(big.Int).Sub(sm2K.privKey.Params().N, one)
k.Mod(k, n)
k.Add(k, one)

tempSK.D.Add(sm2K.privKey.D, k)
tempSK.D.Mod(tempSK.D, sm2K.privKey.PublicKey.Params().N)

// Compute temporary public key
tempX, tempY := sm2K.privKey.PublicKey.ScalarBaseMult(k.Bytes())
tempSK.PublicKey.X, tempSK.PublicKey.Y =
tempSK.PublicKey.Add(
sm2K.privKey.PublicKey.X, sm2K.privKey.PublicKey.Y,
tempX, tempY,
)

// Verify temporary public key is a valid point on the reference curve
isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y)
if !isOn {
return nil, errors.New("Failed temporary public key IsOnCurve check.")
}
return &sm2PrivateKey{tempSK}, nil
default:
return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
}
}
14 changes: 14 additions & 0 deletions bccsp/sw/keygen.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/elliptic"
"crypto/rand"
"fmt"
"github.com/Hyperledger-TWGC/ccs-gm/sm2"

"github.com/hyperledger/fabric/bccsp"
)
Expand Down Expand Up @@ -50,3 +51,16 @@ func (kg *aesKeyGenerator) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) {

return &aesPrivateKey{lowLevelKey, false}, nil
}

type sm2KeyGenerator struct {
curve elliptic.Curve
}

func (kg *sm2KeyGenerator) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) {
privKey, err := sm2.GenerateKey(rand.Reader)
if err != nil {
return nil, fmt.Errorf("Failed generating sm2 key : [%s]", err)
}

return &sm2PrivateKey{privKey}, nil
}
Loading