Sign in

    #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(
    @crypto.bytes_to_hex_string(@crypto.sha1(@encoding.encode(UTF16, input))),
    content="bd136cb58899c93173c33a90dde95ead0d0cf6df",
    )
    }

    #MD5

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

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

    #SM3

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

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

    #MD4

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

    #RIPEMD-160

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

    #SHA-512 / SHA-384

    ///|
    test {
    inspect(
    @crypto.bytes_to_hex_string(@crypto.sha512(b"abc")),
    content="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
    )
    inspect(
    @crypto.bytes_to_hex_string(@crypto.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 = @crypto.aes_ecb_encrypt(key, data)
    inspect(
    @crypto.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