Cryptographic Utilities

RecipeCratesCategories
subtlesubtlecat-cryptography
zeroizezeroizecat-cryptography

zeroize

zeroize zeroize-crates.io zeroize-github zeroize-lib.rs cat-cryptography cat-memory-management cat-os cat-no-std

"Zeroize" refers to the process of securely erasing sensitive data, such as cryptographic keys, passwords, or any other confidential information, from memory or storage. The goal is to ensure that the data cannot be recovered or reconstructed, preventing unauthorized access.

The zeroize crate securely clear secrets from memory. It guarantees that memory is zeroed, using an operation that will not be optimized away by the compiler. It is a portable pure-Rust implementation that works everywhere, even with WASM.

use zeroize::Zeroize;

fn main() {
    // Create a vector of sensitive data e.g. a password or key
    let mut sensitive_data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0];

    println!("Sensitive data before zeroizing: {:?}", sensitive_data);

    // Securely zeroize the sensitive data
    sensitive_data.zeroize();

    println!("Sensitive data after zeroizing: {:?}", sensitive_data);
}

subtle

subtle-website subtle subtle-crates.io subtle-github subtle-lib.rs cat-cryptography cat-no-std

subtle provides pure-Rust traits and utilities for writing constant-time cryptographic code. In cryptography, timing attacks exploit variations in execution time to infer secret information. Constant-time code aims to eliminate these variations, ensuring that the execution time of an operation is independent of the secret data.

It consists of a Choice type, and a collection of traits using Choice instead of bool, which are intended to execute in constant-time. The Choice type is a wrapper around a u8 that holds a 0 or 1.

The subtle crate is a low-level library and doesn't implement cryptographic algorithms itself. Instead, it provides the building blocks for developers to implement cryptographic algorithms in a way that minimizes the risk of timing attacks. It's typically used in low-level cryptographic libraries or when implementing custom cryptographic protocols.

use subtle::Choice;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
use subtle::CtOption;

// Pure-Rust traits and utilities for constant-time cryptographic
// implementations.

fn main() {
    // Example 1: Constant-time equality
    let a = 10u8;
    let b = 10u8;
    let c = 20u8;

    let a_eq_b: Choice = a.ct_eq(&b);
    let a_eq_c: Choice = a.ct_eq(&c);

    println!("a == b: {}", a_eq_b.unwrap_u8() == 1); // 1 for true, 0 for false
    println!("a == c: {}", a_eq_c.unwrap_u8() == 1);

    // Example 2: Conditional selection
    let x = 5u32;
    let y = 10u32;

    let condition = Choice::from(1); // 1 means true
    let selected: u32 = u32::conditional_select(&x, &y, condition);
    println!("Selected (condition true): {}", selected); // Output: 10

    let condition = Choice::from(0); // 0 means false
    let selected: u32 = u32::conditional_select(&x, &y, condition);
    println!("Selected (condition false): {}", selected); // Output: 5

    // Example 3: CtOption for handling potential failures in constant time
    // The CtOption<T> type represents an optional value similar to the
    // Option<T> type but is intended for use in constant time APIs.
    fn try_parse(s: &str) -> CtOption<u32> {
        if s.len() < 3 {
            CtOption::new(0, Choice::from(0)) // Return 0 and a false choice if the string is too short
        } else {
            CtOption::new(s.len() as u32, Choice::from(1)) // Return length and a true choice otherwise
        }
    }

    let short_str = "ab";
    let long_str = "abcd";

    let short_result: CtOption<u32> = try_parse(short_str);
    let long_result: CtOption<u32> = try_parse(long_str);

    let is_some: Choice = long_result.is_some();
    let is_none: Choice = short_result.is_none();
    println!("Long string is some: {}", is_some.unwrap_u8() == 1);
    println!("Short string is none: {}", is_none.unwrap_u8() == 1);

    // Example 4: Using `unwrap_or` to expose the underlying value
    let opt: CtOption<u8> = CtOption::new(10u8, Choice::from(1));
    let val: u8 = opt.unwrap_or(0);
    println!("Unwrapped value: {}", val);

    let none_opt: CtOption<u8> = CtOption::new(5u8, Choice::from(0));
    let default_val = none_opt.unwrap_or(0);
    println!("Unwrapped default value: {}", default_val);
}