Skip to main content

crypto

Namespace used for cryptographic functions.

Functions

crypto.keccak256(byte_array): byte_array

Calculates a Keccak256 hash of a byte array and returns a byte array of size 32. For example, crypto.keccak256('Hello world!'.to_bytes()) produces x'ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab'.

Parameters:

  • byte_array: The byte array to be hashed.

Returns:

  • byte_array: A 32-byte Keccak256 hash of the input byte array.

crypto.sha256(byte_array): byte_array

Calculates an SHA-256 hash of a byte array and returns a byte array of size 32. For example, crypto.sha256('Hello world!'.to_bytes()) produces x'c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a'.

Parameters:

  • byte_array: The byte array to be hashed.

Returns:

  • byte_array: A 32-byte Keccak256 hash of the input byte array.

crypto.privkey_to_pubkey(privkey: byte_array, compress: boolean = false): byte_array

Calculates a public key from the private key. Takes a 32-byte private key and returns either a 65-byte (compress = false) or a 33-byte (compress = true) public key. For example, crypto.privkey_to_pubkey(x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F', true) produces x'036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2'.

Parameters:

  • privkey: The 32-byte private key.
  • compress (optional): Boolean flag indicating whether to return the compressed (33-byte) or uncompressed (65-byte) public key. Defaults to False (uncompressed).

Returns:

  • byte_array: The public key corresponding to the private key in the specified format (compressed or uncompressed).

verify_signature(message: byte_array, pubkey: pubkey, signature: byte_array): boolean

Verifies a signature against a message and public key. Returns true if the signature is valid, indicating that the owner of the private key corresponding to the provided public key indeed signed the message.

Parameters:

  • message: The byte array representing the message that was signed.
  • pubkey: The public key to verify the signature against.
  • signature: The 64-byte signature to verify.

Returns:

  • boolean: true if the signature is valid, false otherwise.

crypto.eth_sign(hash: byte_array, privkey: byte_array): (byte_array, byte_array, integer)

Calculates an Ethereum signature. Takes a hash and a private key and returns values r, s, and rec_id that are accepted by eth_ecrecover().

Parameters:

  • hash: The byte array representing the hash to be signed.
  • privkey: The 32-byte private key used for signing.

Returns:

  • (byte_array, byte_array, integer): A tuple containing the following elements:
    • r: The first component of the Ethereum signature.
    • s: The second component of the Ethereum signature.
    • rec_id: The recovery identifier used for signature recovery.

eth_ecrecover(r: byte_array, s: byte_array, rec_id: integer, hash: byte_array) -> byte_array

Calculates an Ethereum public key from a signature and hash. Returns a byte array representing the public key.

Parameters:

  • r: The first component of the Ethereum signature.
  • s: The second component of the Ethereum signature.
  • rec_id: The recovery identifier used for signature recovery.
  • hash: The byte array representing the hash that was signed.

Returns:

  • byte_array: The byte array representing the recovered public key.

crypto.eth_privkey_to_address(privkey: byte_array) -> byte_array

Description:

Derives a 20-byte Ethereum address from a 32-byte private key.

Parameters:

  • privkey: The 32-byte private key.

Returns:

  • byte_array: The 20-byte Ethereum address.

crypto.eth_pubkey_to_address(pubkey: byte_array) -> byte_array

Derives a 20-byte Ethereum address from a public key (33, 64, or 65 bytes).

Parameters:

  • pubkey: The public key (33, 64, or 65 bytes).

Returns:

  • byte_array: The 20-byte Ethereum address.

crypto.pubkey_encode(pubkey: byte_array, compressed: boolean = false) -> byte_array

Converts a public key between compressed (33-byte) and uncompressed (65-byte) formats.

Parameters:

  • pubkey: The public key to be encoded.
  • compressed (optional): Boolean flag indicating whether to return the compressed (33-byte) or uncompressed (65-byte) public key. Defaults to false (uncompressed).

Returns:

  • byte_array: The encoded public key in the specified format.

crypto.pubkey_to_xy(pubkey: byte_array) -> (big_integer, big_integer)

Extracts the EC point coordinates (x, y) from a public key.

Parameters:

  • pubkey: The public key.

Returns:

  • (big_integer, big_integer): A tuple containing the EC point coordinates (x, y).

crypto.xy_to_pubkey(x: big_integer, y: big_integer, compressed: boolean = false) -> byte_array

Constructs a public key (compressed or uncompressed) from EC point coordinates.

Parameters:

  • x: The x-coordinate of the EC point.
  • y: The y-coordinate of the EC point.
  • compressed (optional): Boolean flag indicating whether to return the compressed (33-byte) or uncompressed (65-byte) public key. Defaults to false (uncompressed).

Returns:

  • byte_array: The constructed public key in the specified format.
note

All functions that take a public key support three kinds of public keys:

  • Compressed 33-byte public key.
  • Uncompressed 65-byte public key.
  • Uncompressed 64-byte public key - same as the 65-byte key, but without the first byte; such key is returned by the crypto.eth_ecrecover() function.

Example - verify signature

val pubkey = x'036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2';
// = crypto.privkey_to_pubkey(x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F', true)

val message = x'DEADBEEF';
val signature = x'8ac02f17b508815fa9495177395925e41fd7db595ad35e54a56be6284e5b8e0824a3bd0e056dcfded7f8073d509b2b674607a06571abebdcb0bd27b12372aff2';

val ok = crypto.verify_signature(message, pubkey, signature);
print(ok); // prints "true"

Example - calculate an Ethereum signature with eth_sign() and recover the public key with eth_ecrecover()

val privkey = x'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
val pubkey = crypto.privkey_to_pubkey(privkey);

val hash = 'Hello'.to_bytes();
val (r, s, rec_id) = crypto.eth_sign(hash, privkey);

val recovered_pubkey = x'04' + crypto.eth_ecrecover(r, s, rec_id, hash);
require(recovered_pubkey == pubkey);