Skip to content

Commit 4d06697

Browse files
authored
Merge branch 'master' into master
2 parents 559c3bc + 8e112a5 commit 4d06697

18 files changed

+189
-280
lines changed

e2e/service/MosaicRestrictionTransactionService.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ describe('MosaicRestrictionTransactionService', () => {
7474
UInt64.fromUint(1000),
7575
networkType, helper.maxFee,
7676
);
77-
console.log(mosaicId.toHex());
7877
const signedTransaction = mosaicDefinitionTransaction.signWith(account, generationHash);
7978
return helper.announce(signedTransaction);
8079
});

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@
5959
"dependencies": {
6060
"bluebird": "^3.5.5",
6161
"catbuffer": "0.0.7",
62-
"nem2-sdk-openapi-typescript-node-client": "0.7.20-beta.6",
6362
"crypto-js": "^3.1.9-1",
63+
"futoin-hkdf": "^1.3.1",
6464
"js-joda": "^1.6.2",
6565
"js-sha256": "^0.9.0",
6666
"js-sha3": "^0.8.0",
6767
"long": "^4.0.0",
6868
"merkletreejs": "^0.1.7",
69+
"nem2-sdk-openapi-typescript-node-client": "0.7.20-beta.6",
6970
"request": "^2.88.0",
7071
"request-promise-native": "^1.0.5",
7172
"ripemd160": "^2.0.2",

src/core/crypto/Crypto.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -228,20 +228,19 @@ export class Crypto {
228228
recipientPub: string,
229229
msg: string,
230230
iv: Uint8Array,
231-
salt: Uint8Array,
232231
signSchema: SignSchema): string => {
233232
// Errors
234-
if (!senderPriv || !recipientPub || !msg || !iv || !salt) { throw new Error('Missing argument !'); }
233+
if (!senderPriv || !recipientPub || !msg || !iv) { throw new Error('Missing argument !'); }
235234
// Processing
236235
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(senderPriv, signSchema);
237236
const pk = convert.hexToUint8(recipientPub);
238-
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, signSchema), 32);
237+
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, signSchema), 32);
239238
const encIv = {
240239
iv: utility.ua2words(iv, 16),
241240
};
242241
const encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Hex.parse(msg), encKey, encIv);
243242
// Result
244-
const result = convert.uint8ToHex(salt) + convert.uint8ToHex(iv) + CryptoJS.enc.Hex.stringify(encrypted.ciphertext);
243+
const result = convert.uint8ToHex(iv) + CryptoJS.enc.Hex.stringify(encrypted.ciphertext);
245244
return result;
246245
}
247246

@@ -264,8 +263,7 @@ export class Crypto {
264263
if (!senderPriv || !recipientPub || !msg) { throw new Error('Missing argument !'); }
265264
// Processing
266265
const iv = Crypto.randomBytes(16);
267-
const salt = Crypto.randomBytes(32);
268-
const encoded = Crypto._encode(senderPriv, recipientPub, isHexString ? msg : convert.utf8ToHex(msg), iv, salt, signSchema);
266+
const encoded = Crypto._encode(senderPriv, recipientPub, isHexString ? msg : convert.utf8ToHex(msg), iv, signSchema);
269267
// Result
270268
return encoded;
271269
}
@@ -277,22 +275,20 @@ export class Crypto {
277275
* @param {string} senderPublic - A sender public key
278276
* @param {Uint8Array} payload - An encrypted message payload in bytes
279277
* @param {Uint8Array} iv - 16-byte AES initialization vector
280-
* @param {Uint8Array} salt - 32-byte salt
281278
* @param {SignSchema} signSchema The Sign Schema. (KECCAK(NIS1) / SHA3(Catapult))
282279
* @return {string} - The decoded payload as hex
283280
*/
284281
public static _decode = (recipientPrivate: string,
285282
senderPublic: string,
286283
payload: Uint8Array,
287284
iv: Uint8Array,
288-
salt: Uint8Array,
289285
signSchema: SignSchema): string => {
290286
// Error
291287
if (!recipientPrivate || !senderPublic || !payload) { throw new Error('Missing argument !'); }
292288
// Processing
293289
const keyPair = KeyPair.createKeyPairFromPrivateKeyString(recipientPrivate, signSchema);
294290
const pk = convert.hexToUint8(senderPublic);
295-
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, salt, signSchema), 32);
291+
const encKey = utility.ua2words(KeyPair.deriveSharedKey(keyPair, pk, signSchema), 32);
296292
const encIv = {
297293
iv: utility.ua2words(iv, 16),
298294
};
@@ -321,10 +317,9 @@ export class Crypto {
321317
if (!recipientPrivate || !senderPublic || !payload) { throw new Error('Missing argument !'); }
322318
// Processing
323319
const binPayload = convert.hexToUint8(payload);
324-
const payloadBuffer = new Uint8Array(binPayload.buffer, 48);
325-
const salt = new Uint8Array(binPayload.buffer, 0, 32);
326-
const iv = new Uint8Array(binPayload.buffer, 32, 16);
327-
const decoded = Crypto._decode(recipientPrivate, senderPublic, payloadBuffer, iv, salt, signSchema);
320+
const payloadBuffer = new Uint8Array(binPayload.buffer, 16);
321+
const iv = new Uint8Array(binPayload.buffer, 0, 16);
322+
const decoded = Crypto._decode(recipientPrivate, senderPublic, payloadBuffer, iv, signSchema);
328323
return decoded.toUpperCase();
329324
}
330325

src/core/crypto/KeyPair.ts

Lines changed: 6 additions & 11 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,17 +65,13 @@ 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
*/
73-
public static deriveSharedKey = (keyPair, publicKey: Uint8Array, salt: Uint8Array, signSchema: SignSchema) => {
74-
if (Utility.Key_Size !== salt.length) {
75-
throw Error(`salt has unexpected size: ${salt.length}`);
76-
}
71+
public static deriveSharedKey = (keyPair, publicKey: Uint8Array, signSchema: SignSchema) => {
7772
if (Utility.Key_Size !== publicKey.length) {
78-
throw Error(`public key has unexpected size: ${salt.length}`);
73+
throw Error(`public key has unexpected size: ${publicKey.length}`);
7974
}
80-
return Utility.catapult_crypto.deriveSharedKey(salt, keyPair.privateKey, publicKey, Utility.catapult_hash.func, signSchema);
75+
return Utility.catapult_crypto.deriveSharedKey(keyPair.privateKey, publicKey, Utility.catapult_hash.func, signSchema);
8176
}
8277
}

src/core/crypto/Utilities.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ 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;
2425
export const Half_Signature_Size = Signature_Size / 2;
2526
export const Hash_Size = 64;
2627
export const Half_Hash_Size = Hash_Size / 2;
28+
export const hkdf = require('futoin-hkdf');
2729

2830
/**
2931
* Convert an Uint8Array to WordArray
@@ -68,7 +70,7 @@ export const catapult_hash = {
6870
};
6971

7072
// custom catapult crypto functions
71-
export const catapult_crypto = (function() {
73+
export const catapult_crypto = (() => {
7274
function clamp(d) {
7375
d[0] &= 248;
7476
d[31] &= 127;
@@ -82,7 +84,7 @@ export const catapult_crypto = (function() {
8284
return d;
8385
}
8486

85-
const encodedSChecker = (function() {
87+
const encodedSChecker = (() => {
8688
const Is_Reduced = 1;
8789
const Is_Zero = 2;
8890

@@ -202,25 +204,26 @@ export const catapult_crypto = (function() {
202204
return 0 === c.crypto_verify_32(signature, 0, t, 0);
203205
},
204206

205-
deriveSharedKey: (salt, 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 => {
206215
const c = nacl;
207-
const d = prepareForScalarMult(sk, hashfunc, signSchema);
216+
const d = prepareForScalarMult(privateKey, hashfunc, signSchema);
208217

209-
// sharedKey = pack(p = d (derived from sk) * q (derived from pk))
218+
// sharedKey = pack(p = d (derived from privateKey) * q (derived from publicKey))
210219
const q = [c.gf(), c.gf(), c.gf(), c.gf()];
211220
const p = [c.gf(), c.gf(), c.gf(), c.gf()];
212-
const sharedKey = new Uint8Array(Key_Size);
213-
c.unpack(q, pk);
221+
const sharedSecret = new Uint8Array(Key_Size);
222+
223+
c.unpack(q, publicKey);
214224
c.scalarmult(p, q, d);
215-
c.pack(sharedKey, p);
216-
// salt the shared key
217-
for (let i = 0; i < Key_Size; ++i) {
218-
sharedKey[i] ^= salt[i];
219-
}
220-
// return the hash of the result
221-
const sharedKeyHash = new Uint8Array(Key_Size);
222-
hashfunc(sharedKeyHash, sharedKey, Key_Size, signSchema);
223-
return sharedKeyHash;
225+
c.pack(sharedSecret, p);
226+
return sharedSecret;
224227
},
225228
};
226229
})();

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];

src/model/message/MessageMarker.ts

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

1717
export class MessageMarker {
1818
/**
19-
* 8-byte marker: FE CC 71 C7 64 BF E5 98 for PersistentDelegationRequestTransaction message
19+
* 8-byte marker: FE2A8061577301E2 for PersistentDelegationRequestTransaction message
2020
*/
21-
public static readonly PersistentDelegationUnlock = 'FECC71C764BFE598';
21+
public static readonly PersistentDelegationUnlock = 'FE2A8061577301E2';
2222
}

src/model/message/PersistentHarvestingDelegationMessage.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import {Crypto, SHA3Hasher} from '../../core/crypto';
1818
import { Convert } from '../../core/format/Convert';
19+
import { Account } from '../account/Account';
1920
import { NetworkType } from '../blockchain/NetworkType';
2021
import { Message } from './Message';
2122
import { MessageMarker } from './MessageMarker';
2223
import { MessageType } from './MessageType';
23-
import { PlainMessage } from './PlainMessage';
2424

2525
export class PersistentHarvestingDelegationMessage extends Message {
2626
constructor(payload: string) {
@@ -33,18 +33,17 @@ export class PersistentHarvestingDelegationMessage extends Message {
3333
/**
3434
*
3535
* @param delegatedPrivateKey - Private key of delegated account
36-
* @param senderPrivateKey - Sender private key
3736
* @param recipientPublicKey - Recipient public key
3837
* @param {NetworkType} networkType - Catapult network type
3938
* @return {PersistentHarvestingDelegationMessage}
4039
*/
4140
public static create(delegatedPrivateKey: string,
42-
senderPrivateKey: string,
4341
recipientPublicKey: string,
4442
networkType: NetworkType): PersistentHarvestingDelegationMessage {
4543
const signSchema = SHA3Hasher.resolveSignSchema(networkType);
46-
const encrypted = MessageMarker.PersistentDelegationUnlock +
47-
Crypto.encode(senderPrivateKey, recipientPublicKey, delegatedPrivateKey, signSchema, true).toUpperCase();
44+
const ephemeralKeypair = Account.generateNewAccount(networkType);
45+
const encrypted = MessageMarker.PersistentDelegationUnlock + ephemeralKeypair.publicKey +
46+
Crypto.encode(ephemeralKeypair.privateKey, recipientPublicKey, delegatedPrivateKey, signSchema, true).toUpperCase();
4847
return new PersistentHarvestingDelegationMessage(encrypted);
4948
}
5049

@@ -61,17 +60,17 @@ export class PersistentHarvestingDelegationMessage extends Message {
6160
*
6261
* @param encryptMessage - Encrypted message to be decrypted
6362
* @param privateKey - Recipient private key
64-
* @param senderPublicKey - Sender public key
6563
* @param {NetworkType} networkType - Catapult network type
6664
* @return {string}
6765
*/
6866
public static decrypt(encryptMessage: PersistentHarvestingDelegationMessage,
6967
privateKey: string,
70-
senderPublicKey: string,
7168
networkType: NetworkType): string {
7269
const signSchema = SHA3Hasher.resolveSignSchema(networkType);
73-
const payload = encryptMessage.payload.substring(MessageMarker.PersistentDelegationUnlock.length);
74-
const decrypted = Crypto.decode(privateKey, senderPublicKey, payload, signSchema);
70+
const markerLength = MessageMarker.PersistentDelegationUnlock.length;
71+
const ephemeralPublicKey = encryptMessage.payload.substring(markerLength, markerLength + 64);
72+
const payload = encryptMessage.payload.substring(markerLength + ephemeralPublicKey.length);
73+
const decrypted = Crypto.decode(privateKey, ephemeralPublicKey, payload, signSchema);
7574
return decrypted.toUpperCase();
7675
}
7776
}

src/model/transaction/PersistentDelegationRequestTransaction.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export class PersistentDelegationRequestTransaction extends TransferTransaction
2828
* @param deadline - The deadline to include the transaction.
2929
* @param delegatedPrivateKey - The private key of delegated account
3030
* @param recipientPublicKey - The recipient public key
31-
* @param senderPrivateKey - The sender's private key
3231
* @param networkType - The network type.
3332
* @param maxFee - (Optional) Max fee defined by the sender
3433
* @returns {TransferTransaction}
@@ -37,11 +36,10 @@ export class PersistentDelegationRequestTransaction extends TransferTransaction
3736
deadline: Deadline,
3837
delegatedPrivateKey: string,
3938
recipientPublicKey: string,
40-
senderPrivateKey: string,
4139
networkType: NetworkType,
4240
maxFee: UInt64 = new UInt64([0, 0])): PersistentDelegationRequestTransaction {
4341
const message = PersistentHarvestingDelegationMessage
44-
.create(delegatedPrivateKey, senderPrivateKey, recipientPublicKey, networkType);
42+
.create(delegatedPrivateKey, recipientPublicKey, networkType);
4543
return super.create(deadline, Address.createFromPublicKey(recipientPublicKey, networkType), [], message, networkType, maxFee);
4644
}
4745
}

0 commit comments

Comments
 (0)