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

Commit

Permalink
Merge pull request #7364 from LiskHQ/7332-remove_passphrase_handling
Browse files Browse the repository at this point in the history
Remove passphrase handling from cryptography - Closes #7291, #6864,#7332
  • Loading branch information
shuse2 authored Aug 5, 2022
2 parents ef942e7 + 080d3fb commit d03d141
Show file tree
Hide file tree
Showing 68 changed files with 2,840 additions and 1,181 deletions.
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

0 comments on commit d03d141

Please sign in to comment.