Cryptography

The Lisk Elements cryptography module provides all the cryptographic functionality necessary when interacting with the Lisk ecosystem.

Installation

This adds the Lisk client as a dependency of your project:

npm install @liskhq/lisk-cryptography@2.4.2

Upgrade

To perform an upgrade, execute the following command:

npm update @liskhq/lisk-cryptography

Usage

The lisk-cryptography package can be used on both the server-side code and the client-side code.

In case the lisk-cryptography is used server-side, it is beneficial to speed up the application by using the sodium-native library.

To perform this, expose NACL_FAST=enable as the environment variable as shown below:

export NACL_FAST=enable

In order to switch back to the default library TweetNaCl.js, which is slower but can also be executed on the client-side, set it to disable as shown below:

export NACL_FAST=disable

Alternatively, it can be unset completely by executing the following command:

unset NACL_FAST

Constants

Cryptography-specific constants are available via the cryptography key as can be seen below:

Usage

import * as cryptography from '@liskhq/lisk-cryptography';

cryptography.constants.SIGNED_MESSAGE_PREFIX; (1)
1 Prefix for signed messages.

Methods for converting between formats

Methods for converting between different formats.

bufferToHex

This converts a buffer or byte array to a hex string.

Syntax

bufferToHex(buffer)

Parameters

buffer: The buffer to convert into hex string format.

Return value

string: The hex string representation of the buffer.

Examples

import * as cryptography from '@liskhq/lisk-cryptography';

const buffer = Buffer.from([0xab, 0xcd, 0x12, 0x34]);
cryptography.bufferToHex(buffer); // 'abcd1234'

getAddressFromPublicKey

This converts a public key into a Lisk address.

Syntax

getAddressFromPublicKey(publicKey)

Parameters

publicKey: This is the public key as string to convert.

Return value

string: This is the Lisk address for the public key.

Examples

const publicKey = '968ba2fa993ea9dc27ed740da0daf49eddd740dbd7cb1cb4fc5db3a20baf341b';
cryptography.getAddressFromPublicKey(publicKey); // '12668885769632475474L'

hexToBuffer

Converts a hexadecimal value string to a buffer.

Syntax

hexToBuffer(hexString)

Parameters

hexString: The string to convert to a buffer.

Return value

buffer: The created buffer.

Examples

const hex = 'abcd1234';
cryptography.hexToBuffer(hex); // <Buffer ab cd 12 34>

intToBuffer

Converts an integer value to a buffer.

Syntax

intToBuffer(intString, byteLength, endianness)

Parameters

  • intString: The integer to convert to a buffer. Can be of type string or number.

  • byteLength: Size of the buffer.

  • endianness: A string value that refers to the order of bytes in the buffer. Default value is big.

Return value

buffer: The created buffer.

Examples

const int = '12345';
cryptography.intToBuffer(int); // <Buffer 30 39>

parseEncryptedPassphrase

This parses an encrypted passphrase string as an object.

Syntax

parseEncryptedPassphrase(encryptedPassphrase)

Parameters

encryptedPassphrase: The stringified encrypted passphrase to parse.

Return value

object: The parsed encrypted passphrase.

Examples

const encryptedPassphrase = 'iterations=1000000&salt=bce40d3176e31998ec435ffc2993b280&cipherText=99bb7eff6755ecfe1dfa0368328c2d10589d7b85a23f75043497d7bdf7f14fb84e8caee1f9bc4b9543ba320e7f10801b0ff2065427d55c3139cf15e3b626b54f73b72a5b993323a6d60ec4aa407472ae&iv=51bcc76bbd0ab97b2292e305&tag=12e8fcfe7ad735fa9957baa48442e205&version=1';
cryptography.parseEncryptedPassphrase(encryptedPassphrase);
/* {
    iterations: 1000000,
    salt: 'bce40d3176e31998ec435ffc2993b280',
    cipherText: '99bb7eff6755ecfe1dfa0368328c2d10589d7b85a23f75043497d7bdf7f14fb84e8caee1f9bc4b9543ba320e7f10801b0ff2065427d55c3139cf15e3b626b54f73b72a5b993323a6d60ec4aa407472ae',
    iv: '51bcc76bbd0ab97b2292e305',
    tag: '12e8fcfe7ad735fa9957baa48442e205',
    version: '1',
} */

stringifyEncryptedPassphrase

This converts an encrypted passphrase object to a string for convenient storage.

Syntax

stringifyEncryptedPassphrase(encryptedPassphrase)

Parameters

encryptedPassphrase: The encrypted passphrase object to convert into a string.

Return value

string: The encrypted passphrase as a string.

Examples

const encryptedPassphrase = cryptography.encryptPassphraseWithPassword(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap',
    'some secure password'
);
cryptography.stringifyEncryptedPassphrase(encryptedPassphrase); // 'iterations=1000000&salt=bce40d3176e31998ec435ffc2993b280&cipherText=99bb7eff6755ecfe1dfa0368328c2d10589d7b85a23f75043497d7bdf7f14fb84e8caee1f9bc4b9543ba320e7f10801b0ff2065427d55c3139cf15e3b626b54f73b72a5b993323a6d60ec4aa407472ae&iv=51bcc76bbd0ab97b2292e305&tag=12e8fcfe7ad735fa9957baa48442e205&version=1'

stringToBuffer

This converts a string value into a Buffer.

Syntax

stringToBuffer(string)

Parameters

string: A string value.

Return value

Buffer: The buffer representation of the string value.

Examples

const someString = "foobar";
cryptography.stringToBuffer(someString); // <Buffer 66 6f 6f 62 61 72>

Methods for encrypting and decrypting

decryptMessageWithPassphrase

This decrypts a message that has been encrypted for a given public key using the corresponding passphrase as shown below:

Syntax

decryptMessageWithPassphrase(cipherHex, nonce, passphrase, senderPublicKey)

Parameters

cipherHex: The hex string representation of the encrypted message.

nonce: The hex string representation of the nonce used during encryption.

passphrase: The passphrase to be used in decryption.

senderPublicKey: The public key of the message sender, (this is used to ensure the message was signed by the correct person).

Return value

string: The decrypted message.

Examples

const decryptedMessage = cryptography.decryptMessageWithPassphrase(
    '7bef28e1ddb34902d2e006a36062805e597924c9885c142444bafb',
    '5c29c9df3f041529a5f9ba07c444a86cbafbfd21413ec3a7',
    'robust swift grocery peasant forget share enable convince deputy road keep cheap',
    '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f'
); // 'Hello Lisk!'

decryptPassphraseWithPassword

This decrypts a passphrase that has been encrypted using a password.

Syntax

decryptPassphraseWithPassword(encryptedPassphraseObject, password)

Parameters

  • encryptedPassphraseObject: The output of encryptPassphraseWithPassword. Contains iterations, cipherText, iv, salt, tag, and version.

  • password: The password to be used in decryption.

Return value

string: The decrypted passphrase.

Examples

const encryptedPassphrase = {
    iterations: 1000000,
    salt: 'bce40d3176e31998ec435ffc2993b280',
    cipherText: '99bb7eff6755ecfe1dfa0368328c2d10589d7b85a23f75043497d7bdf7f14fb84e8caee1f9bc4b9543ba320e7f10801b0ff2065427d55c3139cf15e3b626b54f73b72a5b993323a6d60ec4aa407472ae',
    iv: '51bcc76bbd0ab97b2292e305',
    tag: '12e8fcfe7ad735fa9957baa48442e205',
    version: '1',
};
const decryptedPassphrase = cryptography.decryptPassphraseWithPassword(
    encryptedPassphrase,
    'some secure password'
); // 'robust swift grocery peasant forget share enable convince deputy road keep cheap'

encryptMessageWithPassphrase

This encrypts a message under a recipient’s public key, using a passphrase to create a signature.

Syntax

encryptMessageWithPassphrase(message, passphrase, recipientPublicKey)

Parameters

message: The plaintext message to encrypt.

passphrase: The passphrase used to sign the encryption and ensure message integrity.

recipientPublicKey: The public key to be used in encryption.

Return value

object: The result of encryption. This contains the nonce and encryptedMessage, both in hex string format.

Examples

const encryptedMessage = cryptography.encryptMessageWithPassphrase(
    'Hello Lisk!',
    'robust swift grocery peasant forget share enable convince deputy road keep cheap',
    '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f'
);
/* {
    encryptedMessage: '7bef28e1ddb34902d2e006a36062805e597924c9885c142444bafb',
    nonce: '5c29c9df3f041529a5f9ba07c444a86cbafbfd21413ec3a7',
} */

encryptPassphraseWithPassword

This encrypts a passphrase under a password for secure storage.

Syntax

encryptPassphraseWithPassword(passphrase, password, [iterations])

Parameters

passphrase: The passphrase in plaintext to encrypt.

password: The password to be used in encryption.

iterations: The number of iterations to use when deriving a key from the password using PBKDF2. (The default value if not provided is 1,000,000.)

Return value

object: The result of encryption. This contains the iterations, cipherText, iv, salt, tag, and version.

Examples

const encryptedPassphrase = cryptography.encryptPassphraseWithPassword(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap',
    'some secure password',
);
/* {
    iterations: 1000000,
    salt: 'bce40d3176e31998ec435ffc2993b280',
    cipherText: '99bb7eff6755ecfe1dfa0368328c2d10589d7b85a23f75043497d7bdf7f14fb84e8caee1f9bc4b9543ba320e7f10801b0ff2065427d55c3139cf15e3b626b54f73b72a5b993323a6d60ec4aa407472ae',
    iv: '51bcc76bbd0ab97b2292e305',
    tag: '12e8fcfe7ad735fa9957baa48442e205',
    version: '1',
} */

Methods for hashing

getNetworkIdentifier

Syntax

getNetworkIdentifier(genesisBlockPayloadHash, communityIdentifier)

Parameters

  • genesisBlockPayloadHash: The payload hash of the genesis block.

  • communityIdentifier: The community identifier as string.

Return value

string: The ID of the corresponding network as hash string.

Examples

const networkIdentifier = getNetworkIdentifier(
    "23ce0366ef0a14a91e5fd4b1591fc880ffbef9d988ff8bebf8f3666b0c09597d",
    "Lisk",
); // '7158c297294a540bc9ac6e474529c3da38d03ece056e3fa2d98141e6ec54132d'

hash

Hashes an input using the SHA256 algorithm.

Syntax

hash(data, [format])

Parameters

  • data: The data to hash provided as a buffer, or a string.

  • format: The format of the input data if provided as a string. This must be one of hex or utf8.

Return value

buffer: The result of hashing.

Examples

cryptography.hash(Buffer.from([0xab, 0xcd, 0x12, 0x34])); // <Buffer 77 79 07 d5 4b 6a 45 02 bd 65 4c b4 ae 81 c5 f7 27 01 3b 5e 3b 93 cd 8b 53 d7 21 34 42 69 d3 b0>
cryptography.hash('abcd1234', 'hex'); // <Buffer 77 79 07 d5 4b 6a 45 02 bd 65 4c b4 ae 81 c5 f7 27 01 3b 5e 3b 93 cd 8b 53 d7 21 34 42 69 d3 b0>
cryptography.hash('abcd1234', 'utf8'); // <Buffer e9 ce e7 1a b9 32 fd e8 63 33 8d 08 be 4d e9 df e3 9e a0 49 bd af b3 42 ce 65 9e c5 45 0b 69 ae>

Methods for managing keys

getAddressAndPublicKeyFromPassphrase

This returns an object containing the address and public key for a provided passphrase.

Syntax

getAddressAndPublicKeyFromPassphrase(passphrase)

Parameters

passphrase: The secret passphrase to process.

Return value

object: This contains an address as a string, and publicKey as a hex string.

Examples

cryptography.getAddressAndPublicKeyFromPassphrase(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap'
);
/* {
    address: '8273455169423958419L',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
} */

getAddressFromPassphrase

This returns the Lisk address for a provided passphrase.

Syntax

getAddressFromPassphrase(passphrase)

Parameters

passphrase: The secret passphrase to process.

Return value

string: The address associated with the provided passphrase.

Examples

cryptography.getAddressFromPassphrase(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap'
); //'8273455169423958419L'

getKeys

An alias for getPrivateAndPublicKeyFromPassphrase.

getPrivateAndPublicKeyBytesFromPassphrase

This returns an object containing both the private and public keys as Uint8Arrays for a provided passphrase.

Syntax

getPrivateAndPublicKeyBytesFromPassphrase(passphrase)

Parameters

passphrase: The secret passphrase to process.

Return value

object: This contains both the privateKey and publicKey as Uint8Arrays.

Examples

cryptography.getPrivateAndPublicKeyBytesFromPassphrase(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap'
);
/* {
    privateKey: [Uint8Array],
    publicKey: [Uint8Array],
} */

getPrivateAndPublicKeyFromPassphrase

This returns an object containing both the private and public keys as hex strings for a provided passphrase.

Syntax

getPrivateAndPublicKeyFromPassphrase(passphrase)

Parameters

passphrase: The secret passphrase to process.

Return value

object: This contains both the privateKey and publicKey as hex strings.

Examples

cryptography.getPrivateAndPublicKeyFromPassphrase(
    'robust swift grocery peasant forget share enable convince deputy road keep cheap'
);
/* {
    privateKey: 'b092a6664e9eed658ff50fe796ee695b9fe5617e311e9e8a34eb340eb5b831549d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
} */

Methods for signing and verifying

printSignedMessage

This outputs a string representation of a signed message object which is suitable for printing.

Syntax

printSignedMessage(signedMessageObject)

Parameters

  • signedMessageObject: The result of calling signMessageWithPassphrase or signMessageWithTwoPassphrases.

Return value

string: The string representation of the signed message object.

Examples

const stringToPrint = cryptography.printSignedMessage({
    message: 'Hello Lisk!',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    signature: '125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401',
});
console.log(stringToPrint);
//-----BEGIN LISK SIGNED MESSAGE-----
//-----MESSAGE-----
//Hello Lisk!
//-----PUBLIC KEY-----
//9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f
//-----SIGNATURE-----
//125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401
//-----END LISK SIGNED MESSAGE-----

signAndPrintMessage

This signs a message with one or two passphrases and outputs a string representation which is suitable for printing.

Syntax

signAndPrintMessage(message, passphrase, [secondPassphrase])

Parameters

message: The string message to sign.

passphrase: The secret passphrase required in order to sign the message.

secondPassphrase: The optional second secret passphrase used to sign the message.

Return value

string: The string representation of the signed message object.

Examples

const stringToPrint = cryptography.signAndPrintMessage('Hello Lisk!',  'robust swift grocery peasant forget share enable convince deputy road keep cheap');
console.log(stringToPrint);
// -----BEGIN LISK SIGNED MESSAGE-----
//-----MESSAGE-----
//Hello Lisk!
//-----PUBLIC KEY-----
//9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f
//-----SIGNATURE-----
//125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401
//-----END LISK SIGNED MESSAGE-----

signMessageWithPassphrase

Signs a message with a passphrase.

Syntax

signMessageWithPassphrase(message, passphrase)

Parameters

message: The string message to sign.

passphrase: The secret passphrase as string used to sign the message.

Return value

object: This contains the message, the publicKey corresponding to the passphrase, and the signature as a hex string.

Examples

cryptography.signMessageWithPassphrase('Hello Lisk!',  'robust swift grocery peasant forget share enable convince deputy road keep cheap');
/* {
    message: 'Hello Lisk!',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    signature: '125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401',
} */

signMessageWithTwoPassphrases

This signs a message using a secret passphrase and a second secret passphrase.

Syntax

signMessageWithTwoPassphrases(message, passphrase, secondPassphrase)

Parameters

message: The message to sign as a UTF8-encoded string or a buffer.

passphrase: The secret passphrase to be used in signing.

secondPassphrase: The second secret passphrase to be used in signing.

Return value

object: This contains the message (the original input), the publicKey (for the passphrase as a hex string), the secondPublicKey (for the second passphrase as a hex string), the signature (as a hex string), and finally the secondSignature (as a hex string).

Examples

cryptography.signMessageWithTwoPassphrases(
    'Hello Lisk!',
    'robust swift grocery peasant forget share enable convince deputy road keep cheap',
    'weapon van trap again sustain write useless great pottery urge month nominee',
);
/* {
    message: 'Hello Lisk!',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    secondPublicKey: '141b16ac8d5bd150f16b1caa08f689057ca4c4434445e56661831f4e671b7c0a',
    signature: '125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401',
    secondSignature: '97196d262823166ec9ae5145238479effe00204e763d43cc9539cc711277a6652e8266aace3622f9e8a08cd5de08115c06db15fee71a44a98172cfab58f91c01',
 } */

verifyMessageWithPublicKey

This verifies that a signature for a given message matches the provided public key.

Syntax

verifyMessageWithPublicKey(signedMessageObject)

Parameters

signedMessageObject: The result of calling signMessageWithPassphrase.

Return value

boolean: Returns true if the signature is valid, and false if not.

Examples

cryptography.verifyMessageWithPublicKey({
    message: 'Hello Lisk!',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    signature: '125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401',
}); // true

verifyMessageWithTwoPublicKeys

This verifies that a signature and second signature for a given message match the provided public keys.

Syntax

verifyMessageWithTwoPublicKeys(signedMessageObject)

Parameters

signedMessageObject: The result of calling signMessageWithTwoPassphrases.

Return value

boolean: Returns true if the signatures are valid, and false if not.

Examples

cryptography.verifyMessageWithTwoPublicKeys({
    message: 'Hello Lisk!',
    publicKey: '9d3058175acab969f41ad9b86f7a2926c74258670fe56b37c429c01fca9f2f0f',
    secondPublicKey: '141b16ac8d5bd150f16b1caa08f689057ca4c4434445e56661831f4e671b7c0a',
    signature: '125febe625b2d62381ff836c020de0b00297f7d2493fe6404bc6109fd70a55348555b7a66a35ac657d338d7fe329efd203da1602f4c88cc21934605676558401',
    secondSignature: '97196d262823166ec9ae5145238479effe00204e763d43cc9539cc711277a6652e8266aace3622f9e8a08cd5de08115c06db15fee71a44a98172cfab58f91c01',
}); // true

signDataWithPrivateKey

Signs data with a private key.

Syntax

signDataWithPrivateKey(data,privatekey)

Parameters

data: The data to be signed, e.g. a transaction object as Buffer. privatekey: The private key if a user account as Buffer.

Return value

Buffer: Returns the signed data.