Skip to content

Commit 50b4ae9

Browse files
committed
BCCSP hash.Hash support
This change-set introduces support for hash.Hash at the BCCSP level. The BCCSP will now return instances of hash.Hash to allow streaming hashing. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: I78611c6ae90c58d7ac6c00d2c44eb8c3d5cf4d73 Signed-off-by: Angelo De Caro <[email protected]>
1 parent 742443e commit 50b4ae9

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

core/crypto/bccsp/bccsp.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ limitations under the License.
1616

1717
package bccsp
1818

19-
import "crypto"
19+
import (
20+
"crypto"
21+
"hash"
22+
)
2023

2124
// Key represents a cryptographic key
2225
type Key interface {
@@ -114,8 +117,13 @@ type BCCSP interface {
114117
GetKey(ski []byte) (k Key, err error)
115118

116119
// Hash hashes messages msg using options opts.
120+
// If opts is nil, the default hash function will be used.
117121
Hash(msg []byte, opts HashOpts) (hash []byte, err error)
118122

123+
// GetHash returns and instance of hash.Hash using options opts.
124+
// If opts is nil, the default hash function will be returned.
125+
GetHash(opts HashOpts) (h hash.Hash, err error)
126+
119127
// Sign signs digest using key k.
120128
// The opts argument should be appropriate for the algorithm used.
121129
//

core/crypto/bccsp/bccsp_opts.go

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const (
4545

4646
// X509Certificate Label for X509 certificate realted operation
4747
X509Certificate = "X509Certificate"
48+
49+
// DefaultHash is the identifier for the default hash function (see primitives package)
50+
DefaultHash = "DEFAULT_HASH"
4851
)
4952

5053
// ECDSAKeyGenOpts contains options for ECDSA key generation.

core/crypto/bccsp/sw/impl.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626

2727
"crypto/rsa"
2828

29+
"hash"
30+
2931
"github.com/hyperledger/fabric/core/crypto/bccsp"
3032
"github.com/hyperledger/fabric/core/crypto/primitives"
3133
"github.com/hyperledger/fabric/core/crypto/utils"
@@ -463,17 +465,32 @@ func (csp *impl) GetKey(ski []byte) (k bccsp.Key, err error) {
463465
// Hash hashes messages msg using options opts.
464466
func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (hash []byte, err error) {
465467
if opts == nil {
466-
return nil, errors.New("Invalid Opts parameter. It must not be nil.")
468+
return primitives.Hash(msg), nil
467469
}
468470

469471
switch opts.Algorithm() {
470-
case bccsp.SHA:
472+
case bccsp.DefaultHash, bccsp.SHA:
471473
return primitives.Hash(msg), nil
472474
default:
473475
return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
474476
}
475477
}
476478

479+
// GetHash returns and instance of hash.Hash using options opts.
480+
// If opts is nil then the default hash function is returned.
481+
func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) {
482+
if opts == nil {
483+
return primitives.NewHash(), nil
484+
}
485+
486+
switch opts.Algorithm() {
487+
case bccsp.SHA, bccsp.DefaultHash:
488+
return primitives.NewHash(), nil
489+
default:
490+
return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
491+
}
492+
}
493+
477494
// Sign signs digest using key k.
478495
// The opts argument should be appropriate for the primitive used.
479496
//

core/crypto/bccsp/sw/impl_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -1245,3 +1245,49 @@ func TestKeyImportFromX509RSAPublicKey(t *testing.T) {
12451245
t.Fatal("Failed verifying RSA signature. Signature not valid.")
12461246
}
12471247
}
1248+
1249+
func TestGetHashAndHashCompatibility(t *testing.T) {
1250+
csp := getBCCSP(t)
1251+
1252+
msg1 := []byte("abcd")
1253+
msg2 := []byte("efgh")
1254+
msg := []byte("abcdefgh")
1255+
1256+
digest1, err := csp.Hash(msg, &bccsp.SHAOpts{})
1257+
if err != nil {
1258+
t.Fatalf("Failed computing HASH [%s]", err)
1259+
}
1260+
1261+
digest2, err := csp.Hash(msg, nil)
1262+
if err != nil {
1263+
t.Fatalf("Failed computing HASH [%s]", err)
1264+
}
1265+
1266+
if !bytes.Equal(digest1, digest2) {
1267+
t.Fatalf("Different hash computed. [%x][%x]", digest1, digest2)
1268+
}
1269+
1270+
h, err := csp.GetHash(nil)
1271+
if err != nil {
1272+
t.Fatalf("Failed getting hash.Hash instance [%s]", err)
1273+
}
1274+
h.Write(msg1)
1275+
h.Write(msg2)
1276+
digest3 := h.Sum(nil)
1277+
1278+
h2, err := csp.GetHash(&bccsp.SHAOpts{})
1279+
if err != nil {
1280+
t.Fatalf("Failed getting SHA hash.Hash instance [%s]", err)
1281+
}
1282+
h2.Write(msg1)
1283+
h2.Write(msg2)
1284+
digest4 := h2.Sum(nil)
1285+
1286+
if !bytes.Equal(digest3, digest4) {
1287+
t.Fatalf("Different hash computed. [%x][%x]", digest3, digest4)
1288+
}
1289+
1290+
if !bytes.Equal(digest1, digest3) {
1291+
t.Fatalf("Different hash computed. [%x][%x]", digest1, digest3)
1292+
}
1293+
}

0 commit comments

Comments
 (0)