Skip to content

Commit c0bc197

Browse files
committed
Restored core crypto component to use SignSchema rather than NetworkType
1 parent a394495 commit c0bc197

File tree

16 files changed

+173
-162
lines changed

16 files changed

+173
-162
lines changed

src/core/crypto/Crypto.ts

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { NetworkType } from '../../model/blockchain/NetworkType';
1817
import { WalletAlgorithm } from '../../model/wallet/WalletAlgorithm';
1918
import { Convert as convert } from '../format/Convert';
2019
import { KeyPair } from './KeyPair';
@@ -221,16 +220,16 @@ export class Crypto {
221220
* @param {string} msg - A text message
222221
* @param {Uint8Array} iv - An initialization vector
223222
* @param {Uint8Array} salt - A salt
224-
* @param {NetworkType} networkType - Catapult network identifier
223+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
225224
* @return {string} - The encoded message
226225
*/
227-
public static _encode = (senderPriv, recipientPub, msg, iv, salt, networkType: NetworkType) => {
226+
public static _encode = (senderPriv, recipientPub, msg, iv, salt, signSchema: SignSchema) => {
228227
// Errors
229228
if (!senderPriv || !recipientPub || !msg || !iv || !salt) { throw new Error('Missing argument !'); }
230229
// Processing
231-
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(senderPriv, networkType);
230+
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(senderPriv, signSchema);
232231
const pk = convert.hexToUint8(recipientPub);
233-
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, networkType), 32);
232+
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, signSchema), 32);
234233
const encIv = {
235234
iv: utility.ua2words(iv, 16),
236235
};
@@ -246,16 +245,16 @@ export class Crypto {
246245
* @param {string} senderPriv - A sender private key
247246
* @param {string} recipientPub - A recipient public key
248247
* @param {string} msg - A text message
249-
* @param {NetworkType} networkType - Catapult network identifier
248+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
250249
* @return {string} - The encoded message
251250
*/
252-
public static encode = (senderPriv, recipientPub, msg, networkType: NetworkType) => {
251+
public static encode = (senderPriv, recipientPub, msg, signSchema: SignSchema) => {
253252
// Errors
254253
if (!senderPriv || !recipientPub || !msg) { throw new Error('Missing argument !'); }
255254
// Processing
256255
const iv = Crypto.randomBytes(16);
257256
const salt = Crypto.randomBytes(32);
258-
const encoded = Crypto._encode(senderPriv, recipientPub, msg, iv, salt, networkType);
257+
const encoded = Crypto._encode(senderPriv, recipientPub, msg, iv, salt, signSchema);
259258
// Result
260259
return encoded;
261260
}
@@ -266,16 +265,16 @@ export class Crypto {
266265
* @param {string} recipientPrivate - A recipient private key
267266
* @param {string} senderPublic - A sender public key
268267
* @param {Uint8Array} _payload - An encrypted message payload in bytes
269-
* @param {NetworkType} networkType - Catapult network identifier
268+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
270269
* @return {string} - The decoded payload as hex
271270
*/
272-
public static _decode = (recipientPrivate, senderPublic, payload, iv, salt, networkType: NetworkType) => {
271+
public static _decode = (recipientPrivate, senderPublic, payload, iv, salt, signSchema: SignSchema) => {
273272
// Error
274273
if (!recipientPrivate || !senderPublic || !payload) { throw new Error('Missing argument !'); }
275274
// Processing
276-
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(recipientPrivate, networkType);
275+
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(recipientPrivate, signSchema);
277276
const pk = convert.hexToUint8(senderPublic);
278-
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, networkType), 32);
277+
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, signSchema), 32);
279278
const encIv = {
280279
iv: utility.ua2words(iv, 16),
281280
};
@@ -292,19 +291,19 @@ export class Crypto {
292291
*
293292
* @param {string} recipientPrivate - A recipient private key
294293
* @param {string} senderPublic - A sender public key
295-
* @param {string} _payload - An encrypted message payload
296-
* @param {NetworkType} networkType - Catapult network identifier
294+
* @param {string} payload - An encrypted message payload
295+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
297296
* @return {string} - The decoded payload as hex
298297
*/
299-
public static decode = (recipientPrivate, senderPublic, _payload, networkType: NetworkType) => {
298+
public static decode = (recipientPrivate, senderPublic, payload, signSchema: SignSchema) => {
300299
// Error
301-
if (!recipientPrivate || !senderPublic || !_payload) { throw new Error('Missing argument !'); }
300+
if (!recipientPrivate || !senderPublic || !payload) { throw new Error('Missing argument !'); }
302301
// Processing
303-
const binPayload = convert.hexToUint8(_payload);
304-
const payload = new Uint8Array(binPayload.buffer, 48);
302+
const binPayload = convert.hexToUint8(payload);
303+
const payloadBuffer = new Uint8Array(binPayload.buffer, 48);
305304
const salt = new Uint8Array(binPayload.buffer, 0, 32);
306305
const iv = new Uint8Array(binPayload.buffer, 32, 16);
307-
const decoded = Crypto._decode(recipientPrivate, senderPublic, payload, iv, salt, networkType);
306+
const decoded = Crypto._decode(recipientPrivate, senderPublic, payloadBuffer, iv, salt, signSchema);
308307
return decoded;
309308
}
310309

@@ -318,18 +317,4 @@ export class Crypto {
318317
const crypto = require('crypto');
319318
return crypto.randomBytes(length);
320319
}
321-
322-
/**
323-
* Resolve signature schema from given network type
324-
*
325-
* @param {NetworkType} networkType - Network type
326-
*
327-
* @return {SignSchema}
328-
*/
329-
public static resolveNetworkType(networkType: NetworkType): SignSchema {
330-
if (networkType === NetworkType.MAIN_NET || networkType === NetworkType.TEST_NET) {
331-
return SignSchema.KECCAK;
332-
}
333-
return SignSchema.SHA3;
334-
}
335320
}

src/core/crypto/KeyPair.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,22 @@
1515
*/
1616
import { NetworkType } from '../../model/blockchain/NetworkType';
1717
import { Convert as convert } from '../format';
18+
import { SignSchema } from './SignSchema';
1819
import * as Utility from './Utilities';
1920

2021
export class KeyPair {
2122
/**
2223
* Creates a key pair from a private key string.
2324
* @param {string} privateKeyString A hex encoded private key string.
24-
* @param {networkType} networkType Catapult network identifier
25+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
2526
* @returns {module:crypto/keyPair~KeyPair} The key pair.
2627
*/
27-
public static createKeyPairFromPrivateKeyString = (privateKeyString: string, networkType: NetworkType) => {
28+
public static createKeyPairFromPrivateKeyString = (privateKeyString: string, signSchema: SignSchema) => {
2829
const privateKey = convert.hexToUint8(privateKeyString);
2930
if (Utility.Key_Size !== privateKey.length) {
3031
throw Error(`private key has unexpected size: ${privateKey.length}`);
3132
}
32-
const publicKey = Utility.catapult_crypto.extractPublicKey(privateKey, Utility.catapult_hash.func, networkType);
33+
const publicKey = Utility.catapult_crypto.extractPublicKey(privateKey, Utility.catapult_hash.func, signSchema);
3334
return {
3435
privateKey,
3536
publicKey,
@@ -40,24 +41,24 @@ export class KeyPair {
4041
* Signs a data buffer with a key pair.
4142
* @param {module:crypto/keyPair~KeyPair} keyPair The key pair to use for signing.
4243
* @param {Uint8Array} data The data to sign.
43-
* @param {networkType} networkType Catapult network identifier
44+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
4445
* @returns {Uint8Array} The signature.
4546
*/
46-
public static sign = (keyPair, data: Uint8Array, networkType: NetworkType) => {
47+
public static sign = (keyPair, data: Uint8Array, signSchema: SignSchema) => {
4748
return Utility.catapult_crypto.sign(data, keyPair.publicKey, keyPair.privateKey,
48-
Utility.catapult_hash.createHasher(64, networkType));
49+
Utility.catapult_hash.createHasher(64, signSchema));
4950
}
5051

5152
/**
5253
* Verifies a signature.
5354
* @param {module:crypto/keyPair~PublicKey} publicKey The public key to use for verification.
5455
* @param {Uint8Array} data The data to verify.
5556
* @param {Uint8Array} signature The signature to verify.
56-
* @param {networkType} networkType Catapult network identifier
57+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
5758
* @returns {boolean} true if the signature is verifiable, false otherwise.
5859
*/
59-
public static verify = (publicKey, data: Uint8Array, signature: Uint8Array, networkType: NetworkType) => {
60-
return Utility.catapult_crypto.verify(publicKey, data, signature, Utility.catapult_hash.createHasher(64, networkType));
60+
public static verify = (publicKey, data: Uint8Array, signature: Uint8Array, signSchema: SignSchema) => {
61+
return Utility.catapult_crypto.verify(publicKey, data, signature, Utility.catapult_hash.createHasher(64, signSchema));
6162
}
6263

6364
/**
@@ -66,16 +67,16 @@ export class KeyPair {
6667
* @param {module:crypto/keyPair~KeyPair} keyPair The key pair for which to create the shared key.
6768
* @param {Uint8Array} publicKey The public key for which to create the shared key.
6869
* @param {Uint8Array} salt A salt that should be applied to the shared key.
69-
* @param {networkType} networkType Catapult network identifier
70+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
7071
* @returns {Uint8Array} The shared key.
7172
*/
72-
public static deriveSharedKey = (keyPair, publicKey: Uint8Array, salt: Uint8Array, networkType: NetworkType) => {
73+
public static deriveSharedKey = (keyPair, publicKey: Uint8Array, salt: Uint8Array, signSchema: SignSchema) => {
7374
if (Utility.Key_Size !== salt.length) {
7475
throw Error(`salt has unexpected size: ${salt.length}`);
7576
}
7677
if (Utility.Key_Size !== publicKey.length) {
7778
throw Error(`public key has unexpected size: ${salt.length}`);
7879
}
79-
return Utility.catapult_crypto.deriveSharedKey(salt, keyPair.privateKey, publicKey, Utility.catapult_hash.func, networkType);
80+
return Utility.catapult_crypto.deriveSharedKey(salt, keyPair.privateKey, publicKey, Utility.catapult_hash.func, signSchema);
8081
}
8182
}

src/core/crypto/SHA3Hasher.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import { keccak256, keccak512, sha3_256, sha3_512 } from 'js-sha3';
1818
import { NetworkType } from '../../model/blockchain/NetworkType';
1919
import { Convert as convert, RawArray as array } from '../format';
20-
import { Crypto } from './Crypto';
2120
import { SignSchema } from './SignSchema';
2221

2322
export class SHA3Hasher {
@@ -26,25 +25,25 @@ export class SHA3Hasher {
2625
* @param {Uint8Array} dest The computed hash destination.
2726
* @param {Uint8Array} data The data to hash.
2827
* @param {numeric} length The hash length in bytes.
29-
* @param {NetworkType} networkType Catapult network identifier
28+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
3029
*/
31-
public static func = (dest, data, length, networkType: NetworkType) => {
32-
const hasher = SHA3Hasher.getHasher(length, networkType);
30+
public static func = (dest, data, length, signSchema: SignSchema) => {
31+
const hasher = SHA3Hasher.getHasher(length, signSchema);
3332
const hash = hasher.arrayBuffer(data);
3433
array.copy(dest, array.uint8View(hash));
3534
}
3635

3736
/**
3837
* Creates a hasher object.
3938
* @param {numeric} length The hash length in bytes.
40-
* @param {NetworkType} networkType Catapult network identifier
39+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
4140
* @returns {object} The hasher.
4241
*/
43-
public static createHasher = (length = 64, networkType: NetworkType) => {
42+
public static createHasher = (length = 64, signSchema: SignSchema) => {
4443
let hash;
4544
return {
4645
reset: () => {
47-
hash = SHA3Hasher.getHasher(length, networkType).create();
46+
hash = SHA3Hasher.getHasher(length, signSchema).create();
4847
},
4948
update: (data: any) => {
5049
if (data instanceof Uint8Array) {
@@ -64,11 +63,10 @@ export class SHA3Hasher {
6463
/**
6564
* Get a hasher instance.
6665
* @param {numeric} length The hash length in bytes.
67-
* @param {NetworkType} networkType Catapult network identifier
66+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
6867
* @returns {object} The hasher.
6968
*/
70-
public static getHasher = (length = 64, networkType: NetworkType) => {
71-
const signSchema = Crypto.resolveNetworkType(networkType);
69+
public static getHasher = (length = 64, signSchema: SignSchema) => {
7270
return {
7371
32: signSchema === SignSchema.SHA3 ? sha3_256 : keccak256,
7472
64: signSchema === SignSchema.SHA3 ? sha3_512 : keccak512 ,
@@ -78,11 +76,24 @@ export class SHA3Hasher {
7876
/**
7977
* Create a hasher instance with given payload bytes and return hash array buffer.
8078
* @param {Uint8Array} payload Payload in bytes.
81-
* @param {NetworkType} networkType Catapult network identifier
79+
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
8280
* @returns {ArrayBuffer}
8381
*/
84-
public static getHashArrayBuffer(payload: Uint8Array, networkType: NetworkType): ArrayBuffer {
85-
const signSchema = Crypto.resolveNetworkType(networkType);
82+
public static getHashArrayBuffer(payload: Uint8Array, signSchema: SignSchema): ArrayBuffer {
8683
return signSchema === SignSchema.SHA3 ? sha3_256.arrayBuffer(payload) : keccak256.arrayBuffer(payload);
8784
}
85+
86+
/**
87+
* Resolve signature schema from given network type
88+
*
89+
* @param {NetworkType} networkType - Network type
90+
*
91+
* @return {SignSchema}
92+
*/
93+
public static resolveSignSchema(networkType: NetworkType): SignSchema {
94+
if (networkType === NetworkType.MAIN_NET || networkType === NetworkType.TEST_NET) {
95+
return SignSchema.KECCAK;
96+
}
97+
return SignSchema.SHA3;
98+
}
8899
}

src/core/crypto/Utilities.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { NetworkType } from '../../model/blockchain/NetworkType';
16+
1717
import { RawArray as array } from '../format';
1818
import * as nacl from './nacl_catapult';
1919
import { SHA3Hasher as sha3Hasher } from './SHA3Hasher';
20+
import { SignSchema } from './SignSchema';
2021
export const CryptoJS = require('crypto-js');
2122
export const Key_Size = 32;
2223
export const Signature_Size = 64;
@@ -74,9 +75,9 @@ export const catapult_crypto = (function() {
7475
d[31] |= 64;
7576
}
7677

77-
function prepareForScalarMult(sk, hashfunc, networkType: NetworkType) {
78+
function prepareForScalarMult(sk, hashfunc, signSchema: SignSchema) {
7879
const d = new Uint8Array(Hash_Size);
79-
hashfunc(d, sk, Hash_Size, networkType);
80+
hashfunc(d, sk, Hash_Size, signSchema);
8081
clamp(d);
8182
return d;
8283
}
@@ -108,9 +109,9 @@ export const catapult_crypto = (function() {
108109
})();
109110

110111
return {
111-
extractPublicKey: (sk, hashfunc, networkType: NetworkType) => {
112+
extractPublicKey: (sk, hashfunc, signSchema: SignSchema) => {
112113
const c = nacl;
113-
const d = prepareForScalarMult(sk, hashfunc, networkType);
114+
const d = prepareForScalarMult(sk, hashfunc, signSchema);
114115

115116
const p = [c.gf(), c.gf(), c.gf(), c.gf()];
116117
const pk = new Uint8Array(Key_Size);
@@ -201,9 +202,9 @@ export const catapult_crypto = (function() {
201202
return 0 === c.crypto_verify_32(signature, 0, t, 0);
202203
},
203204

204-
deriveSharedKey: (salt, sk, pk, hashfunc, networkType: NetworkType) => {
205+
deriveSharedKey: (salt, sk, pk, hashfunc, signSchema: SignSchema) => {
205206
const c = nacl;
206-
const d = prepareForScalarMult(sk, hashfunc, networkType);
207+
const d = prepareForScalarMult(sk, hashfunc, signSchema);
207208

208209
// sharedKey = pack(p = d (derived from sk) * q (derived from pk))
209210
const q = [c.gf(), c.gf(), c.gf(), c.gf()];
@@ -218,7 +219,7 @@ export const catapult_crypto = (function() {
218219
}
219220
// return the hash of the result
220221
const sharedKeyHash = new Uint8Array(Key_Size);
221-
hashfunc(sharedKeyHash, sharedKey, Key_Size, networkType);
222+
hashfunc(sharedKeyHash, sharedKey, Key_Size, signSchema);
222223
return sharedKeyHash;
223224
},
224225
};

src/core/crypto/nacl_catapult.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,11 @@ export const cleanup = (arr) => {
672672
}
673673
};
674674

675-
export const crypto_shared_key_hash = (shared, pk, sk, hashfunc, networkType) => {
675+
export const crypto_shared_key_hash = (shared, pk, sk, hashfunc, signSchema) => {
676676
const d = new Uint8Array(64);
677677
const p = [gf(), gf(), gf(), gf()];
678678

679-
hashfunc(d, sk, 32, networkType);
679+
hashfunc(d, sk, 32, signSchema);
680680
d[0] &= 248;
681681
d[31] &= 127;
682682
d[31] |= 64;

src/core/format/RawAddress.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { keccak256, sha3_256 } from 'js-sha3';
1818
import RIPEMD160 = require('ripemd160');
19-
import { Crypto, SignSchema} from '../crypto';
19+
import { SignSchema} from '../crypto';
2020
import { SHA3Hasher } from '../crypto/SHA3Hasher';
2121
import { Base32 } from './Base32';
2222
import { Convert } from './Convert';
@@ -81,7 +81,7 @@ export class RawAddress {
8181
public static publicKeyToAddress = (publicKey: Uint8Array,
8282
networkIdentifier: number): Uint8Array => {
8383
// step 1: sha3 hash of the public key
84-
const signSchema = Crypto.resolveNetworkType(networkIdentifier);
84+
const signSchema = SHA3Hasher.resolveSignSchema(networkIdentifier);
8585
const publicKeyHash = signSchema === SignSchema.SHA3 ? sha3_256.arrayBuffer(publicKey) : keccak256.arrayBuffer(publicKey);
8686

8787
// step 2: ripemd160 hash of (1)
@@ -110,7 +110,7 @@ export class RawAddress {
110110
* @returns {boolean} true if the decoded address is valid, false otherwise.
111111
*/
112112
public static isValidAddress = (decoded: Uint8Array, networkIdentifier: number): boolean => {
113-
const signSchema = Crypto.resolveNetworkType(networkIdentifier);
113+
const signSchema = SHA3Hasher.resolveSignSchema(networkIdentifier);
114114
const hash = signSchema === SignSchema.SHA3 ? sha3_256.create() : keccak256.create();
115115
const checksumBegin = RawAddress.constants.sizes.addressDecoded - RawAddress.constants.sizes.checksum;
116116
hash.update(decoded.subarray(0, checksumBegin));

0 commit comments

Comments
 (0)