tc_threefish
The Threefish tweakable block ciphers with 256-, 512- and 1024-bit blocks, the
core of the Skein hash. Every engine implements the
tc_block_cipher traits.
The crate is no_std, needs no allocator by default and contains no unsafe
code. It depends on tc_block_cipher and
tc_zeroize, and on RustCrypto's
threefish only with the default-off
rustcrypto feature.
Requires Rust 1.85 or later (edition 2024) for the default build and the
alloc feature. The optional rustcrypto feature follows the minimum Rust
version of the threefish crate instead, which is 1.85 for threefish 0.6.0.
Traits
ThreefishParams— aKeyParamsthat also supplies an optional 16-byte tweak; implement it to pass a key and tweak from your own type.
Types
Threefish256Engine— 256-bit block with a 32-byte key; constant time.Threefish512Engine— 512-bit block with a 64-byte key; constant time.Threefish1024Engine— 1024-bit block with a 128-byte key; constant time.ThreefishEngine— the engine behind the three aliases, on the RustCrypto engine withrustcrypto, otherwise on the portable engine; constant time.ThreefishPortableEngine— portable Threefish after Bouncy Castle, which derives each subkey while processing a block; the faster engine for both key setup and blocks; constant time.ThreefishRustCryptoEngine(rustcrypto) — RustCrypto'sthreefish, which expands every subkey ininit; constant time.ThreefishParamsRef— a borrowed key with an optional borrowed tweak.ThreefishParamsOwned(alloc) — the same, owning the key and tweak and wiping them on drop.
The three engine types take a const parameter that counts 64-bit block words;
only 4, 8 and 16 compile. Each engine takes its key and tweak through any
ThreefishParams. The key must
be one block long and the tweak, when present, 16 bytes; an absent tweak is all
zero. Another length returns InitError::InvalidKeyLength or
InitError::InvalidTweakLength and keeps the previous key, tweak and direction.
process_block transforms the first block and returns its length, returning
BlockError::NotInitialised before init and BlockError::BufferTooShort
for a buffer shorter than a block, without touching the output. Display
writes the variant name without inspecting key material.
The constant TWEAK_BYTES is 16, and THREEFISH_256_ALGO_NAME,
THREEFISH_512_ALGO_NAME and THREEFISH_1024_ALGO_NAME hold the names. Every
engine implements Default and has const fn new.
Features
alloc(off by default) — addsThreefishParamsOwned.rustcrypto(off by default) — addsThreefishRustCryptoEngine, whichThreefishEnginethen uses; pulls in thethreefishcrate and its minimum Rust version. This makesThreefishEngineslower, 5 to 10 times for key setup and up to twice for blocks in BENCHES.md; useThreefishPortableEnginedirectly where speed matters.
Usage
[]
= "0.1.0"
= "0.1.0"
use ;
use ;
let key = ;
let tweak = ;
let mut engine = new;
engine
.init
.expect;
let mut ciphertext = ;
assert_eq!;
The crate and engine documentation carry executable examples.
Security
Every engine is constant time with respect to the key, the tweak and the block contents: both backends use only additions, XORs and rotations, and their schedule indices follow the public round number.
Engines keep the key and tweak, or the RustCrypto engine its expanded
schedule, rather than borrowing the caller's, and wipe them when they are
replaced and on drop; the RustCrypto engine does so through the threefish
crate's zeroize support, which the feature enables. ThreefishParamsOwned wipes
its key and tweak on drop. Wiping does not reach the caller's buffers or copies
left in registers and on the stack.
This is a block-cipher primitive, not a message-encryption format. It supplies no padding, mode of operation or authentication.
Validation
Every engine is tested against the vectors of the Skein 1.3 submission and the
Bouncy Castle tests for every block size, with zero and nonzero tweaks, in both
directions, and against RustCrypto's threefish with random keys, tweaks and
blocks for every block size. Contract tests cover error state, untouched output
on errors, preserved output tails, absent tweaks and third-party parameter
types. A test requires every engine API to document whether it is constant or
variable time.
Benchmark results for both engines, and the commands to reproduce them, are in BENCHES.md.
Missing public documentation and unsafe code are rejected by crate-level
lints.
Run these commands from the workspace root:
cargo test -p tc_threefish --locked
cargo test -p tc_threefish --locked --all-features
cargo clippy -p tc_threefish --all-targets --all-features --locked -- -D warnings
cargo fmt -p tc_threefish --check
cargo doc -p tc_threefish --no-deps --all-features --locked
Before a release, check the archive contents and run publication validation from a committed checkout:
cargo package -p tc_threefish --list --locked
cargo publish -p tc_threefish --dry-run --locked
The archive includes both license texts, this README, the changelog, the
benchmark results, the source, the integration tests and the benchmark. It must
not include target/ or other build artifacts.
License
Licensed under either the MIT license or the Apache License, Version 2.0, at your option.