Expand description
§arcana — classical cryptography for the krypteia workspace
Pure-Rust implementations of widely-used classical primitives —
hash functions, symmetric ciphers, AEAD modes, RSA, ECDSA / ECDH,
EdDSA, X25519, and X448 — sharing the same side-channel
countermeasure toolkit (silentops)
used by the post-quantum side of the workspace
(quantica).
Zero external runtime dependencies (only std / alloc and the
workspace-local silentops); constant-time on the data path.
§Algorithms
§Hash functions (hash)
| Algorithm | Output | Module |
|---|---|---|
| SHA-1 | 160 b | hash::sha1::Sha1 (legacy) |
| SHA-224 | 224 b | hash::sha224::Sha224 |
| SHA-256 | 256 b | hash::sha256::Sha256 |
| SHA-384 | 384 b | hash::sha384::Sha384 |
| SHA-512 | 512 b | hash::sha512::Sha512 |
| SHA-512/224 | 224 b | hash::sha512_trunc::Sha512_224 |
| SHA-512/256 | 256 b | hash::sha512_trunc::Sha512_256 |
| SHA3-224 | 224 b | hash::sha3::Sha3_224 |
| SHA3-256 | 256 b | hash::sha3::Sha3_256 |
| SHA3-384 | 384 b | hash::sha3::Sha3_384 |
| SHA3-512 | 512 b | hash::sha3::Sha3_512 |
| SHAKE128 | XOF | hash::sha3::Shake128 |
| SHAKE256 | XOF | hash::sha3::Shake256 |
| cSHAKE128 | XOF | hash::sha3::CShake128 |
| cSHAKE256 | XOF | hash::sha3::CShake256 |
| BLAKE2b | 1-512 b | hash::blake2::Blake2b |
| BLAKE2s | 1-256 b | hash::blake2::Blake2s |
| RIPEMD-160 | 160 b | hash::ripemd160::Ripemd160 (legacy) |
§Symmetric ciphers and modes (cipher)
| Algorithm | Module |
|---|---|
| AES-128 / 192 / 256 | cipher::aes |
| DES, Triple-DES (EDE) | cipher::des |
| ECB, CBC, CTR, GCM modes | cipher::modes |
| AES-CCM (RFC 3610) AEAD | cipher::ccm |
| AES-XTS (IEEE 1619) disk crypto | cipher::xts |
| ChaCha20 (RFC 8439) | cipher::chacha20 |
| Poly1305 one-time MAC | cipher::poly1305 |
| ChaCha20-Poly1305 AEAD | cipher::chacha20poly1305 |
| XChaCha20-Poly1305 AEAD | cipher::xchacha20poly1305 (24-byte nonce) |
In addition to these one-shot, function-oriented APIs, a
stateful streaming Cipher object lives in
cipher::ctx. It wraps the AES / DES / 3DES block ciphers
with the ECB / CBC / CTR modes behind a uniform
init / update / finalize cycle, with caller-provided output
buffers (no allocation required) and configurable padding
(None, Pkcs7, Iso9797M1, Iso9797M2, AnsiX923). AEAD
modes intentionally stay function-oriented to avoid releasing
unverified plaintext during streaming decryption.
§Message authentication codes (mac)
A streaming MAC object lives in mac::ctx, exposing a
uniform init / update / sign | verify cycle across four
families:
| Family | Algorithms | Standard |
|---|---|---|
| HMAC | SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256/384/512, RIPEMD-160 | RFC 2104, FIPS 198-1 |
| CMAC | AES-128 / 192 / 256, Triple-DES | NIST SP 800-38B, RFC 4493 |
| KMAC | KMAC128, KMAC256 | FIPS SP 800-185 |
| GMAC | AES-128 / 192 / 256 | NIST SP 800-38D |
Three init variants distinguish families that need different
inputs: init(key) (HMAC, CMAC, KMAC default),
init_kmac(key, custom) (KMAC with explicit customization
string), and init_with_nonce(key, nonce) (GMAC, 12-byte
unique nonce). verify accepts truncated tags and runs in
constant time. Poly1305 is intentionally not routed
through Mac because it is a one-time MAC and would be unsafe
behind an “init then reuse” object.
§RSA (rsa)
| Padding | Module |
|---|---|
| PKCS#1 v1.5 encryption + signature | rsa::pkcs1 (8 hash functions supported) |
| OAEP encryption (PKCS#1 v2.2) | rsa::oaep |
| RSASSA-PSS signature (PKCS#1 v2.2) | rsa::pss |
§Elliptic curve cryptography (ecc)
ECDSA / ECDH / SEC1-compressed / signature DER are all unified
behind a single ecc::curves::Curve trait, implemented by:
| Wrapper | Curve |
|---|---|
ecc::curves::P256 | NIST P-256 |
ecc::curves::P384 | NIST P-384 |
ecc::curves::P521 | NIST P-521 |
ecc::curves::Secp256k1 | secp256k1 (SECG) |
ecc::curves::BrainpoolP256r1 | BSI / RFC 5639 |
ecc::curves::BrainpoolP384r1 | BSI / RFC 5639 |
ecc::curves::BrainpoolP512r1 | BSI / RFC 5639 |
Edwards / Montgomery curves live in standalone modules because
their algebraic shape doesn’t fit the short-Weierstrass Curve
trait:
| Algorithm | Module |
|---|---|
| Ed25519, Ed25519ctx, Ed25519ph | ecc::eddsa |
| X25519 ECDH (Curve25519) | ecc::x25519 |
| X448 ECDH (Curve448) | ecc::x448 |
Ed448 is planned but not yet implemented.
§Cargo features
| Feature | Default | Effect |
|---|---|---|
std | no | Reserved for future no_std work (currently a no-op). |
rust-crypto-traits | no | Pulls in digest 0.10 / cipher 0.4 / signature 2.0 and activates the bridge module, which wraps every hash in a digest::Digest impl for ecosystem interop (HMAC, HKDF, PBKDF2, Argon2, …). |
Default builds are zero-dependency (only the workspace-local
silentops crate). The rust-crypto-traits feature is opt-in
and pulls in definitions only (no crypto code).
§Quick start
// SHA-256 one-shot hash
use arcana::hash::sha256::Sha256;
use arcana::Hasher;
let digest = Sha256::hash(b"hello, arcana");
assert_eq!(digest.len(), 32);// AES-128-GCM AEAD
use arcana::cipher::aes::Aes128;
use arcana::cipher::modes::Gcm;
use arcana::BlockCipher;
let key = [0x42u8; 16];
let nonce = [0u8; 12];
let cipher = Aes128::new(&key);
let (ct, tag) = Gcm::encrypt(&cipher, &nonce, b"aad", b"plaintext");
let pt = Gcm::decrypt(&cipher, &nonce, b"aad", &ct, &tag).unwrap();
assert_eq!(pt, b"plaintext");// X25519 ECDH key exchange
use arcana::ecc::x25519::{x25519_derive_public, x25519_ecdh};
let alice_sk = [0x77u8; 32];
let bob_sk = [0x88u8; 32];
let alice_pk = x25519_derive_public(&alice_sk);
let bob_pk = x25519_derive_public(&bob_sk);
let shared_a = x25519_ecdh(&alice_sk, &bob_pk);
let shared_b = x25519_ecdh(&bob_sk, &alice_pk);
assert_eq!(shared_a, shared_b);§Examples
cargo run -p arcana --release --example hash_demo
cargo run -p arcana --release --example aes_demo
cargo run -p arcana --release --example rsa_demo
cargo run -p arcana --release --example ecdsa_demo
cargo run -p arcana --release --example eddsa_demo
cargo run -p arcana --release --example x25519_demo§Side-channel guarantees
The full threat model and per-algorithm countermeasure roadmap
lives in arcana/doc/sca/ (HTML rendered by ./gendoc.sh arcana). The roadmap items referenced here (T1-A, T1-C,
T2-D …) are defined there. This section is a quick-reference
summary; for evaluation evidence, refer to the annex.
§Always-on
| Defence | Scope |
|---|---|
| Constant-time tag comparison | All AEAD decrypt, MAC verify, ECDSA verify (via silentops::ct_eq) |
| Constant-time field arithmetic | ECC (P-256, P-384, P-521, secp256k1, Brainpool), Ed25519, X25519, X448 |
| CT Montgomery ladder | ecc::curve::scalar_mul_point — branch-free across all 7 short-Weierstrass curves |
core::hint::black_box shielding | ecc::field mask selects, to keep LLVM from recovering branches at opt-level >= 2 |
| No secret-dependent branches | Hash, symmetric, HMAC, CMAC, KMAC, GMAC |
| RFC 6979 deterministic nonce | ECDSA — eliminates nonce-reuse attacks (but see fault-attack note below) |
silentops::ct_zeroize available | Caller can zeroize sensitive buffers explicitly |
§Open vulnerabilities (evaluation gaps — track in roadmap)
| Primitive | Issue | Roadmap item |
|---|---|---|
| AES S-box | Table-based lookup — cache-line leaks on CPUs with shared L1 | T1-A (fixsliced AES port from Adomnicai-Peyrin TCHES 2021/1) |
| RSA-CRT decrypt | Bellcore single-fault → factorisation of N | T1-C (Aumüller 2002, formally verified) |
| RSA bigint | Montgomery_mul, cmp, pow_mod not formally CT-audited | T1-E |
| ECDSA / ECDH | Minerva-class bit-length leak audit not yet completed | T1-B |
| Ed25519 / ECDSA-RFC 6979 | Single-fault on deterministic signing → key recovery | T1-D (hedged signatures, CFRG draft) |
| HMAC-SHA-2 | Carry-based DPA breaks unmasked HMAC-SHA-2 in 30 K – 275 K traces | T2-D (first-order Boolean masking) |
| DES / 3DES S-boxes | Table-based; legacy only | unscoped — avoid on SCA-sensitive targets |
§Not yet implemented
- Zeroize-on-Drop: typed key wrappers (
ecc::curves::SecretKey,ecc::eddsa::Ed25519SecretKey,rsa::rsa::RsaSecretKey) currently do not implementDropwithsilentops::ct_zeroize. Callers should zeroize sensitive buffers explicitly. Roadmap itemT2-E. - DPA / EM / multi-fault: out of scope for the current evaluation profile; tier-4 items in the SCA annex.
§Native API vs RustCrypto bridge
By default, this crate exposes its own trait hierarchy
(Hasher, Xof, BlockCipher, …). Enable
rust-crypto-traits to additionally activate the bridge
module which implements digest::Digest for the hash
functions. The two universes are intentionally separate so the
native modules never depend on a specific external crate
version.
Modules§
- cipher
- Symmetric ciphers: AES, DES, 3DES.
- ecc
- Elliptic curve cryptography: ECDSA, EdDSA.
- encoding
- Key serialization: DER, PEM, PKCS#1, PKCS#8, SEC1, SPKI. Key serialization: DER (ASN.1), PEM, PKCS#1, PKCS#8, SPKI, SEC1.
- hash
- Hash functions: SHA-1, SHA-2, SHA-3, RIPEMD-160.
- mac
- Message authentication codes (HMAC, CMAC, KMAC, GMAC). Message Authentication Codes (MACs).
- rsa
- RSA encryption and signatures. RSA encryption and signatures.
Traits§
- Block
Cipher - Trait for symmetric block ciphers operating on a fixed block size.
- Hasher
- Trait for hash functions (fixed-output).
- Public
KeyEncryption - Trait for public-key encryption schemes.
- Signature
Scheme - Trait for digital signature schemes that produce fixed-shape keys and signatures (no per-call hash parameter).
- Xof
- Trait for extendable-output functions (XOF) such as SHAKE128 / SHAKE256.