Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Remove passphrase handling from cryptography - Closes #7291, #6864,#7332 #7364

Merged
merged 4 commits into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion commander/src/bootstrapping/commands/account/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface AccountInfo {

const createAccount = (prefix: string): AccountInfo => {
const generatedPassphrase = passphrase.Mnemonic.generateMnemonic();
const { privateKey, publicKey } = cryptography.ed.getKeys(generatedPassphrase);
const { privateKey, publicKey } = cryptography.legacy.getKeys(generatedPassphrase);
const blsPrivateKey = cryptography.bls.generatePrivateKey(
Buffer.from(generatedPassphrase, 'utf-8'),
);
Expand Down
3 changes: 2 additions & 1 deletion commander/src/bootstrapping/commands/forging/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ export class ConfigCommand extends Command {
const hashOnion = { count, distance, hashes };

const passphrase = passphraseSource ?? (await getPassphraseFromPrompt('passphrase', true));
const address = cryptography.address.getAddressFromPassphrase(passphrase).toString('hex');
const { publicKey } = cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
const address = cryptography.address.getAddressFromPublicKey(publicKey).toString('hex');
const password = passwordSource ?? (await getPasswordFromPrompt('password', true));
const { encryptedPassphrase } = await encryptPassphrase(passphrase, password, false);
const message = { address, encryptedPassphrase, hashOnion };
Expand Down
22 changes: 17 additions & 5 deletions commander/src/bootstrapping/commands/transaction/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
ModuleMetadataJSON,
} from 'lisk-framework';
import { PromiseResolvedType } from '../../../types';
import { deriveKeypair } from '../../../utils/commons';
import { DEFAULT_KEY_DERIVATION_PATH } from '../../../utils/config';
import { flagsWithParser } from '../../../utils/flags';
import { getDefaultPath } from '../../../utils/path';
import { getParamsFromPrompt, getPassphraseFromPrompt, getFileParams } from '../../../utils/reader';
Expand Down Expand Up @@ -57,6 +59,7 @@ interface CreateFlags {
'sender-public-key'?: string;
nonce?: string;
file?: string;
'key-derivation-path': string;
}

interface Transaction {
Expand Down Expand Up @@ -98,20 +101,21 @@ const getPassphraseAddressAndPublicKey = async (flags: CreateFlags) => {
passphrase = '';
} else {
passphrase = flags.passphrase ?? (await getPassphraseFromPrompt('passphrase', true));
const result = cryptography.address.getAddressAndPublicKeyFromPassphrase(passphrase);
publicKey = result.publicKey;
address = result.address;
const keys = cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
publicKey = keys.publicKey;
address = cryptography.address.getAddressFromPublicKey(publicKey);
}

return { address, passphrase, publicKey };
};

const validateAndSignTransaction = (
const validateAndSignTransaction = async (
transaction: Transaction,
schema: RegisteredSchema,
metadata: ModuleMetadataJSON[],
networkIdentifier: string,
passphrase: string,
keyDerivationPath: string,
noSignature: boolean,
) => {
const { params, ...transactionWithoutParams } = transaction;
Expand All @@ -132,10 +136,11 @@ const validateAndSignTransaction = (
};

if (!noSignature) {
const { privateKey } = await deriveKeypair(passphrase, keyDerivationPath);
return transactions.signTransaction(
decodedTx,
Buffer.from(networkIdentifier, 'hex'),
passphrase,
privateKey,
paramsSchema,
);
}
Expand All @@ -161,6 +166,7 @@ const createTransactionOffline = async (
metadata,
flags['network-identifier'] as string,
passphrase,
flags['key-derivation-path'],
flags['no-signature'],
);
};
Expand Down Expand Up @@ -202,6 +208,7 @@ const createTransactionOnline = async (
metadata,
nodeInfo.networkIdentifier,
passphrase,
flags['key-derivation-path'],
flags['no-signature'],
);
};
Expand Down Expand Up @@ -265,6 +272,11 @@ export abstract class CreateCommand extends Command {
'Creates the transaction with provided sender publickey, when passphrase is not provided',
}),
'data-path': flagsWithParser.dataPath,
'key-derivation-path': flagParser.string({
default: DEFAULT_KEY_DERIVATION_PATH,
description: 'Key derivation path to use to derive keypair from passphrase',
char: 'k',
}),
pretty: flagsWithParser.pretty,
file: flagsWithParser.file,
};
Expand Down
17 changes: 14 additions & 3 deletions commander/src/bootstrapping/commands/transaction/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
import { getDefaultPath } from '../../../utils/path';
import { isApplicationRunning } from '../../../utils/application';
import { PromiseResolvedType } from '../../../types';
import { DEFAULT_KEY_DERIVATION_PATH } from '../../../utils/config';
import { deriveKeypair } from '../../../utils/commons';

interface AuthAccount {
nonce: string;
Expand All @@ -61,6 +63,7 @@ interface SignFlags {
'sender-public-key': string | undefined;
'mandatory-keys': string[];
'optional-keys': string[];
'key-derivation-path': string;
}

const signTransaction = async (
Expand Down Expand Up @@ -92,20 +95,22 @@ const signTransaction = async (
params: paramsObject,
};

const edKeys = cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);

// sign from multi sig account offline using input keys
if (!flags['include-sender'] && !flags['sender-public-key']) {
return transactions.signTransaction(
decodedTx,
networkIdentifierBuffer,
passphrase,
edKeys.privateKey,
paramsSchema,
);
}

return transactions.signMultiSignatureTransaction(
decodedTx,
networkIdentifierBuffer,
passphrase,
edKeys.privateKey,
keys,
paramsSchema,
flags['include-sender'],
Expand Down Expand Up @@ -165,7 +170,8 @@ const signTransactionOnline = async (
// Sign non multi-sig transaction
const transactionObject = decodeTransaction(registeredSchema, metadata, transactionHexStr);
const passphrase = flags.passphrase ?? (await getPassphraseFromPrompt('passphrase', true));
const address = cryptography.address.getAddressFromPassphrase(passphrase);
const edKeys = await deriveKeypair(passphrase, flags['key-derivation-path']);
const address = cryptography.address.getAddressFromPublicKey(edKeys.publicKey);

let signedTransaction: Record<string, unknown>;

Expand Down Expand Up @@ -231,6 +237,11 @@ export abstract class SignCommand extends Command {
'network-identifier': flagsWithParser.networkIdentifier,
'sender-public-key': flagsWithParser.senderPublicKey,
'data-path': flagsWithParser.dataPath,
'key-derivation-path': flagParser.string({
default: DEFAULT_KEY_DERIVATION_PATH,
description: 'Key derivation path to use to derive keypair from passphrase',
char: 'k',
}),
pretty: flagsWithParser.pretty,
};

Expand Down
8 changes: 5 additions & 3 deletions commander/src/commands/message/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Removal or modification of this copyright notice is prohibited.
*
*/
import { encrypt } from '@liskhq/lisk-cryptography';
import { encrypt, legacy } from '@liskhq/lisk-cryptography';
import { flags as flagParser } from '@oclif/command';

import BaseCommand from '../../base';
Expand All @@ -37,10 +37,12 @@ const processInputs = (
throw new ValidationError('No message was provided.');
}

return encrypt.decryptMessageWithPassphrase(
const keys = legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);

return encrypt.decryptMessageWithPrivateKey(
message,
nonce,
passphrase,
keys.privateKey,
Buffer.from(senderPublicKey, 'hex'),
);
};
Expand Down
7 changes: 4 additions & 3 deletions commander/src/commands/message/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Removal or modification of this copyright notice is prohibited.
*
*/
import { encrypt } from '@liskhq/lisk-cryptography';
import { encrypt, legacy } from '@liskhq/lisk-cryptography';
import { flags as flagParser } from '@oclif/command';

import BaseCommand from '../../base';
Expand All @@ -30,11 +30,12 @@ const processInputs = (recipientPublicKey: string, passphrase: string, message?:
if (!message) {
throw new ValidationError('No message was provided.');
}
const keys = legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);

return {
...encrypt.encryptMessageWithPassphrase(
...encrypt.encryptMessageWithPrivateKey(
message,
passphrase,
keys.privateKey,
Buffer.from(recipientPublicKey, 'hex'),
),
recipientPublicKey,
Expand Down
5 changes: 3 additions & 2 deletions commander/src/commands/message/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Removal or modification of this copyright notice is prohibited.
*
*/
import { ed } from '@liskhq/lisk-cryptography';
import { ed, legacy } from '@liskhq/lisk-cryptography';
import { flags as flagParser } from '@oclif/command';

import BaseCommand from '../../base';
Expand All @@ -30,7 +30,8 @@ const processInputs = (passphrase: string, message?: string) => {
throw new ValidationError('No message was provided.');
}

const signedMessageWithOnePassphrase = ed.signMessageWithPassphrase(message, passphrase);
const keys = legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
const signedMessageWithOnePassphrase = ed.signMessageWithPrivateKey(message, keys.privateKey);
return {
...signedMessageWithOnePassphrase,
publicKey: signedMessageWithOnePassphrase.publicKey.toString('hex'),
Expand Down
17 changes: 16 additions & 1 deletion commander/src/utils/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,22 @@ export const encryptPassphrase = async (
return outputPublicKey
? {
encryptedPassphrase,
publicKey: cryptography.ed.getKeys(passphrase).publicKey.toString('hex'),
publicKey: cryptography.legacy.getKeys(passphrase).publicKey.toString('hex'),
}
: { encryptedPassphrase };
};

export const deriveKeypair = async (passphrase: string, keyDerivationPath: string) => {
if (keyDerivationPath === 'legacy') {
return cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
}
const privateKey = await cryptography.ed.getKeyPairFromPhraseAndPath(
passphrase,
keyDerivationPath,
);
const publicKey = cryptography.ed.getPublicKeyFromPrivateKey(privateKey);
return {
publicKey,
privateKey,
};
};
2 changes: 2 additions & 0 deletions commander/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ export const defaultConfig = {
},
plugins: {},
};

export const DEFAULT_KEY_DERIVATION_PATH = "m/25519'/134'/0'/0'";
6 changes: 3 additions & 3 deletions commander/src/utils/genesis_creation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { Mnemonic } from '@liskhq/lisk-passphrase';
import { Schema } from '@liskhq/lisk-codec';
import { bls, address, utils, ed } from '@liskhq/lisk-cryptography';
import { bls, address, utils, legacy } from '@liskhq/lisk-cryptography';
import {
dposGenesisStoreSchema,
DPoSModule,
Expand Down Expand Up @@ -65,7 +65,7 @@ export const generateGenesisBlockDefaultDPoSAssets = (input: GenesisBlockDefault
const accountList = [];
for (let i = 0; i < input.numberOfAccounts; i += 1) {
const passphrase = Mnemonic.generateMnemonic(256);
const keys = ed.getKeys(passphrase);
const keys = legacy.getKeys(passphrase);
accountList.push({
publicKey: keys.publicKey,
privateKey: keys.privateKey,
Expand All @@ -77,7 +77,7 @@ export const generateGenesisBlockDefaultDPoSAssets = (input: GenesisBlockDefault
const validatorList = [];
for (let i = 0; i < input.numberOfValidators; i += 1) {
const passphrase = Mnemonic.generateMnemonic(256);
const keys = ed.getKeys(passphrase);
const keys = legacy.getKeys(passphrase);
const blsPrivateKey = bls.generatePrivateKey(Buffer.from(passphrase, 'utf-8'));
const blsPublicKey = bls.getPublicKeyFromPrivateKey(blsPrivateKey);
const blsPoP = bls.popProve(blsPrivateKey);
Expand Down
24 changes: 12 additions & 12 deletions commander/test/bootstrapping/commands/account/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ describe('account:create', () => {
await CreateCommand.run([], config);
expect(JSON.parse(results[0])).toEqual([
{
publicKey: cryptography.ed.getKeys(defaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.ed.getKeys(defaultMnemonic).privateKey.toString('hex'),
publicKey: cryptography.legacy.getKeys(defaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.legacy.getKeys(defaultMnemonic).privateKey.toString('hex'),
blsPublicKey: cryptography.bls.getPublicKeyFromPrivateKey(blsPrivateKey).toString('hex'),
blsPrivateKey: blsPrivateKey.toString('hex'),
address: cryptography.address.getLisk32AddressFromPublicKey(
cryptography.ed.getKeys(defaultMnemonic).publicKey,
cryptography.legacy.getKeys(defaultMnemonic).publicKey,
'lsk',
),
binaryAddress: cryptography.address
.getAddressFromPassphrase(defaultMnemonic)
.getAddressFromPublicKey(cryptography.legacy.getKeys(defaultMnemonic).publicKey)
.toString('hex'),
passphrase: defaultMnemonic,
},
Expand All @@ -70,32 +70,32 @@ describe('account:create', () => {
await CreateCommand.run(['--count', defaultNumber.toString()], config);
const result = [
{
publicKey: cryptography.ed.getKeys(defaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.ed.getKeys(defaultMnemonic).privateKey.toString('hex'),
publicKey: cryptography.legacy.getKeys(defaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.legacy.getKeys(defaultMnemonic).privateKey.toString('hex'),
blsPublicKey: cryptography.bls.getPublicKeyFromPrivateKey(blsPrivateKey).toString('hex'),
blsPrivateKey: blsPrivateKey.toString('hex'),
address: cryptography.address.getLisk32AddressFromPublicKey(
cryptography.ed.getKeys(defaultMnemonic).publicKey,
cryptography.legacy.getKeys(defaultMnemonic).publicKey,
'lsk',
),
binaryAddress: cryptography.address
.getAddressFromPassphrase(defaultMnemonic)
.getAddressFromPublicKey(cryptography.legacy.getKeys(defaultMnemonic).publicKey)
.toString('hex'),
passphrase: defaultMnemonic,
},
{
publicKey: cryptography.ed.getKeys(secondDefaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.ed.getKeys(secondDefaultMnemonic).privateKey.toString('hex'),
publicKey: cryptography.legacy.getKeys(secondDefaultMnemonic).publicKey.toString('hex'),
privateKey: cryptography.legacy.getKeys(secondDefaultMnemonic).privateKey.toString('hex'),
blsPublicKey: cryptography.bls
.getPublicKeyFromPrivateKey(secondBlsPrivateKey)
.toString('hex'),
blsPrivateKey: secondBlsPrivateKey.toString('hex'),
address: cryptography.address.getLisk32AddressFromPublicKey(
cryptography.ed.getKeys(secondDefaultMnemonic).publicKey,
cryptography.legacy.getKeys(secondDefaultMnemonic).publicKey,
'lsk',
),
binaryAddress: cryptography.address
.getAddressFromPassphrase(secondDefaultMnemonic)
.getAddressFromPublicKey(cryptography.legacy.getKeys(secondDefaultMnemonic).publicKey)
.toString('hex'),
passphrase: secondDefaultMnemonic,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('forging:config command', () => {
jest.spyOn(process.stdout, 'write').mockImplementation(val => stdout.push(val as string) > -1);
jest.spyOn(process.stderr, 'write').mockImplementation(val => stderr.push(val as string) > -1);
jest.spyOn(ConfigCommand.prototype, 'printJSON').mockReturnValue();
jest.spyOn(cryptography.ed, 'getKeys').mockReturnValue(defaultKeys as never);
jest.spyOn(cryptography.legacy, 'getKeys').mockReturnValue(defaultKeys as never);
jest.spyOn(fs, 'ensureDirSync').mockReturnValue();
jest.spyOn(fs, 'writeJSONSync').mockReturnValue();
jest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('passphrase:encrypt', () => {
jest.spyOn(process.stdout, 'write').mockImplementation(val => stdout.push(val as string) > -1);
jest.spyOn(process.stderr, 'write').mockImplementation(val => stderr.push(val as string) > -1);
jest.spyOn(EncryptCommand.prototype, 'printJSON').mockReturnValue();
jest.spyOn(cryptography.ed, 'getKeys').mockReturnValue(defaultKeys as never);
jest.spyOn(cryptography.legacy, 'getKeys').mockReturnValue(defaultKeys as never);
jest
.spyOn(cryptography.encrypt, 'encryptMessageWithPassword')
.mockResolvedValue(encryptedPassphraseObject as never);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('transaction:create command', () => {
'{"votes":[{"delegateAddress":"ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815","amount":100},{"delegateAddress":"ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815","amount":-50}]}';
const unVoteParams =
'{"votes":[{"delegateAddress":"ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815","amount":-50}]}';
const { publicKey } = cryptography.address.getAddressAndPublicKeyFromPassphrase(passphrase);
const { publicKey } = cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
const senderPublicKey = publicKey.toString('hex');
const mockEncodedTransaction = Buffer.from('encoded transaction');
const mockJSONTransaction = {
Expand Down
2 changes: 1 addition & 1 deletion commander/test/commands/message/encrypt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('message:encrypt', () => {
jest.spyOn(process.stderr, 'write').mockImplementation(val => stderr.push(val as string) > -1);
jest.spyOn(inquirer, 'prompt').mockResolvedValue({ passphrase: defaultInputs });
jest.spyOn(readerUtils, 'readFileSource').mockResolvedValue(message);
jest.spyOn(cryptography.encrypt, 'encryptMessageWithPassphrase').mockReturnValue({
jest.spyOn(cryptography.encrypt, 'encryptMessageWithPrivateKey').mockReturnValue({
encryptedMessage: defaultEncryptedMessage.message,
nonce: defaultEncryptedMessage.nonce,
});
Expand Down
2 changes: 1 addition & 1 deletion commander/test/helpers/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export const createTransferTransaction = ({
},
},
networkIdentifier,
account.passphrase,
Buffer.from(account.privateKey, 'hex'),
tokenTransferParamsSchema,
) as any;

Expand Down
Loading