#moonbitlang/x/crypto

#Overview

A collection of cryptographic hash functions and utilities.

#Security

MD4, MD5, SHA-1, and RIPEMD-160 are provided for compatibility and should not be used where collision resistance is required. Prefer SHA-256, SHA-384, SHA-512, or SM3 for new applications.

AES-ECB, AES-CBC, and raw ChaCha encryption do not authenticate ciphertexts. New protocols should use an authenticated-encryption construction. AES modes also do not apply padding. ChaCha callers that need to handle exhaustion of the 32-bit block counter should use ChaCha::transform_checked.

#Usage

Strings in MoonBit are UTF-16 LE encoded.

#SHA-1

///|
test {
let input = "The quick brown fox jumps over the lazy dog"
inspect(
bytes_to_hex_string(sha1(@encoding.encode(UTF16, input))),
content="bd136cb58899c93173c33a90dde95ead0d0cf6df",
)
}

#MD5

///|
test {
let input = "The quick brown fox jumps over the lazy dog"
inspect(
bytes_to_hex_string(md5(@encoding.encode(UTF16, input))),
content="b0986ae6ee1eefee8a4a399090126837",
)

// buffered
let ctx = MD5::new()
ctx.update(b"a")
ctx.update(b"b")
ctx.update(b"c")
inspect(
bytes_to_hex_string(ctx.finalize()),
content="900150983cd24fb0d6963f7d28e17f72",
)
}

#SM3

///|
test {
let input = "The quick brown fox jumps over the lazy dog"
inspect(
bytes_to_hex_string(sm3(@encoding.encode(UTF16, input))),
content="fc2b31896629e88652ca1e3be449ec7ec93f7e5e29769f273fb973bc1858c66d",
)

//buffered
let ctx = SM3::new()
ctx.update(b"a".to_fixedarray())
ctx.update(b"b".to_fixedarray())
ctx.update(b"c".to_fixedarray())
inspect(
bytes_to_hex_string(ctx.finalize()),
content="66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0",
)
}

#MD4

///|
test {
inspect(
bytes_to_hex_string(md4(b"abc")),
content="a448017aaf21d8525fc10ae87aa6729d",
)
}

#RIPEMD-160

///|
test {
inspect(
bytes_to_hex_string(ripemd160(b"abc")),
content="8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
)
}

#SHA-512 / SHA-384

///|
test {
inspect(
bytes_to_hex_string(sha512(b"abc")),
content="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
)
inspect(
bytes_to_hex_string(sha384(b"abc")),
content="cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
)
}

#AES

AES-128/192/256 block cipher, with ECB and CBC modes. All functions raise CryptoError on invalid key, block, IV or data lengths; no padding is applied.

///|
test {
let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
let data = b"0123456789abcdef0123456789abcdef"
let encrypted = aes_ecb_encrypt(key, data)
inspect(
aes_ecb_decrypt(key, encrypted),
content="b\"0123456789abcdef0123456789abcdef\"",
)
}

ByteSource

trait ByteSource

impl ByteSource for Bytes

CryptoHasher

pub(open) trait CryptoHasher {
fn size(Self) -> Int
fn block_size(Self) -> Int
fn reset(Self) -> Unit
fn update(Self, BytesView) -> Unit
fn finalize_into(Self, FixedArray[Byte], offset~ : Int) -> Unit
}

ChaChaError

pub suberror ChaChaError {
CounterExhausted
InvalidOutputRange
}

Errors raised by ChaCha operations.

CryptoError

pub suberror CryptoError {
InvalidCrypto(msg~ : String)
}

Errors raised by AES operations on invalid key, block, IV or data lengths.

ChaCha

type ChaCha

ChaCha::chacha12

fn[K : ByteSource, N : ByteSource] ChaCha::chacha12(key : K, nonce : N, counter? : UInt) -> ChaCha raise

Creates a ChaCha12 encryption context following the RFC 8439 standard.
  • [key] must be 256-bit (32 bytes), in little-endian order.
  • [nonce] must be a 96-bit (12 bytes) bytes, in little-endian order.
  • [counter] is the counter value, defaulting to 0.

raise Error if the length of key or nonce is invalid.

ChaCha::chacha20

fn[K : ByteSource, N : ByteSource] ChaCha::chacha20(key : K, nonce : N, counter? : UInt) -> ChaCha raise

Creates a ChaCha20 encryption context following the RFC 8439 standard.
  • [key] must be 256-bit (32 bytes), in little-endian order.
  • [nonce] must be a 96-bit (12 bytes) bytes, in little-endian order.
  • [counter] is the counter value, defaulting to 0.

raise Error if the length of key or nonce is invalid.

ChaCha::chacha8

fn[K : ByteSource, N : ByteSource] ChaCha::chacha8(key : K, nonce : N, counter? : UInt) -> ChaCha raise

Creates a ChaCha8 encryption context following the RFC 8439 standard.
  • [key] must be 256-bit (32 bytes), in little-endian order.
  • [nonce] must be a 96-bit (12 bytes) bytes, in little-endian order.
  • [counter] is the counter value, defaulting to 0.

raise Error if the length of key or nonce is invalid.

ChaCha::transform

fn[D : ByteSource] ChaCha::transform(self : ChaCha, data : D, target : FixedArray[Byte], offset? : Int) -> Unit

Transforms data with ChaCha and writes it into target at offset.

Aborts if target does not have room for the output or if the 32-bit block counter would be exhausted. Use transform_checked when the caller needs to handle these conditions.

ChaCha::transform_checked

fn[D : ByteSource] ChaCha::transform_checked(self : ChaCha, data : D, target : FixedArray[Byte], offset? : Int) -> Unit raise ChaChaError

Transforms data with ChaCha and writes it into target at offset.

Raises ChaChaError::InvalidOutputRange or ChaChaError::CounterExhausted before writing any output if the target range is invalid or the operation would exhaust the 32-bit block counter.

MD4

type MD4

impl CryptoHasher for MD4

MD4::block_size

fn MD4::block_size(_self : MD4) -> Int

MD4::finalize

fn MD4::finalize(self : MD4) -> FixedArray[Byte]

MD4::finalize_into

fn MD4::finalize_into(self : MD4, buffer : FixedArray[Byte], offset~ : Int) -> Unit

MD4::new

fn MD4::new() -> MD4

Instantiate an MD4 context

MD4::reset

fn MD4::reset(self : MD4) -> Unit

MD4::size

fn MD4::size(_self : MD4) -> Int

MD4::update

fn[Data : ByteSource] MD4::update(self : MD4, data : Data) -> Unit

update the state of given context from new data

MD4::update_from_iter

fn MD4::update_from_iter(self : MD4, data : Iter[Byte]) -> Unit

MD5

#alias(MD5Context, deprecated="Use `MD5` instead")
type MD5

impl CryptoHasher for MD5

MD5::block_size

#deprecated("`MD5::block_size` is deprecated, use `CryptoHasher::block_size` instead.")
fn MD5::block_size(_self : MD5) -> Int

MD5::finalize

fn MD5::finalize(self : MD5) -> FixedArray[Byte]

MD5::finalize_into

#deprecated("`MD5::finalize_into` is deprecated, use `CryptoHasher::finalize_into` instead.")
fn MD5::finalize_into(self : MD5, buffer : FixedArray[Byte], offset~ : Int) -> Unit

MD5::new

fn MD5::new() -> MD5

Instantiate a MD5 context

MD5::reset

#deprecated("`MD5::reset` is deprecated, use `CryptoHasher::reset` instead.")
fn MD5::reset(self : MD5) -> Unit

MD5::size

#deprecated("`MD5::size` is deprecated, use `CryptoHasher::size` instead.")
fn MD5::size(_self : MD5) -> Int

MD5::update

fn[Data : ByteSource] MD5::update(self : MD5, data : Data) -> Unit

update the state of given context from new data

RIPEMD160

type RIPEMD160

RIPEMD160::block_size

fn RIPEMD160::block_size(_self : RIPEMD160) -> Int

RIPEMD160::finalize

fn RIPEMD160::finalize(self : RIPEMD160) -> FixedArray[Byte]

RIPEMD160::finalize_into

fn RIPEMD160::finalize_into(self : RIPEMD160, buffer : FixedArray[Byte], offset~ : Int) -> Unit

RIPEMD160::new

fn RIPEMD160::new() -> RIPEMD160

Instantiate a RIPEMD-160 context

RIPEMD160::reset

fn RIPEMD160::reset(self : RIPEMD160) -> Unit

RIPEMD160::size

fn RIPEMD160::size(_self : RIPEMD160) -> Int

RIPEMD160::update

fn[Data : ByteSource] RIPEMD160::update(self : RIPEMD160, data : Data) -> Unit

update the state of given context from new data

RIPEMD160::update_from_iter

fn RIPEMD160::update_from_iter(self : RIPEMD160, data : Iter[Byte]) -> Unit

SHA224

type SHA224

SHA-224 is a truncated variant of SHA-256 with a distinct initial state, producing a 28-byte digest. It shares the compression core with SHA-256.

SHA224::block_size

fn SHA224::block_size(_self : SHA224) -> Int

SHA224::finalize

fn SHA224::finalize(self : SHA224) -> FixedArray[Byte]

SHA224::finalize_into

fn SHA224::finalize_into(self : SHA224, buffer : FixedArray[Byte], offset~ : Int) -> Unit

SHA224::new

fn SHA224::new() -> SHA224

Instantiate a SHA-224 context with the standard initial hash value.

SHA224::reset

fn SHA224::reset(self : SHA224) -> Unit

SHA224::size

fn SHA224::size(_self : SHA224) -> Int

SHA224::update

fn[Data : ByteSource] SHA224::update(self : SHA224, data : Data) -> Unit

SHA224::update_from_iter

fn SHA224::update_from_iter(self : SHA224, data : Iter[Byte]) -> Unit

SHA256

#alias(Sha256Context, deprecated="Use `SHA256` instead")
type SHA256

SHA256::block_size

#deprecated("`SHA256::block_size` is deprecated, use `CryptoHasher::block_size` instead.")
fn SHA256::block_size(_self : SHA256) -> Int

SHA256::finalize

fn SHA256::finalize(self : SHA256) -> FixedArray[Byte]

SHA256::finalize_into

#deprecated("`SHA256::finalize_into` is deprecated, use `CryptoHasher::finalize_into` instead.")
fn SHA256::finalize_into(self : SHA256, buffer : FixedArray[Byte], offset~ : Int) -> Unit

SHA256::new

fn SHA256::new(reg? : FixedArray[UInt]) -> SHA256

Instantiate a SHA-256 context with the standard initial hash value.

SHA256::reset

#deprecated("`SHA256::reset` is deprecated, use `CryptoHasher::reset` instead.")
fn SHA256::reset(self : SHA256) -> Unit

SHA256::size

#deprecated("`SHA256::size` is deprecated, use `CryptoHasher::size` instead.")
fn SHA256::size(_self : SHA256) -> Int

SHA256::update

fn[Data : ByteSource] SHA256::update(self : SHA256, data : Data) -> Unit

update the state of given context from new data

SHA256::update_from_iter

fn SHA256::update_from_iter(self : SHA256, data : Iter[Byte]) -> Unit

SHA512

type SHA512

SHA512::block_size

fn SHA512::block_size(_self : SHA512) -> Int

SHA512::finalize

fn SHA512::finalize(self : SHA512) -> FixedArray[Byte]

SHA512::finalize_into

fn SHA512::finalize_into(self : SHA512, buffer : FixedArray[Byte], offset~ : Int) -> Unit

SHA512::new

fn SHA512::new() -> SHA512

Instantiates a SHA-512 context.

SHA512::reset

fn SHA512::reset(self : SHA512) -> Unit

SHA512::size

fn SHA512::size(_self : SHA512) -> Int

SHA512::update

fn[Data : ByteSource] SHA512::update(self : SHA512, data : Data) -> Unit

update the state of given context from new data

SHA512::update_from_iter

fn SHA512::update_from_iter(self : SHA512, data : Iter[Byte]) -> Unit

SM3

#alias(SM3Context, deprecated="Use `SM3` instead")
type SM3

impl CryptoHasher for SM3

SM3::block_size

#deprecated("`SM3::block_size` is deprecated, use `CryptoHasher::block_size` instead.")
fn SM3::block_size(_self : SM3) -> Int

SM3::finalize

fn SM3::finalize(self : SM3) -> FixedArray[Byte]

SM3::finalize_into

#deprecated("`SM3::finalize_into` is deprecated, use `CryptoHasher::finalize_into` instead.")
fn SM3::finalize_into(self : SM3, buffer : FixedArray[Byte], offset~ : Int) -> Unit

SM3::new

fn SM3::new() -> SM3

Instantiate a SM3 context

SM3::reset

#deprecated("`SM3::reset` is deprecated, use `CryptoHasher::reset` instead.")
fn SM3::reset(self : SM3) -> Unit

SM3::size

#deprecated("`SM3::size` is deprecated, use `CryptoHasher::size` instead.")
fn SM3::size(_self : SM3) -> Int

SM3::update

fn[Data : ByteSource] SM3::update(self : SM3, data : Data) -> Unit

update the state of given context from new data

SM3::update_from_iter

fn SM3::update_from_iter(self : SM3, data : Iter[Byte]) -> Unit

aes_cbc_decrypt

fn aes_cbc_decrypt(key : BytesView, iv : BytesView, data : BytesView) -> Bytes raise CryptoError

Decrypts data (a multiple of 16 bytes) with AES in CBC mode.

Raises CryptoError if key, iv or data has an invalid length.

aes_cbc_encrypt

fn aes_cbc_encrypt(key : BytesView, iv : BytesView, data : BytesView) -> Bytes raise CryptoError

Encrypts data (a multiple of 16 bytes) with AES in CBC mode. No padding is applied; callers must pad themselves.

Raises CryptoError if key, iv or data has an invalid length.

aes_ecb_decrypt

fn aes_ecb_decrypt(key : BytesView, data : BytesView) -> Bytes raise CryptoError

Decrypts data (a multiple of 16 bytes) with AES in ECB mode.

Raises CryptoError if key or data has an invalid length.

aes_ecb_encrypt

fn aes_ecb_encrypt(key : BytesView, data : BytesView) -> Bytes raise CryptoError

Encrypts data (a multiple of 16 bytes) with AES in ECB mode. No padding is applied; callers must pad themselves.

Raises CryptoError if key or data has an invalid length.

bytes_to_hex_string

fn[D : ByteSource] bytes_to_hex_string(input : D) -> String

print a sequence of byte in hex representation

chacha12

#deprecated("Use ChaCha::chacha12 and ChaCha::transform instead")
fn[Data : ByteSource] chacha12(key : FixedArray[UInt], counter : UInt, block : Data, nonce? : UInt) -> FixedArray[Byte] raise

Encrypts a block of data using the ChaCha12 algorithm.
  • [key] must be 8 32-bit unsigned integers.
  • [counter] is the counter value.
  • [block] is the block of data to be encrypted.
  • [nonce] is default to 0
  • Returns the encrypted block of data.

chacha20

#deprecated("Use ChaCha::chacha20 and ChaCha::transform instead")
fn[Data : ByteSource] chacha20(key : FixedArray[UInt], counter : UInt, block : Data, nonce? : UInt) -> FixedArray[Byte] raise

Encrypts a block of data using the ChaCha20 algorithm.
  • [key] must be 8 32-bit unsigned integers.
  • [counter] is the counter value.
  • [block] is the block of data to be encrypted.
  • [nonce] is default to 0
  • Returns the encrypted block of data.

chacha8

#deprecated("Use ChaCha::chacha8 and ChaCha::transform instead")
fn[Data : ByteSource] chacha8(key : FixedArray[UInt], counter : UInt, block : Data, nonce? : UInt) -> FixedArray[Byte] raise

Encrypts a block of data using the ChaCha8 algorithm.
  • [key] must be 8 32-bit unsigned integers.
  • [counter] is the counter value.
  • [block] is the block of data to be encrypted.
  • [nonce] is default to 0
  • Returns the encrypted block of data.

hmac

fn[H : CryptoHasher] hmac(hash : H, key : BytesView, message : BytesView) -> FixedArray[Byte]

Computes HMAC (Hash-based Message Authentication Code) using a specified cryptographic hash function.

Parameters:

  • hash : A hash function implementation that satisfies the CryptoHasher trait.
  • key : The secret key used for generating the authentication code.
  • message : The message to be authenticated.

Returns a fixed-size array of bytes containing the HMAC value. The length of the output depends on the underlying hash function's output size.

md4

fn[Data : ByteSource] md4(data : Data) -> FixedArray[Byte]

Compute the MD4 digest of some data based on RFC1320.
  • Note that MD4 is considered cryptographically broken. Unless mandated, more secure alternatives should be preferred.

md4_from_iter

fn md4_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

md5

fn[Data : ByteSource] md5(data : Data) -> FixedArray[Byte]

Compute the MD5 digest of some data based on RFC1321.
  • Note that MD5 is considered cryptographically broken. Unless mandated, more secure alternatives should be preferred.

ripemd160

fn[Data : ByteSource] ripemd160(data : Data) -> FixedArray[Byte]

Compute the RIPEMD-160 digest of some data.
  • Note that RIPEMD-160 is no longer considered a strong hash; unless mandated, more secure alternatives should be preferred.

ripemd160_from_iter

fn ripemd160_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

sha1

fn[Data : ByteSource] sha1(input : Data) -> FixedArray[Byte]

sha224

fn[Data : ByteSource] sha224(data : Data) -> FixedArray[Byte]

sha224_from_iter

fn sha224_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

sha256

fn[Data : ByteSource] sha256(data : Data) -> FixedArray[Byte]

Compute the Sha256 digest in Bytes of some data. Note that Sha256 is big-endian.

sha256_from_iter

fn sha256_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

sha384

fn[Data : ByteSource] sha384(data : Data) -> FixedArray[Byte]

sha384_from_iter

fn sha384_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

sha512

fn[Data : ByteSource] sha512(data : Data) -> FixedArray[Byte]

Compute the Sha512 digest in FixedArray[Byte] of some data. Note that Sha512 is big-endian.

sha512_from_iter

fn sha512_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

sm3

fn[Data : ByteSource] sm3(data : Data) -> FixedArray[Byte]

Compute the SM3 digest in FixedArray[Byte] of some data. Note that SM3 is big-endian.

sm3_from_iter

fn sm3_from_iter(data : Iter[Byte]) -> FixedArray[Byte]

uints_to_hex_string

fn uints_to_hex_string(input : Iter[UInt]) -> String

convert a sequence of UInt to hex representation