Collection of block cipher algorithms written in pure Rust

Overview

RustCrypto: block ciphers Project Chat dependency status

Collection of block ciphers and block modes written in pure Rust.

Warnings

Currently only the aes crate provides constant-time implementation and has received a third-party security audit.

Other crates in this repository are not implemented in a constant-time manner and have not yet received any formal cryptographic and security reviews.

It's generally recommended not to use other cipher implementations in this repository besides the aes crate.

USE AT YOUR OWN RISK.

Supported algorithms

Name Crate name crates.io Docs Build Status
AES (Rijndael) aes crates.io Documentation aes build
Blowfish blowfish crates.io Documentation build
CAST5 (CAST-128) cast5 crates.io Documentation build
DES + 3DES (DEA, 3DEA) des crates.io Documentation build
IDEA idea crates.io Documentation build
Kuznyechik (GOST R 34.12-2015) kuznyechik crates.io Documentation build
Magma (GOST 28147-89 and GOST R 34.12-2015) magma crates.io Documentation build
RC2 (ARC2) rc2 crates.io Documentation build
Serpent serpent crates.io Documentation build
SM4 sm4 crates.io Documentation build
Twofish twofish crates.io Documentation build
Threefish threefish crates.io Documentation build

Additional crates

Crate name crates.io Docs Build Status
block-modes crates.io Documentation build
gost-modes crates.io Documentation build

Minimum Supported Rust Version

All crates in this repository support Rust 1.22 or higher. (except aesni and aes crates, which require Rust 1.27) In future minimum supported Rust version can be changed, but it will be done with the minor version bump.

Usage

Block cipher crates provide only bare block cipher implementations. For most applications you will need to use some block cipher mode of operation which are generically implemented in the block-modes crate.

Some block modes (CTR, CFB, OFV) transform block ciphers into stream ciphers.Such modes are published under separate crates in the RustCrypto/stream-ciphers repository.

Lets use AES128-CBC with PKCS7 padding to show an example:

use aes::Aes128;
use block_modes::{BlockMode, Cbc};
use block_modes::block_padding::Pkcs7;
use hex_literal::hex;

// create an alias for convenience
type Aes128Cbc = Cbc<Aes128, Pkcs7>;

let key = hex!("000102030405060708090a0b0c0d0e0f");
let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
let plaintext = b"Hello world!";
let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();

// buffer must have enough space for message+padding
let mut buffer = [0u8; 32];
// copy message to the buffer
let pos = plaintext.len();
buffer[..pos].copy_from_slice(plaintext);
let ciphertext = cipher.encrypt(&mut buffer, pos).unwrap();

assert_eq!(ciphertext, hex!("1b7a4c403124ae2fb52bedc534d82fa8"));

// re-create cipher mode instance and decrypt the message
let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
let mut buf = ciphertext.to_vec();
let decrypted_ciphertext = cipher.decrypt(&mut buf).unwrap();

assert_eq!(decrypted_ciphertext, plaintext);

With an enabled std feature (which is enabled by default) you can use encrypt_vec and decrypt_vec methods:

let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
let ciphertext = cipher.encrypt_vec(plaintext);

assert_eq!(ciphertext, hex!("1b7a4c403124ae2fb52bedc534d82fa8"));

let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
let decrypted_ciphertext = cipher.decrypt_vec(&ciphertext).unwrap();

assert_eq!(decrypted_ciphertext, plaintext);

Note that this example does not use any authentification which can lead to serious vulnarabilities! For Message Authentication Code implementations take a look at RustCrypto/MACs repository.

License

All crates licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • AES implementation should be chosen at runtime rather than compile time

    AES implementation should be chosen at runtime rather than compile time

    AES implementation should be chosen at runtime rather than compile time, otherwise it makes people very hard to ship products with this crate, because they cannot choose the environment a product would be run on.

    aes 
    opened by upsuper 36
  • aes: autodetection support for AES-NI

    aes: autodetection support for AES-NI

    Closes #25.

    Adds an off-by-default autodetect feature which the cpuid-bool crate to detect whether AES-NI is available when compiling on i686/x86_64 architectures.

    aes 
    opened by tarcieri 24
  • Missing AES-KW

    Missing AES-KW

    AFAICS, there is currently no implementation of AES-KW. Is that on the roadmap?

    The only mention I could find was offer here to submit code for this mode.

    opened by cryptographix 17
  • added HCTR

    added HCTR

    ~~Not quite ready for publishing.~~ Ready for review!

    • [x] Generic over the block cipher and AXU universal hash function.

    • [x] Documentation.

    • [ ] Review.

    • [ ] Publish to crates.io under RustCrypto

    Why is Aes + ctr about half the performance of aesni w\ the ctr feature?

    Because the latter benefits from XMM registers for the counter, while the former is more general and not currently checking if it can use XMM registers to boost aes in this case.

    opened by WildCryptoFox 16
  • aes: implement `Zeroize` for aes keys

    aes: implement `Zeroize` for aes keys

    The crate feature zeroize was previously present, but unused.

    This implements zeroization on drop for all aes types in the software and aesni implementations, if the zeroize feature is enabled.

    This PR does not include support for the armv8 implementation. I do not have access to hardware to test it and a clean implementation is also likely blocked on the zeroize crate implementing Zeroize for the inner uint8x16_t type used.

    Still I thought this might be a useful patch even without armv8 support. If you'd prefer, I can also add some documentation describing this limitation to users.

    opened by aticu 15
  • Added Serpent

    Added Serpent

    Serpent1 first implementation. Some work to do for optimization.

    Bitslicing implemented. No benchmark.

    Tested on 128bits, 192bits and 256bits key official vectors.

    There is one panic in the code (in round and round_inverse), should it returns an Err instead?

    EDIT : Bitslicing is now implemented. No more panic in the code.

    opened by Slals 14
  • aes: feature flags are not additive

    aes: feature flags are not additive

    The aes crate has two feature flags, both of which remove functionality:

    https://github.com/RustCrypto/block-ciphers/blob/f68ad0db49c2136e9d3b3a5d3b2e098782b030a8/aes/Cargo.toml#L29-L31

    This is an incorrect use of Cargo feature flags. From my comments at https://github.com/SergioBenitez/cookie-rs/pull/176#issuecomment-834028088, which focus on force-soft:

    This seems like an ill-fitted, perhaps incorrect use of features. Features should only be used to add capabilities, but force-soft removes the ability to make use of AES-NI. The consequence is that a consumer of aes has little control over whether AES-NI is actually used: all it takes is a single dependency, direct or indirect, enabling force-soft to disable AES-NI completely, without recourse.

    I would suggest what I would consider to be the "correct" approach: always enable AES-NI if it is known to statically exist, and otherwise, add a feature that adds the ability to dynamically detect its existence, which of course becomes a no-op if the first condition is met.

    Somewhere in the codebase, you already have 2 versions of the code. Let's call them aes::ni and aes::soft.

    Effectively, we want this:

    fn aes() {
        #[cfg(have_aesni)]
        return aes::ni();
    
        #[cfg(feature(autodetect)]
        if detect(aes-ni) { return aes::ni() }
    
        aes::soft()
    }
    

    This structure makes it clear that autodetect is additive; it adds the ability to dynamically detect AES-NI and removes nothing otherwise; there is no not(feature(autodetect)). This is the only fully correct use of features. If the code that requires 1.49 is restricted to detect, then MSRV can remain at 1.41 as long as autodetect is not enabled.

    The same reasoning applies to the compact feature. If it must exist at all, a non-feature --cfg aes_compact is the correct approach. This restores control of expected performance to the top-level binary as opposed to any crate in the transitive closure of dependencies.

    See also the full comment thread in https://github.com/SergioBenitez/cookie-rs/pull/176.

    aes 
    opened by SergioBenitez 13
  • Add feature to disable aesni target feature compile time checks

    Add feature to disable aesni target feature compile time checks

    When using runtime is_x86_feature_detected macro to check if I could use aesni, I had to disable the checks. Is it possible to include this little feature to allow usage of aesni without compile time checks?

    opened by cheme 13
  • aes: soft `hazmat` backend

    aes: soft `hazmat` backend

    The hazmat API provides access to the raw AES cipher round, equivalent inverse cipher round, mix columns, and inverse mix column operations.

    This PR wires up support for these operations in the "soft" backend (or more specifically, both the 32-bit and 64-bit fixsliced backends).

    It would benefit from a parallel API instead of what's currently provided, however that's left for future work.

    opened by tarcieri 12
  • Implemented DES

    Implemented DES

    This is an implementation of DES. The included benchmark gives 2 MB/s performance, I'm not sure if that's good or bad. Most of the trickiness with the implementation is the fact that the most significant bit is considered bit zero instead of the least significant bit. It's possible I did some unnecessary shifting/arithmetic to account for this.

    Note that the crate name des is taken on crates.io, so we might have to change that name.

    I'm planning on adding more test cases. I have a file of (input, key, output) tuples that I need to parse and turn into the correct format for tests used in this repo.

    opened by gsingh93 12
  • Add implementation of Camellia

    Add implementation of Camellia

    This is implemented based on RFC 3713 and refer to Botan. Test vectors are from NESSIE, and tested on all three key sizes of Camellia.

    This partially solves #1.

    opened by sorairolake 11
  • initial rc5 impl

    initial rc5 impl

    Implemented RC5 based on the revised paper. Got test vector at: https://www.ietf.org/archive/id/draft-krovetz-rc6-rc5-vectors-00.txt

    Core impl features a generic impl using typenum and generic array. Const generic implementation without generic expressions doesn't seem appropriate.

    I was not sure what api would work best with the cipher crate so i decided to propagate the InOut ptr. Put all the core fn behind a trait to avoid rewriting generic bounds.

    For now only 32, 20, 20 parametrization made public.

    opened by antonio-dropulic 0
  • Gift

    Gift

    This pull request contains a constant-time software fixslicing implementation of the GIFT block cipher, based on the C implementation of the original authors found here.

    Gift is a PRESENT based block cipher with focus on energy efficiency and a small memory footprint making it ideal for usage in resource constrained environments. It gained some popularity as part of GIFT-COFB, which is a finalist in the current NIST lightweight cryptography competition as well as SUNDAE-GIFT.

    This pull request comes with an implementation of GIFT-128, meaning Gift operating on 128-bit blocks, though I am planning on implementing GIFT-64 in the future.

    It passes all test vectors and performs at ~44.5 cpb on an Intel Core i7 8700k with 3.7GHz core clock, while the C version "only" performs at ~47.1 cpb on the same machine.

    opened by Schmid7k 0
  • magma: provide a way to support both gost28147 and magma subkeys order

    magma: provide a way to support both gost28147 and magma subkeys order

    GOST 28147-89 and GOST R 34.12-2015 ended up using different subkeys schedule during encryption. For the non-formal description see the RFC. Please provide a way to support both of them. From my experience the easies (and most probably the most correct) way to achieve this is to specify Gost89 ciphers (original subkeys order) using all defined SBox-es (including the TC26-A one) and to specify a separate (Magma) cipher fixed to use TC26-A S-Box and using "new" subkeys order.

    help wanted 
    opened by lumag 1
  • Add implementation of Speck

    Add implementation of Speck

    Based on https://eprint.iacr.org/2013/404.pdf Using testvectors from Appendix C of the aforementioned paper.

    Notes:

    • I implemented this based on the cipher v0.4 branch, so this should only be merged after that branch is merged.
    • The crate name is currently speck, however, there's already a crate with that name on crates.io, so I think we need to come up with a different name? I've never published on crates.io before.
    • The actual code itself uses a macro system similar to AES, with the code inside the macro definition based on SM4.
    • I'm not very experienced in Rust, so there might be some things that could be done better. Please let me know!

    This partially solves #1.

    opened by jvdsn 8
  • Optional compact round keys for AES fixslice

    Optional compact round keys for AES fixslice

    In the current fixslice implementation there is some redundancy in the way keys are stored (2x for fixslice32, 4x for fixslice64). This enables the round keys to simply be XORed in for each round.

    It is possible to store the round keys in a compact format and expand them in each round, which requires a few additional instructions (prototype code for fixslice64 puts this at 10% slower; the penalty will be smaller for fixslice32). The memory saving for the key storage is then: 50% i.e. 176/208/240 bytes for fixslice32 AES 128/192/256 respectively, or 75% i.e. 528/624/720 bytes for fixslice64.

    Is there a standard cfg attribute for constrained memory devices, and/or should this project support a feature making smaller memory footprint a priority?

    aes 
    opened by peterdettman 2
Owner
Rust Crypto
Cryptographic algorithms written in pure Rust
Rust Crypto
AEGIS cipher for Rust.

AEGIS for Rust This is a Rust implementation of the AEGIS authenticated cipher, ported from the Zig standard library. AEGIS is extremely fast on CPUs

Frank Denis 12 Nov 24, 2022
ROT Cipher implementation in rust, supports rot1 to rot25.

rotcipher-rs ROT Cipher implementation in rust, supports rot1 to rot25. Supported ROT ciphers ROT1 up to ROT25, it is also possible to make custom ROT

null 0 Sep 7, 2022
Bessie - an authenticated, chunked cipher based on BLAKE3

Bessie Bessie is an authenticated, chunked cipher based on BLAKE3. Right now it's in the early design stages. See design.md. Although the Bessie ciphe

Jack O'Connor 12 Dec 9, 2022
A general solution for commonly used crypt in rust, collection of cryptography-related traits and algorithms.

Crypto-rs A general solution for commonly used crypt in rust, collection of cryptography-related traits and algorithms. This is a Rust implementation

houseme 4 Nov 28, 2022
Collection of cryptographic hash functions written in pure Rust

RustCrypto: hashes Collection of cryptographic hash functions written in pure Rust. All algorithms reside in the separate crates and implemented using

Rust Crypto 1.2k Jan 8, 2023
A collection of algorithms that can do join between two parties while preserving the privacy of keys on which the join happens

Private-ID Private-ID is a collection of algorithms to match records between two parties, while preserving the privacy of these records. We present tw

Meta Research 169 Dec 5, 2022
A (mostly) pure-Rust implementation of various cryptographic algorithms.

Rust-Crypto A (mostly) pure-Rust implementation of various common cryptographic algorithms. Rust-Crypto seeks to create practical, auditable, pure-Rus

null 1.2k Dec 27, 2022
A small block explorer for geth PoAs written in rust

Tesseracts A minimalistic block explorer initially created to learn rust. This block explorer has been created as a rust self-learning project to give

adria0.eth 15 Jun 25, 2022
Elliptic-curves - Collection of pure Rust elliptic curve implementations (e.g. P-256, P-384, secp256k1)

RustCrypto: Elliptic Curves General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic cu

Rust Crypto 386 Dec 27, 2022
A very bare-bone Block Chain demo that purely implemented by Rust and yew

Intro bloc is one of bare-bone blockchain demo written by Rust, Yew during my learning BlockChain, about years ago. see demo here It just demonstrate

null 4 Dec 16, 2022
Example of a block root with a Verkle state root

Example of a block root with a Verkle state root Block content This is a standard RLP block containing 3 transactions, and an added VerkleProof field

Guillaume Ballet 25 Nov 25, 2022
The Stage 2 building block to reach the dream of DSNs with Bitcoin DeFi

rust-nostr Intro A complete suite of nostr Bitcoin libraries that can be used to develop Decentralized Social Networks (DSN) with integrated Bitcoin f

Raj 82 Jan 2, 2023
Substreams development kit for Ethereum chains, contains Firehose Block model and helpers as well as utilities for Ethereum ABI encoding/decoding.

Substreams Ethereum Substreams development kit for Ethereum chains, contains Rust Firehose Block model and helpers as well as utilities for Ethereum A

StreamingFast 15 Oct 25, 2022
Kinda functional block engine for testing bundles on jito-solana locally

Half Baked Block Engine About This is a half-baked block engine. It can be used for testing bundles running through jito-solana. Shortcomings The bare

null 8 Nov 16, 2022
Bindings for the etherscan API and other block explorers.

foundry-block-explorers Bindings for the etherscan.io web API and other block explorers. Examples use ethers_core::types::Chain; use foundry_block_exp

Foundry 7 Nov 3, 2023
Port path module (and tests) of nodejs to rust using the same algorithms.

rusty_nodejs_path Port path module (and tests) of nodejs to rust using the same algorithms. crates.io Documents Progress posix path.basename(path[, ex

Yunfei He 10 Sep 25, 2022
A Rust Library of China's Standards of Encryption Algorithms (SM2/3/4)

Libsm Libsm is an open source pure rust library of China Cryptographic Algorithm Standards. It is completed by a collaborative effort between the Cryp

CITAHub 149 Dec 23, 2022
A Rust Implementation of China's Standards of Encryption Algorithms(SM2/SM3/SM4)

gm-rs A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms(SM2/SM3/SM4) Usage Add this to your Cargo.toml: [depen

null 2 Oct 27, 2022
A template for writing CMSIS-Pack flash algorithms in Rust

Flash Algorithm Template This is a flash algorithm template for writing CMSIS-Pack flash algorithms in Rust. It can be used to generate new flash algo

probe.rs 5 Feb 11, 2023