Skip to content

Commit c5809b6

Browse files
committed
Improve docs
Improved test vector assertions Improved some types
1 parent 24df29c commit c5809b6

File tree

5 files changed

+67
-31
lines changed

5 files changed

+67
-31
lines changed

src/core/crypto/KeyPair.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { NetworkType } from '../../model/blockchain/NetworkType';
1716
import { Convert as convert } from '../format';
1817
import { SignSchema } from './SignSchema';
1918
import * as Utility from './Utilities';
@@ -44,20 +43,20 @@ export class KeyPair {
4443
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
4544
* @returns {Uint8Array} The signature.
4645
*/
47-
public static sign = (keyPair, data: Uint8Array, signSchema: SignSchema) => {
46+
public static sign = (keyPair, data: Uint8Array, signSchema: SignSchema): Uint8Array => {
4847
return Utility.catapult_crypto.sign(data, keyPair.publicKey, keyPair.privateKey,
4948
Utility.catapult_hash.createHasher(64, signSchema));
5049
}
5150

5251
/**
5352
* Verifies a signature.
54-
* @param {module:crypto/keyPair~PublicKey} publicKey The public key to use for verification.
53+
* @param {Uint8Array} publicKey The public key to use for verification.
5554
* @param {Uint8Array} data The data to verify.
5655
* @param {Uint8Array} signature The signature to verify.
5756
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
5857
* @returns {boolean} true if the signature is verifiable, false otherwise.
5958
*/
60-
public static verify = (publicKey, data: Uint8Array, signature: Uint8Array, signSchema: SignSchema) => {
59+
public static verify = (publicKey: Uint8Array, data: Uint8Array, signature: Uint8Array, signSchema: SignSchema): boolean => {
6160
return Utility.catapult_crypto.verify(publicKey, data, signature, Utility.catapult_hash.createHasher(64, signSchema));
6261
}
6362

@@ -66,7 +65,6 @@ export class KeyPair {
6665
* The shared key can be used for encrypted message passing between the two.
6766
* @param {module:crypto/keyPair~KeyPair} keyPair The key pair for which to create the shared key.
6867
* @param {Uint8Array} publicKey The public key for which to create the shared key.
69-
* @param {Uint8Array} salt A salt that should be applied to the shared key.
7068
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
7169
* @returns {Uint8Array} The shared key.
7270
*/

src/core/crypto/Utilities.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { RawArray as array } from '../format';
1818
import * as nacl from './nacl_catapult';
1919
import { SHA3Hasher as sha3Hasher } from './SHA3Hasher';
2020
import { SignSchema } from './SignSchema';
21+
2122
export const CryptoJS = require('crypto-js');
2223
export const Key_Size = 32;
2324
export const Signature_Size = 64;
@@ -203,21 +204,26 @@ export const catapult_crypto = (() => {
203204
return 0 === c.crypto_verify_32(signature, 0, t, 0);
204205
},
205206

206-
deriveSharedKey: (sk, pk, hashfunc, signSchema: SignSchema) => {
207+
deriveSharedKey: (privateKey: Uint8Array, publicKey: Uint8Array, hashfunc, signSchema: SignSchema): Uint8Array => {
208+
const sharedSecret = catapult_crypto.deriveSharedSecret(privateKey, publicKey, hashfunc, signSchema);
209+
const info = 'catapult';
210+
const hash = 'SHA-256';
211+
return hkdf(sharedSecret, 32, {salt: new Uint8Array(32), info, hash});
212+
},
213+
214+
deriveSharedSecret: (privateKey: Uint8Array, publicKey: Uint8Array, hashfunc, signSchema: SignSchema): Uint8Array => {
207215
const c = nacl;
208-
const d = prepareForScalarMult(sk, hashfunc, signSchema);
216+
const d = prepareForScalarMult(privateKey, hashfunc, signSchema);
209217

210-
// sharedKey = pack(p = d (derived from sk) * q (derived from pk))
218+
// sharedKey = pack(p = d (derived from privateKey) * q (derived from publicKey))
211219
const q = [c.gf(), c.gf(), c.gf(), c.gf()];
212220
const p = [c.gf(), c.gf(), c.gf(), c.gf()];
213221
const sharedSecret = new Uint8Array(Key_Size);
214-
c.unpack(q, pk);
222+
223+
c.unpack(q, publicKey);
215224
c.scalarmult(p, q, d);
216225
c.pack(sharedSecret, p);
217-
const info = 'catapult';
218-
const hash = 'SHA-256';
219-
const sharedKey = hkdf(sharedSecret, 32, {salt: new Uint8Array(32), info, hash});
220-
return sharedKey;
226+
return sharedSecret;
221227
},
222228
};
223229
})();

src/core/format/Convert.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Convert {
8686
* @param {Uint8Array} input A uint8 array.
8787
* @returns {string} A hex encoded string corresponding to the input.
8888
*/
89-
public static uint8ToHex = (input) => {
89+
public static uint8ToHex = (input): string => {
9090
let s = '';
9191
for (const byte of input) {
9292
s += utilities.Nibble_To_Char_Map[byte >> 4];

test/core/crypto/hkdf.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2020 NEM
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { expect } from 'chai';
17+
import { Convert } from '../../../src/core/format';
18+
19+
const hkdf = require('futoin-hkdf');
20+
21+
describe('hkdf', () => {
22+
describe('Example tests', () => {
23+
// This test is used to validate that values are the same in both java and ts implementation.
24+
const sharedSecret = 'string-or-buffer';
25+
const hash = 'SHA-256';
26+
const info = 'catapult';
27+
const sharedKey = hkdf(sharedSecret, 32, {salt: new Uint8Array(32), info, hash});
28+
expect(Convert.uint8ToHex(sharedKey)).equal('E618ACB2558E1721492E4AE3BED3F4D86F26C2B0CE6AD939943A6A540855D23F');
29+
});
30+
});

test/core/crypto/keyPair.spec.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import {expect} from 'chai';
17-
import {Crypto, KeyPair, SHA3Hasher, SignSchema} from '../../../src/core/crypto';
16+
import { expect } from 'chai';
17+
import { Crypto, KeyPair, SHA3Hasher, SignSchema } from '../../../src/core/crypto';
18+
import * as Utility from '../../../src/core/crypto/Utilities';
1819
import { Convert } from '../../../src/core/format/Convert';
1920
import { NetworkType } from '../../../src/model/blockchain/NetworkType';
20-
import { Address } from '../../../src/model/account/Address';
2121

2222
describe('key pair', () => {
2323
const randomKeyPair = () =>
@@ -605,12 +605,12 @@ describe('key pair', () => {
605605
'63ABC887EAD7B80247244E0C58CB7689C313444F4924278DBEA72DDB3391F9DA',
606606
];
607607

608-
const Nis1_Salt = [
609-
'422c39df16aae42a74a5597d6ee2d59cfb4eeb6b3f26d98425b9163a03daa3b5',
610-
'ad63ac08f9afc85eb0bf4f8881ca6eaa0215924c87aa2f137d56109bb76c6f98',
611-
'96104f0a28f9cca40901c066cd435134662a3b053eb6c8df80ee0d05dc941963',
612-
'd8f94a0bbb1de80aea17aab42e2ffb982e73fc49b649a318479e951e392d8728',
613-
'3f8c969678a8abdbfb76866a142c284a6f01636c1c1607947436e0d2c30d5245',
608+
const Expected_ScalarMulResult = [
609+
'FEB242779628761122E9FB1718512025040C683D69B8105BA1F383D47578B29F',
610+
'277FD55F1A54F57F3E5B408CACA560360BA75F67AB954FB4E27A7ADBCAAB6719',
611+
'8B38A30824E322555A748A5BEB67FBE0E0F1BD2B51635549F1F19CDF76BA0E9A',
612+
'9342380F112C70B17B7254EFCD3FCF6F4F1FF844C7790426BF6EDC4C800BD0A0',
613+
'A5593308E182D6D86D633F18DF19D87FAA4EF447FD1904891600CEEF303FD591',
614614
];
615615

616616
const Expected_Derived_Key = [
@@ -629,10 +629,11 @@ describe('key pair', () => {
629629

630630
// Act:
631631
const sharedKey = Convert.uint8ToHex(KeyPair.deriveSharedKey(keyPair, publicKey, nis1TestSignSchema));
632+
const sharedSecret = Convert.uint8ToHex(Utility.catapult_crypto.deriveSharedSecret(keyPair.privateKey, publicKey, Utility.catapult_hash.func, nis1TestSignSchema));
632633

633634
// Assert:
634-
const message = ` from ${Nis1_Private_Key[i]}`;
635635
expect(sharedKey.toUpperCase()).to.deep.equal(Expected_Derived_Key[i].toUpperCase());
636+
expect(sharedSecret.toUpperCase()).to.deep.equal(Expected_ScalarMulResult[i].toUpperCase());
636637
}
637638
});
638639
});
@@ -660,12 +661,12 @@ describe('key pair', () => {
660661
'9896A394B035E0F18855B2F6EE934E20ABADBF6B65B26E0C9329C283C1A9F980',
661662
];
662663

663-
const Salt = [
664-
'422c39df16aae42a74a5597d6ee2d59cfb4eeb6b3f26d98425b9163a03daa3b5',
665-
'ad63ac08f9afc85eb0bf4f8881ca6eaa0215924c87aa2f137d56109bb76c6f98',
666-
'96104f0a28f9cca40901c066cd435134662a3b053eb6c8df80ee0d05dc941963',
667-
'd8f94a0bbb1de80aea17aab42e2ffb982e73fc49b649a318479e951e392d8728',
668-
'3f8c969678a8abdbfb76866a142c284a6f01636c1c1607947436e0d2c30d5245',
664+
const Expected_ScalarMulResult = [
665+
'4118C2B3058714A288A9E218B7E0F9CCAD74C2EC44884CABBE20A2A33DB1282F',
666+
'DA4BFF3709E40B4299988806435819D3E8E90ADE435EAC086EE295E0ADC3E0BB',
667+
'81B15312FA6A87285C883FF205BA7E7DB319DEA1E7A79D1F78B93E73A156AA64',
668+
'100221B07AB55C3260A7B7F12CDA0A8FA97998664C6509661A2E51417AF9C998',
669+
'EE74B025E7A304BD0D3F131EF1132D2C194568034B9A7DE93653327D6618215C',
669670
];
670671

671672
const Expected_Derived_Key = [
@@ -683,10 +684,11 @@ describe('key pair', () => {
683684

684685
// Act:
685686
const sharedKey = Convert.uint8ToHex(KeyPair.deriveSharedKey(keyPair, publicKey, mijinTestSignSchema));
687+
const sharedSecret = Convert.uint8ToHex(Utility.catapult_crypto.deriveSharedSecret(keyPair.privateKey, publicKey, Utility.catapult_hash.func, mijinTestSignSchema));
686688

687689
// Assert:
688-
const message = ` from ${Private_Key[i]}`;
689690
expect(sharedKey.toUpperCase()).to.deep.equal(Expected_Derived_Key[i].toUpperCase());
691+
expect(sharedSecret.toUpperCase()).to.deep.equal(Expected_ScalarMulResult[i].toUpperCase());
690692
}
691693
});
692694
});

0 commit comments

Comments
 (0)