Skip to content

Commit

Permalink
[FAB-8791] Optimize hash primitive and CryptoSuite impl
Browse files Browse the repository at this point in the history
- move base class of hash algo in hash.js to api.js
- Allign hash algo -> size pair to pattern like `${algo.toUpperCase}_${outputSize}`
- pkcs11: fix invalid 'pkcs11Slot' like '2.1'
- modify verification logic in cryptoSuite constructor

**NOT MERGE, some modifications not included yet:
 - typeScript interface of hash algo
 - move 'hash' parameter in construtor of CryptoSuite
    to 'opts.algorithm' in cryptoSuite.hash(msg,opts)

Change-Id: Icedb13f0a7b846e0734f3b5bc078bbf1601f7316
Signed-off-by: davidliu <[email protected]>
  • Loading branch information
davidkhala committed May 14, 2018
1 parent e55f817 commit ca90c97
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 485 deletions.
20 changes: 16 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
# Contributions Welcome!

This repository is part of the Fabric project.
Please consult [Fabric's CONTRIBUTING documentation](http://hyperledger-fabric.readthedocs.io/en/latest/CONTRIBUTING.html) for information on how to contribute to this repository.

<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
s
Please consult [Fabric's CONTRIBUTING documentation](http://hyperledger-fabric.readthedocs.io/en/latest/CONTRIBUTING.html) as the basis on how to contribute to this repository.

## To code contributors

The following check-list is for code contributors to make sure their changesets are compliant to the coding standards and avoid time wasted in rejected changesets:

Check the coding styles, run the following command and make sure no ESLint violations are present:
* `gulp`

Run the full unit test bucket and make sure 100% are passing. Because v1.0 is still in active development, all tests may not pass. You can run each individually to isolate the failure(s):
* `gulp test`

The gulp test command above also generates code coverage reports. Your new code should be accompanied with unit tests and provide 80% line coverage or higher.

<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
s
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,6 @@ The unit test assumes slot '0' and user PIN `98765432`. If your configuration is
* PKCS11_PIN
* PKCS11_SLOT

### Contributor Check-list
The following check-list is for code contributors to make sure their changesets are compliant to the coding standards and avoid time wasted in rejected changesets:

Check the coding styles, run the following command and make sure no ESLint violations are present:
* `gulp`

Run the full unit test bucket and make sure 100% are passing. Because v1.0 is still in active development, all tests may not pass. You can run each individually to isolate the failure(s):
* `gulp test`

The gulp test command above also generates code coverage reports. Your new code should be accompanied with unit tests and provide 80% line coverage or higher.

### Hyperledger Fabric Client objects and reference documentation
For a high-level design specificiation for Fabric SDKs of all languages, visit [this google doc](https://docs.google.com/document/d/1R5RtIBMW9fZpli37E5Li5_Q9ve3BnQ4q3gWmGZj6Sv4/edit?usp=sharing) (Work-In-Progress).

Expand All @@ -118,5 +107,9 @@ HFC defines the following abstract classes for application developers to supply

3. If the user application uses an alternative membership service than the one provided by the component `fabric-ca`, the client code will likely need to use an alternative client to `fabric-ca-client` to interact with that membership service.

### Contributing

Check [the documentation](./CONTRIBUTING.md) on how to contribute to this project for the full details.

<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
s
2 changes: 1 addition & 1 deletion fabric-client/lib/BaseClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var BaseClient = class {
*
* <br><br><code>cryptosuite.setCryptoKeyStore(Client.newCryptoKeyStore(KVSImplClass, opts))</code>
*
* @param {function} KVSImplClass Optional. The built-in key store saves private keys. The key store may be backed by different
* @param {api.KeyValueStore} KVSImplClass Optional. The built-in key store saves private keys. The key store may be backed by different
* {@link KeyValueStore} implementations. If specified, the value of the argument must point to a module implementing the
* KeyValueStore interface.
* @param {Object} opts Implementation-specific option object used in the constructor
Expand Down
4 changes: 1 addition & 3 deletions fabric-client/lib/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,7 @@ var Client = class extends BaseClient {
* @returns {Peer} The Peer instance.
*/
newPeer(url, opts) {
let peer = new Peer(url, opts);

return peer;
return new Peer(url, opts);
}

/**
Expand Down
54 changes: 27 additions & 27 deletions fabric-client/lib/TransactionID.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

'use strict';

var sdkUtils = require('./utils.js');
var logger = sdkUtils.getLogger('TransactionID.js');
var User = require('./User.js');
var hashPrimitives = require('./hash.js');
const sdkUtils = require('./utils.js');
const logger = sdkUtils.getLogger('TransactionID.js');
const User = require('./User.js');
const hashPrimitives = require('./hash.js');


/**
Expand All @@ -20,61 +20,61 @@ var hashPrimitives = require('./hash.js');
*
* @class
*/
var TransactionID = class {
class TransactionID {

/**
* Builds a new tranaction Id based on a user's certificate and an automatically
* generates a nonce value.
* @param {Identity} signer_or_userContext - An instance of {@link Identity} that provides an unique
* base for this transaction id. This also may be an instance of a {@User}.
* @param {boolean} admin - Indicates that this instance will be used for administrative transactions.
*/
* Builds a new transaction Id based on a user's certificate and an automatically
* generates a nonce value.
* @param {Identity} signer_or_userContext - An instance of {@link Identity} that provides an unique
* base for this transaction id. This also may be an instance of a {@User}.
* @param {boolean} admin - Indicates that this instance will be used for administrative transactions.
*/
constructor(signer_or_userContext, admin) {
logger.debug('const - start');
if (typeof signer_or_userContext === 'undefined' || signer_or_userContext === null) {
logger.debug('constructor - start');
if (!signer_or_userContext) {
throw new Error('Missing userContext or signing identity parameter');
}
var signer = null;
if((User.isInstance(signer_or_userContext))) {
let signer = null;
if ((User.isInstance(signer_or_userContext))) {
signer = signer_or_userContext.getSigningIdentity();
} else {
signer = signer_or_userContext;
}

this._nonce = sdkUtils.getNonce(); //nonce is in bytes
let creator_bytes = signer.serialize();//same as signatureHeader.Creator
let trans_bytes = Buffer.concat([this._nonce, creator_bytes]);
let trans_hash = hashPrimitives.sha2_256(trans_bytes);
const creator_bytes = signer.serialize();//same as signatureHeader.Creator
const trans_bytes = Buffer.concat([this._nonce, creator_bytes]);
const trans_hash = hashPrimitives.SHA2_256(trans_bytes);
this._transaction_id = Buffer.from(trans_hash).toString();
logger.debug('const - transaction_id %s',this._transaction_id);
logger.debug('const - transaction_id %s', this._transaction_id);

this._admin = admin;
}

/**
* The transaction ID
*/
* The transaction ID
*/
getTransactionID() {
return this._transaction_id;
}

/**
* The nonce value
*/
* The nonce value
*/
getNonce() {
return this._nonce;
}

/**
* indicates if this transactionID was generated for an admin
*/
* indicates if this transactionID was generated for an admin
*/
isAdmin() {
if(this._admin) {
if (this._admin) {
return true;
} else {
return false;
}
}
};
}

module.exports = TransactionID;
31 changes: 31 additions & 0 deletions fabric-client/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ module.exports.CryptoAlgorithms = {
SHA256: 'SHA256',
// SHA384
SHA384: 'SHA384',
// SHA256
SHA2_256: 'SHA256',
// SHA384
SHA2_384: 'SHA384',
// SHA3_256
SHA3_256: 'SHA3_256',
// SHA3_384
Expand All @@ -278,3 +282,30 @@ module.exports.CryptoAlgorithms = {
// X509Certificate Label for X509 certificate related operation
X509Certificate: 'X509Certificate'
};

/**
* Base class for hash primitives.
* @type {Hash}
*/
module.exports.Hash = class {
constructor(blockSize) {
this._blockSize = blockSize;
this.reset();
}

hash(data) {
return this.reset().update(data).finalize();
}

reset() {
return this;
}

update(data) {
this._hash.update(data);
return this;
}

finalize() {
}
};
60 changes: 27 additions & 33 deletions fabric-client/lib/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,91 +8,85 @@
/**
* Implement hash primitives.
*/
const logger = require('./utils').getLogger('hash');
const jsSHA3 = require('js-sha3');
const { sha3_256, sha3_384, shake_256 } = jsSHA3;
const {sha3_256, sha3_384, shake_256} = jsSHA3;
const crypto = require('crypto');
const {Hash} = require('./api');

class hashBaseClass {
class hash_sha2_256 extends Hash {
constructor() {
this.reset();
super(512);
}

hash(data) {
return this.reset().update(data).finalize();
}
reset() {
return this;
this._hash = crypto.createHash('sha256');
return super.reset();
}
update(data) {
//logger.debug(`update(${typeof data})`);
this._hash.update(data);
return this;
}
finalize() {
}
}
class hash_sha2_256 extends hashBaseClass {
constructor() {
super();
this.blockSize = 512;
}
reset() {
this._hash = crypto.createHash('sha256');
return super.reset();
}
finalize() {
const hash = this._hash.digest('hex');
this.reset();
return hash;
}
}
class hash_sha2_384 extends hashBaseClass {

class hash_sha2_384 extends Hash {
constructor() {
super();
this.blockSize = 1024;
super(1024);
}

reset() {
this._hash = crypto.createHash('sha384');
return super.reset();
}

finalize() {
const hash = this._hash.digest('hex');
this.reset();
return hash;
}
}
class hash_sha3_256 extends hashBaseClass {

class hash_sha3_256 extends Hash {
static hashSimple(data) {
return sha3_256(data);
}

constructor() {
super();
this.blockSize = 1088;
super(1088);
}

reset() {
this._hash = sha3_256.create();
return super.reset();
}

finalize() {
const hash = this._hash.hex();
this.reset();
return hash;
}

}
class hash_sha3_384 extends hashBaseClass {

class hash_sha3_384 extends Hash {
static hashSimple(data) {
return sha3_384(data);
}

constructor() {
super();
this.blockSize = 832;
super(832);
}

reset() {
this._hash = sha3_384.create();
return super.reset();
}

finalize() {
const hash = this._hash.hex();
this.reset();
Expand All @@ -104,12 +98,12 @@ exports.hash_sha3_256 = hash_sha3_256;
exports.hash_sha3_384 = hash_sha3_384;
exports.hash_sha2_256 = hash_sha2_256;
exports.hash_sha2_384 = hash_sha2_384;
exports.sha2_256 = (data) => {
exports.SHA2_256 = (data) => {
return (new hash_sha2_256()).hash(data);
};
exports.sha3_256 = sha3_256;
exports.sha2_384 = (data) => {
exports.SHA3_256 = sha3_256;
exports.SHA2_384 = (data) => {
return (new hash_sha2_384()).hash(data);
};
exports.sha3_384 = sha3_384;
exports.SHA3_384 = sha3_384;
exports.shake_256 = shake_256;//TODO
Loading

0 comments on commit ca90c97

Please sign in to comment.