Pure-MoonBit crypto primitives: SHA-1/2 (incl. SHA-512/224/256), SHA-3, Keccak-256, SHAKE/cSHAKE, BLAKE2b/BLAKE2s/BLAKE3 (+keyed), RIPEMD-160, HMAC/Poly1305/CMAC/KMAC/GMAC, AES-CBC/GCM/CTR/CCM/KW/SIV, ChaCha20/XChaCha20 + Salsa20, HKDF/PBKDF2/scrypt/Argon2, RSA (PKCS1-v1.5/OAEP/PSS), ECDSA P-256, Ed25519/Ed25519ctx/Ed25519ph, X25519, HOTP/TOTP (SHA-1/256/512), SipHash, CRC32/CRC32C/CRC-64/Adler-32, Base64/Hex, sealed-box envelope
The implementations are correct and tested but have not been formally audited. See Security & performance boundaries.
git remote add gitlink https://www.gitlink.org.cn/CC01/mooncry_mirror.git
git push gitlink mastermoon add cc06b/mooncrymoon new myapp
cd myapp
moon add cc06b/mooncryimport {
"cc06b/mooncry/lib",
}
pkgtype(kind: "executable")fn main {
// SHA-256 one-shot
let digest = @lib.sha256(b"Hello, world!")
println("SHA-256: " + @lib.bytes_to_hex(digest))
// AES-GCM round-trip (256-bit key, 96-bit nonce, with AAD)
let key = Bytes::make(32, b'\x00')
let iv = Bytes::make(12, b'\x00')
let (ciphertext, tag) = @lib.aes_gcm_encrypt(b"secret data", key, iv, b"aad")
let (plaintext, ok) = @lib.aes_gcm_decrypt(ciphertext, key, iv, b"aad", tag)
let status = if ok { "OK" } else { "FAIL" }
println("AES-GCM round-trip: " + status)
println("Recovered: " + @lib.bytes_to_hex(plaintext))
// Sealed-box envelope: HKDF-SHA256 derives the AES-256-GCM key from a
// master key + context, then encrypts into a versioned envelope.
let master = Bytes::make(32, b'\x07')
let nonce = Bytes::make(12, b'\x01')
let envelope = @lib.sealed_box_seal(master, nonce, b"plaintext", b"aad", b"tenant-1")
match @lib.sealed_box_open(master, envelope, b"aad", b"tenant-1") {
Ok(pt) => println("Sealed box: " + @lib.bytes_to_hex(pt))
Err(msg) => println("Sealed box failed: " + msg)
}
}moon run cmd/mainSHA-256: 315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3
AES-GCM round-trip: OK
Recovered: 7365637265742064617461| Function | Description |
|---|---|
| md5(data : Bytes) -> Bytes | MD5 one-shot, 16-byte digest |
| sha224 / sha256 / sha384 / sha512(data : Bytes) -> Bytes | SHA-2 family (FIPS 180-4) |
| sha3_224 / sha3_256 / sha3_384 / sha3_512(data : Bytes) -> Bytes | SHA-3 (FIPS 202) |
| shake_128 / shake_256(data : Bytes, out_len : Int) -> Bytes | SHAKE XOF, out_len bytes |
| blake2b(data : Bytes, out_len : Int) -> Bytes | BLAKE2b (RFC 7693), out_len 1..64 |
| blake3(data : Bytes) -> Bytes | BLAKE3, 32-byte digest |
| blake3_xof(data : Bytes, out_len : Int) -> Bytes | BLAKE3 XOF (arbitrary-length) |
| hmac_sha256 / hmac_sha512(key, msg : Bytes) -> Bytes | HMAC (RFC 2104) |
| hmac_sha3_256 / hmac_sha3_512(key, msg : Bytes) -> Bytes | HMAC over SHA-3 (RFC 2104 + FIPS 202) |
| poly1305(key, msg : Bytes) -> Bytes | Poly1305 MAC (RFC 8439), 16-byte tag |
| cmac_aes(data, key : Bytes) -> Bytes | AES-CMAC (NIST SP 800-38B), 16-byte tag |
| aes_encrypt_cbc / aes_decrypt_cbc(data, key, iv) -> Bytes | AES-CBC (IV prepended, PKCS#7) |
| aes_gcm_encrypt(pt, key, iv, aad) -> (Bytes, Bytes) | AES-GCM encrypt → (ct, 16-byte tag) |
| aes_gcm_decrypt(ct, key, iv, aad, tag) -> (Bytes, Bool) | AES-GCM decrypt, constant-time tag verify |
| aes_ctr(data, key, iv) -> Bytes | AES-CTR encrypt/decrypt (symmetric) |
| chacha20_xor(input, key, nonce, counter) -> Bytes | ChaCha20 encrypt/decrypt (symmetric) |
| salsa20_keystream_block(key, nonce, counter) -> Bytes | Salsa20 keystream block (64 bytes) |
| salsa20_xor(key, nonce, counter, data) -> Bytes | Salsa20 stream cipher encrypt/decrypt (symmetric) |
| chacha20_poly1305_encrypt(key, nonce, aad, pt) -> Bytes | ChaCha20-Poly1305 AEAD → ct ‖ tag |
| chacha20_poly1305_decrypt(key, nonce, aad, input) -> Bytes | AEAD decrypt, aborts on tag mismatch |
| hkdf_sha256(salt, ikm, info, len) -> Bytes | HKDF-SHA256 (RFC 5869) |
| pbkdf2_hmac_sha256(password, salt, iterations, len) -> Bytes | PBKDF2-HMAC-SHA256 (RFC 8018) |
| hkdf_sha3_256(salt, ikm, info, len) -> Bytes | HKDF-SHA3-256 (RFC 5869 over FIPS 202) |
| pbkdf2_hmac_sha3_256(password, salt, iterations, len) -> Bytes | PBKDF2-HMAC-SHA3-256 (RFC 8018 over FIPS 202) |
| scrypt(password, salt, n, r, p, dklen) -> Bytes | scrypt memory-hard KDF (RFC 7914), n power of two |
| rsa_pkcs1_v15_encrypt(msg, n, e, rand_ps) -> Bytes | RSAES-PKCS1-v1.5 encrypt (RFC 8017 §7.2) |
| rsa_pkcs1_v15_decrypt(ct, n, d) -> Bytes | RSAES-PKCS1-v1.5 decrypt |
| rsa_pkcs1_v15_sign(msg, n, d) -> Bytes | RSASSA-PKCS1-v1.5 sign (SHA-256) |
| rsa_pkcs1_v15_verify(msg, sig, n, e) -> Bool | RSASSA-PKCS1-v1.5 verify |
| rsa_oaep_encrypt(msg, n, e, seed, label) -> Bytes | RSAES-OAEP encrypt (SHA-256) |
| rsa_oaep_decrypt(ct, n, d, label) -> Bytes | RSAES-OAEP decrypt |
| rsa_pss_sign(msg, n, d, salt) -> Bytes | RSASSA-PSS sign (SHA-256) |
| rsa_pss_verify(msg, sig, n, e, salt_len) -> Bool | RSASSA-PSS verify |
| ed25519_public_key(seed) -> Bytes | Derive 32-byte Ed25519 public key |
| ed25519_sign(seed, message) -> Bytes | Ed25519 sign (RFC 8032), 64-byte sig |
| ed25519_verify(public_key, message, sig) -> Bool | Ed25519 verify |
| x25519(scalar, u) -> Bytes | X25519 scalar mult (RFC 7748), DH shared secret |
| x25519_public_key(private_key) -> Bytes | Derive X25519 public key (base u=9) |
| crc32 / crc32c(data : Bytes) -> Bytes | CRC-32 (IEEE) / CRC-32C, 4-byte big-endian |
| siphash_2_4(key, data : Bytes) -> Bytes | SipHash-2-4 (64-bit), key 16 bytes → 8 bytes |
| sealed_box_seal(master_key, nonce, pt, aad, ctx) -> Bytes | AEAD envelope (HKDF + AES-256-GCM) |
| sealed_box_open(master_key, envelope, aad, ctx) -> Result[Bytes, String] | Open envelope, Err on auth failure |
| base64_encode(data : Bytes) -> String | Base64 encode (RFC 4648) |
| base64_decode(encoded : String) -> Bytes | Base64 decode |
| base64_decode_or(encoded : String) -> Result[Bytes, String] | Base64 decode, Err on malformed input |
| bytes_to_hex(data : Bytes) -> String | Bytes → lowercase hex |
| hex_to_bytes(hex : String) -> Bytes | hex → Bytes (aborts on bad input) |
| hex_to_bytes_or(hex : String) -> Result[Bytes, String] | hex → Bytes, Err on bad input |
| bytes_equal(a, b : Bytes) -> Bool | Constant-time comparison |
moon bench| Algorithm | 1 KiB (approx.) |
|---|---|
| MD5 | ~8.5 µs |
| SHA-256 | ~16 µs |
| SHA-512 | ~14 µs |
| SHA3-256 | ~140 µs |
| BLAKE2b | ~27 µs |
| BLAKE3 | ~46 µs |
| HMAC-SHA256 | ~23 µs |
| HMAC-SHA3-256 | ~213 µs |
| HMAC-SHA3-512 | ~338 µs |
| AES-128-CMAC | ~347 µs |
| SipHash-2-4 | ~4.2 µs |
| CRC32 / CRC32C | ~4.7 µs |
| sealed_box_seal | ~588 µs (HKDF + AES-256-GCM) |
| scrypt (N=1024,r=8,p=1,dk32) | ~84 ms (memory-hard KDF) |
| Argon2id (t=1,m=64,p=1,dk16) | ~1 ms (memory-hard KDF) |
| ECDSA P-256 sign | ~270 ms (BigInt affine, correctness-first) |
| ECDSA P-256 verify | ~540 ms (two scalar mults) |
| AES-256-SIV encrypt 1KiB | ~950 µs (S2V + AES-CTR) |
| AES-128-KW wrap 32B | ~146 µs |
| ChaCha20 | ~46 µs |
| AES-256-CBC | ~315 µs (table-based GF mul) |
| AES-256-GCM | ~420 µs (table-based) |
| Base64 encode | ~10 µs |
| Hex encode | ~6.7 µs |
moon testmoon check --deny-warn
moon fmt --check
moon info
moon test --deny-warn
moon bench # run the benchmark suitemoon login # one time, with the account that owns cc06b
moon publish # publishes the current versionPure-MoonBit crypto primitives: SHA-1/2 (incl. SHA-512/224/256), SHA-3, Keccak-256, SHAKE/cSHAKE, BLAKE2b/BLAKE2s/BLAKE3 (+keyed), RIPEMD-160, HMAC/Poly1305/CMAC/KMAC/GMAC, AES-CBC/GCM/CTR/CCM/KW/SIV, ChaCha20/XChaCha20 + Salsa20, HKDF/PBKDF2/scrypt/Argon2, RSA (PKCS1-v1.5/OAEP/PSS), ECDSA P-256, Ed25519/Ed25519ctx/Ed25519ph, X25519, HOTP/TOTP (SHA-1/256/512), SipHash, CRC32/CRC32C/CRC-64/Adler-32, Base64/Hex, sealed-box envelope