### ISO/IEC 7816-4 Padding Example Source: https://context7.com/rustcrypto/utils/llms.txt Implements ISO/IEC 7816-4 padding, which appends a 0x80 byte followed by zero bytes. This method is suitable when a specific byte pattern is required for padding. ```rust use block_padding::{Padding, Pkcs7, ZeroPadding, Iso7816, AnsiX923, NoPadding}; use block_padding::array::{Array, typenum::U16}; fn iso7816_padding() { // ISO/IEC 7816-4 padding (0x80 followed by zeros) let msg = b"test"; let mut block: Array = [0xFF; 16].into(); block[..msg.len()].copy_from_slice(msg); Iso7816::pad(&mut block, msg.len()); // Result: "test\x80\x00\x00\x00..." assert_eq!(block[4], 0x80); assert_eq!(block[5], 0x00); let unpadded = Iso7816::unpad(&block).unwrap(); assert_eq!(unpadded, msg); } ``` -------------------------------- ### ANSI X9.23 Padding Example Source: https://context7.com/rustcrypto/utils/llms.txt Implements ANSI X9.23 padding, which uses zero bytes for padding and sets the last byte to the padding length. This is a common standard for financial data. ```rust use block_padding::{Padding, Pkcs7, ZeroPadding, Iso7816, AnsiX923, NoPadding}; use block_padding::array::{Array, typenum::U16}; fn ansi_x923_padding() { // ANSI X9.23: zeros with final byte = padding length let msg = b"test"; let mut block: Array = [0xFF; 16].into(); block[..msg.len()].copy_from_slice(msg); AnsiX923::pad(&mut block, msg.len()); // Result: "test\x00\x00...\x00\x0c" (last byte is 12 = padding count) assert_eq!(block[15], 12); // 12 padding bytes assert_eq!(block[5], 0x00); // zeros in between } ``` -------------------------------- ### Zero Padding Example Source: https://context7.com/rustcrypto/utils/llms.txt Applies zero padding by appending null bytes. Note that this method may not always be reversible if the original message itself contained trailing null bytes. ```rust use block_padding::{Padding, Pkcs7, ZeroPadding, Iso7816, AnsiX923, NoPadding}; use block_padding::array::{Array, typenum::U16}; fn zero_padding() { // Zero padding - simple but not always reversible let msg = b"data"; let mut block: Array = [0xFF; 16].into(); block[..msg.len()].copy_from_slice(msg); ZeroPadding::pad(&mut block, msg.len()); assert_eq!(&block[4..], &[0x00; 12]); } ``` -------------------------------- ### PKCS#7 Padding Example Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates PKCS#7 padding (RFC 5652) for block ciphers. Use this for AES encryption. It pads the message to a block boundary and unpads to recover the original message. ```rust use block_padding::{Padding, Pkcs7, ZeroPadding, Iso7816, AnsiX923, NoPadding}; use block_padding::array::{Array, typenum::U16}; fn pkcs7_padding() { // PKCS#7 padding (RFC 5652) - most common for AES let msg = b"Hello World!"; // 12 bytes let mut block: Array = [0x00; 16].into(); block[..msg.len()].copy_from_slice(msg); Pkcs7::pad(&mut block, msg.len()); // Result: "Hello World!\x04\x04\x04\x04" (4 padding bytes, each = 0x04) assert_eq!(&block[12..], &[0x04, 0x04, 0x04, 0x04]); // Unpad to recover original message let unpadded = Pkcs7::unpad(&block).unwrap(); assert_eq!(unpadded, msg); } ``` -------------------------------- ### Securely Zeroize Sensitive Data in Rust Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates how to use the `Zeroize` trait to securely erase sensitive data from memory, preventing it from being optimized away by the compiler. Includes examples for manual zeroing, automatic zeroing on drop, and custom struct implementations. ```rust use zeroize::{Zeroize, Zeroizing, ZeroizeOnDrop}; // Basic usage: manually zeroize a secret fn process_secret() { let mut secret = b"Air shield password: 1,2,3,4,5".to_vec(); // Use the secret... // Securely zero it when done secret.zeroize(); // secret is now all zeros } // Wrapper type that auto-zeroizes on drop fn auto_zeroize_example() { let secret = Zeroizing::new([0u8; 32]); // Use secret.as_ref() or secret.copy_from_slice() // Automatically zeroized when `secret` goes out of scope } // Custom derive for structs (requires `zeroize_derive` feature) #[derive(Zeroize, ZeroizeOnDrop)] struct Credentials { username: String, password: Vec, api_key: [u8; 32], } // Skip specific fields with attribute #[derive(Zeroize)] struct PartialSecret { #[zeroize(skip)] public_id: u64, // Not zeroized secret_key: [u8; 32], // Will be zeroized } // Works with all core types fn zeroize_primitives() { let mut num: u64 = 0xDEADBEEF; let mut arr: [u8; 16] = [0xFF; 16]; let mut slice: &mut [u8] = &mut [1, 2, 3, 4]; num.zeroize(); arr.zeroize(); slice.zeroize(); } ``` -------------------------------- ### Separate input and output buffers with InOutBuf Source: https://context7.com/rustcrypto/utils/llms.txt Illustrates using `inout::InOutBuf` with separate input and output buffers. Data is read from the input buffer and written to the output buffer. ```rust fn separate_buffers_example() { // Separate input and output buffers let input = [1u8, 2, 3, 4]; let mut output = [0u8; 4]; let inout_buf = InOutBuf::new(&input, &mut output).unwrap(); for inout in inout_buf { *inout.get_out() = inout.get_in() ^ 0xFF; } assert_eq!(output, [0xFE, 0xFD, 0xFC, 0xFB]); } ``` -------------------------------- ### Define CPU Word Size with cpubits! Macro Source: https://github.com/rustcrypto/utils/blob/master/cpubits/README.md Use this macro to define different `Word` types based on the detected CPU architecture (16, 32, or 64 bits). This allows for compile-time optimization. ```rust cpubits::cpubits! { 16 => { pub type Word = u16; } 32 => { pub type Word = u32; } 64 => { pub type Word = u64; } } ``` -------------------------------- ### Detect CPU Features in Rust with cpufeatures Source: https://context7.com/rustcrypto/utils/llms.txt Shows how to use the `cpufeatures` crate for runtime detection of CPU features like AES-NI, SHA extensions, and AVX on supported architectures. This allows for conditional use of hardware acceleration. ```rust // Define a module that detects AES and SHA CPU features #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] mod crypto_features { cpufeatures::new!(cpuid_aes_sha, "aes", "sha"); } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn use_hardware_acceleration() { use crypto_features::cpuid_aes_sha; // Initialize and get result in one call let token = cpuid_aes_sha::init(); if token.get() { println!("Hardware AES and SHA available - using fast path"); // Use AES-NI and SHA extensions } // Alternative: get value without keeping token let has_features = cpuid_aes_sha::get(); // Or get both at once let (token, has_features) = cpuid_aes_sha::init_get(); } // Detecting AVX2 for SIMD operations #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] mod simd_features { cpufeatures::new!(cpuid_avx2, "avx2"); } // Multiple feature sets for different algorithms #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] mod all_features { cpufeatures::new!(has_aes, "aes"); cpufeatures::new!(has_pclmulqdq, "pclmulqdq"); cpufeatures::new!(has_avx512f, "avx512f"); } ``` -------------------------------- ### Buffer transformation with InOutBuf Source: https://context7.com/rustcrypto/utils/llms.txt Shows how to use `inout::InOutBuf` for in-place transformations of buffer elements. Each element is processed and modified directly within the buffer. ```rust fn inout_buffer_example() { // Buffer transformation (in-place) let mut buffer = [1u8, 2, 3, 4, 5, 6, 7, 8]; let inout_buf = InOutBuf::from(&mut buffer); // Process each element for inout in inout_buf { *inout.get_out() = inout.get_in().wrapping_add(1); } assert_eq!(buffer, [2, 3, 4, 5, 6, 7, 8, 9]); } ``` -------------------------------- ### Constant-Time Comparisons with CtEq, CtGt, CtLt Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates constant-time comparison functions like `ct_eq`, `ct_gt`, and `ct_lt`. These are essential for comparing sensitive data without leaking information through timing variations. ```rust use ctutils::{Choice, CtOption, CtEq, CtSelect, CtAssign, CtGt, CtLt}; fn ct_comparison_example() { // Constant-time comparisons let a: u64 = 100; let b: u64 = 200; let eq: Choice = a.ct_eq(&b); // FALSE let gt: Choice = a.ct_gt(&b); // FALSE let lt: Choice = a.ct_lt(&b); // TRUE // Compare byte slices in constant time let slice_a = [1u8, 2, 3, 4]; let slice_b = [1u8, 2, 3, 4]; let slices_equal: Choice = slice_a.ct_eq(&slice_b); } ``` -------------------------------- ### Applying SHA-2 Style Padding with EagerBuffer Source: https://context7.com/rustcrypto/utils/llms.txt Use `len64_padding_be` on an `EagerBuffer` to apply SHA-2 style padding, which includes appending a single '1' bit, zero bits, and the message length in bits as a 64-bit big-endian integer. This is crucial for finalizing hash computations. ```rust let mut buffer = EagerBuffer::::default(); buffer.digest_blocks(b"message to hash", |_| {}); // SHA-2 style padding with 64-bit length (big-endian) let message_len_bits: u64 = 15 * 8; // 15 bytes * 8 bits buffer.len64_padding_be(message_len_bits, |block| { println!("Final padded block: {:02x?}", &block[..]); }); ``` -------------------------------- ### Constant-Time Option Handling with CtOption Source: https://context7.com/rustcrypto/utils/llms.txt Illustrates the `CtOption` type, a constant-time equivalent of `Option`. It provides methods like `map`, `is_some`, and `unwrap_or` that operate in constant time. ```rust use ctutils::{Choice, CtOption, CtEq, CtSelect, CtAssign, CtGt, CtLt}; fn ct_option_example() { // CtOption: constant-time Option equivalent let some_value: CtOption = CtOption::some(42); let none_value: CtOption = CtOption::none(0); // Eagerly-evaluated map (runs regardless of some/none) let doubled = some_value.map(|x| x * 2); // Check if value is present (returns Choice) let is_some: Choice = doubled.is_some(); // Unwrap with default (constant-time) let value = doubled.unwrap_or(0); assert_eq!(value, 84); // Chain operations let result = some_value .map(|x| x + 10) .and_then(|x| { if x > 50 { CtOption::some(x) } else { CtOption::none(0) } }); } ``` -------------------------------- ### Define and Use CPU Feature Detection Macro Source: https://github.com/rustcrypto/utils/blob/master/cpufeatures/README.md This macro defines a module for CPU feature detection, specifically for AES and SHA extensions on x86/x86_64. It initializes a Zero Sized Type (ZST) token to ensure proper initialization and allows checking feature support. The result is cached after the first call for efficiency. ```rust #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub mod x86_backend { // This macro creates `cpuid_aes_sha` module cpufeatures::new!(cpuid_aes_sha, "aes", "sha"); pub fn run() { // `token` is a Zero Sized Type (ZST) value, which guarantees // that underlying static storage got properly initialized, // which allows to omit initialization branch let token: cpuid_aes_sha::InitToken = cpuid_aes_sha::init(); if token.get() { println!("CPU supports both SHA and AES extensions"); } else { println!("SHA and AES extensions are not supported"); } // If stored value needed only once you can get stored value // omitting the token let val = cpuid_aes_sha::get(); assert_eq!(val, token.get()); // Additionally you can get both token and value let (token, val) = cpuid_aes_sha::init_get(); assert_eq!(val, token.get()); } } ``` -------------------------------- ### Constant-Time Assignment with CtAssign Source: https://context7.com/rustcrypto/utils/llms.txt Shows how to perform conditional assignments in constant time using `ct_assign`. This prevents timing differences based on whether a value is assigned or not. ```rust use ctutils::{Choice, CtOption, CtEq, CtSelect, CtAssign, CtGt, CtLt}; fn ct_assign_example() { // Constant-time conditional assignment let mut target: u64 = 0; let source: u64 = 0xDEADBEEF; // Only assign if condition is TRUE target.ct_assign(&source, Choice::TRUE); assert_eq!(target, source); // Works with slices let mut buffer = [0u8; 4]; let data = [1u8, 2, 3, 4]; buffer.ct_assign(&data, Choice::TRUE); } ``` -------------------------------- ### EagerBuffer for Block Processing with Automatic Padding Source: https://context7.com/rustcrypto/utils/llms.txt The `EagerBuffer` processes data in fixed-size blocks, automatically handling partial blocks and padding. It's suitable for algorithms like SHA-256 that require block-based processing. Use the closure to process fully formed blocks as they are generated. ```rust use block_buffer::{EagerBuffer, LazyBuffer, array::typenum::U64}; // Create a 64-byte block buffer (e.g., for SHA-256) let mut buffer = EagerBuffer::::default(); let mut processed_blocks = Vec::new(); // Process data in chunks - automatically handles partial blocks let data1 = b"Hello, "; let data2 = b"World! This is a longer message for testing."; buffer.digest_blocks(data1, |blocks| { for block in blocks { processed_blocks.push(block.clone()); } }); buffer.digest_blocks(data2, |blocks| { for block in blocks { processed_blocks.push(block.clone()); } }); // Finalize with padding let final_block = buffer.pad_with_zeros(); println!("Remaining data padded to block: {:?}", &final_block[..8]); ``` -------------------------------- ### Read Data from an Extendable-Output Reader Source: https://github.com/rustcrypto/utils/blob/master/digest-io/README.md Use IoWrapper to wrap an extendable-output reader (like Shake128) for standard io::Read operations. This allows reading a fixed-size buffer from the XOF. ```rust use digest_io::IoWrapper; use sha3::{Shake128, digest::ExtendableOutput}; use std::{fs::File, io}; fn read_array(r: &mut impl io::Read) -> io::Result<[u8; 64]> { let mut buf = [0u8; 64]; r.read_exact(&mut buf)?; Ok(buf) } fn main() -> io::Result<()> { // Create XOF reader let mut hasher = IoWrapper(Shake128::default()); let mut f = File::open("Cargo.toml")?; io::copy(&mut f, &mut hasher)?; let reader = hasher.0.finalize_xof(); // Wrap the reader and read data from it let mut reader = IoWrapper(reader); let buf = read_array(&mut reader)?; println!("{buf:?}"); Ok(()) } ``` -------------------------------- ### Update Hash Function by Writing Data Source: https://github.com/rustcrypto/utils/blob/master/digest-io/README.md Use IoWrapper to treat a hash function like an io::Write. This is useful for hashing the contents of a file directly. ```rust use digest_io::IoWrapper; use sha2::{Digest, Sha256}; use std::{fs::File, io}; fn main() -> io::Result<()> { // Wrap SHA-256 hash function let mut hasher = IoWrapper(Sha256::new()); // Write contents of the file to the wrapped hasher let mut f = File::open("Cargo.toml")?; io::copy(&mut f, &mut hasher)?; // Get the resulting hash of the file data let hash = hasher.0.finalize(); println!("{hash:?}"); Ok(()) } ``` -------------------------------- ### In-place transformation with InOut Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates using `inout::InOut` for in-place transformations of a single value. The `get_out()` method provides mutable access to the value for modification. ```rust use inout::{InOut, InOutBuf}; fn inout_single_example() { // In-place transformation let mut data = 42u64; let inout = InOut::from(&mut data); // Transform in place *inout.get_out() = inout.get_in() * 2; assert_eq!(data, 84); } ``` -------------------------------- ### Compile-time Hex to Bytes Conversion with hex! Macro Source: https://context7.com/rustcrypto/utils/llms.txt Use the `hex!` macro to convert hexadecimal string literals into byte arrays at compile time. It supports various formatting styles including spaces, colons, and multi-line inputs. This is useful for defining constants like keys or initial vectors. ```rust use hex_literal::hex; // Basic hex conversion (compile-time) const AES_KEY: [u8; 16] = hex!("000102030405060708090a0b0c0d0e0f"); const IV: [u8; 16] = hex!("00112233445566778899AABBCCDDEEFF"); ``` ```rust assert_eq!(hex!("a1 b2 c3 d4"), [0xA1, 0xB2, 0xC3, 0xD4]); ``` ```rust assert_eq!(hex!("E5 E6 90 92"), [0xE5, 0xE6, 0x90, 0x92]); ``` ```rust let mac_addr = hex!("00:1A:2B:3C:4D:5E"); assert_eq!(mac_addr, [0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E]); ``` ```rust let sha256_hash = hex!(" e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855 "); ``` ```rust let full_block = hex!( "00010203 04050607" // first half "08090a0b 0c0d0e0f" // second half ); assert_eq!(full_block.len(), 16); ``` ```rust const TEST_VECTOR: [u8; 4] = hex!("DEADBEEF"); assert_eq!(TEST_VECTOR, [0xDE, 0xAD, 0xBE, 0xEF]); ``` -------------------------------- ### Simultaneously Hash Data and Write to File Source: https://github.com/rustcrypto/utils/blob/master/digest-io/README.md Employ HashWriter to write data to a destination (like a file) while simultaneously calculating a hash of the written data. The hash can be finalized after all data has been written. ```rust use digest_io::HashWriter; use sha2::{Digest, Sha256}; use std::{ fs::File, io::{self, Write}, }; fn main() -> io::Result<()> { // Create new hashing reader let f = File::create("out.txt")?; let mut writer = HashWriter::::new(f); // Write data to the file let data = b"Hello world!"; writer.write_all(data)?; // Get the resulting hash over written data let hash = writer.finalize(); println!("{hash:?}"); assert_eq!(hash, Sha256::digest(data)); std::fs::remove_file("out.txt")?; Ok(()) } ``` -------------------------------- ### Simultaneously Read and Hash File Data Source: https://github.com/rustcrypto/utils/blob/master/digest-io/README.md Utilize HashReader to read data from a source (like a file) while simultaneously calculating its hash. The hash can be finalized after all data has been read. ```rust use digest_io::HashReader; use sha2::Sha256; use std::{ fs::File, io::{self, Read}, }; fn main() -> io::Result<()> { // Create new hashing reader let f = File::open("Cargo.toml")?; let mut reader = HashReader::::new(f); // Read all data from the file let mut buf = Vec::new(); reader.read_to_end(&mut buf)?; // Get the resulting hash over read data let hash = reader.finalize(); println!("Data: {buf:?}"); println!("Hash: {hash:?}"); Ok(()) } ``` -------------------------------- ### Constant-time conditional move with cmov Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates using `cmov` for constant-time conditional moves on primitive types and arrays. Ensures security against timing attacks. ```rust use cmov::{Cmov, CmovEq}; fn cmov_example() { // Low-level conditional move (used by ctutils internally) let mut value: u64 = 100; let new_value: u64 = 200; let condition: bool = true; // Conditionally move new_value into value // Uses CMOV instruction on x86 - guaranteed constant-time value.cmov(condition, &new_value); assert_eq!(value, 200); // Conditional equality check and move let mut a: u32 = 5; let b: u32 = 5; let replacement: u32 = 10; // If a == b, replace a with replacement a.cmoveq(&b, &replacement); assert_eq!(a, 10); } ``` ```rust fn cmov_array_example() { // Works with arrays let mut arr = [1u8, 2, 3, 4]; let new_arr = [5u8, 6, 7, 8]; arr.cmov(true, &new_arr); assert_eq!(arr, [5, 6, 7, 8]); } ``` -------------------------------- ### Parse blobby data into structured test vectors Source: https://context7.com/rustcrypto/utils/llms.txt Uses the `blobby::parse_into_structs!` macro to parse binary data into a static array of structs at compile time. Defines a struct with named fields for test vectors. ```rust // Parse into structured test vectors blobby::parse_into_structs!( BLOBBY_DATA; #[define_struct] static TEST_VECTORS: &[TestVector { input, separator, empty, output }]; ); fn blobby_struct_example() { assert_eq!(TEST_VECTORS[0].input, b"hello"); assert_eq!(TEST_VECTORS[0].output, b"world!"); assert_eq!(TEST_VECTORS.len(), 2); } ``` -------------------------------- ### Compile-time Hex to Byte Array Conversion Source: https://github.com/rustcrypto/utils/blob/master/hex-literal/README.md Use the `hex!` macro in const contexts to convert hex string literals to byte arrays. It supports uppercase, lowercase, spaces, and colons as delimiters. ```rust use hex_literal::hex; // The macro can be used in const contexts const DATA: [u8; 4] = hex!("01020304"); assert_eq!(DATA, [1, 2, 3, 4]); ``` ```rust assert_eq!(hex!("a1 b2 c3 d4"), [0xA1, 0xB2, 0xC3, 0xD4]); ``` ```rust assert_eq!(hex!("E5 E6 90 92"), [0xE5, 0xE6, 0x90, 0x92]); ``` ```rust assert_eq!(hex!("0a0B 0C0d"), [10, 11, 12, 13]); ``` ```rust assert_eq!(hex!("0A:0B:0C:0D"), [10, 11, 12, 13]); ``` ```rust let bytes1 = hex!( 00010203 04050607 08090a0b 0c0d0e0f ); assert_eq!( bytes1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], ); ``` ```rust let bytes2 = hex!( "00010203 04050607" "08090a0b 0c0d0e0f" ); assert_eq!(bytes1, bytes2); ``` -------------------------------- ### Constant-Time Selection with CtSelect Source: https://context7.com/rustcrypto/utils/llms.txt Shows how to use `ct_select` for constant-time conditional selection between two values. This is crucial for avoiding data leakage when choosing between secret values. ```rust use ctutils::{Choice, CtOption, CtEq, CtSelect, CtAssign, CtGt, CtLt}; fn ct_select_example() { // Constant-time selection between two values let secret_a: u64 = 0xDEADBEEF; let secret_b: u64 = 0xCAFEBABE; let condition = Choice::TRUE; // Select secret_a if TRUE, secret_b if FALSE let result = secret_a.ct_select(&secret_b, condition); assert_eq!(result, secret_a); // Works with arrays too let key_a = [1u8, 2, 3, 4]; let key_b = [5u8, 6, 7, 8]; let selected = key_a.ct_select(&key_b, Choice::FALSE); assert_eq!(selected, key_b); } ``` -------------------------------- ### Encode Text File to Blobby Format Source: https://github.com/rustcrypto/utils/blob/master/blobby/README.md Use the `encode` binary with Cargo to convert a text file containing hex-encoded data into the Blobby format. The input file should have alternating hash inputs and outputs, with a trailing empty line. ```sh cargo run --release --features alloc --bin encode -- /path/to/input.txt /path/to/output.blb ``` -------------------------------- ### Constant-Time Boolean Choice Operations Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates the `Choice` type for constant-time boolean operations. Use `Choice::TRUE` or `Choice::FALSE` for cryptographic comparisons to prevent timing leaks. ```rust use ctutils::{Choice, CtOption, CtEq, CtSelect, CtAssign, CtGt, CtLt}; fn choice_examples() { // Choice is a constant-time boolean let condition = Choice::TRUE; let other = Choice::FALSE; // Logical operations let and_result = condition & other; // FALSE let or_result = condition | other; // TRUE let not_result = !condition; // FALSE // Convert from comparison (constant-time) let a: u32 = 42; let b: u32 = 42; let are_equal: Choice = a.ct_eq(&b); // Convert to bool only when timing doesn't matter if bool::from(are_equal) { println!("Values are equal"); } } ``` -------------------------------- ### Decode Blobby File to Text Source: https://github.com/rustcrypto/utils/blob/master/blobby/README.md Use the `decode` binary with Cargo to inspect the contents of a Blobby file. The output will be a sequence of hex-encoded byte strings. ```sh cargo run --release --features alloc --bin decode -- /path/to/input.blb /path/to/output.txt ``` -------------------------------- ### Parse blobby data into a slice at compile time Source: https://context7.com/rustcrypto/utils/llms.txt Uses the `blobby::parse_into_slice!` macro to parse binary data into a static slice of byte slices at compile time. Useful for embedding test vectors. ```rust // Parse blobby data at compile time into a slice static BLOBBY_DATA: &[u8] = b"\x08\x02\x05hello\x06world!\x01\x02 \x00\x03\x06:::\x03\x01\x00"; static ITEMS: &[&[u8]] = blobby::parse_into_slice!(BLOBBY_DATA); fn blobby_slice_example() { assert_eq!(ITEMS[0], b"hello"); assert_eq!(ITEMS[1], b" "); assert_eq!(ITEMS[2], b""); assert_eq!(ITEMS[3], b"world!"); assert_eq!(ITEMS.len(), 8); } ``` -------------------------------- ### Parse Blobby Data into Structs Source: https://github.com/rustcrypto/utils/blob/master/blobby/README.md Use `parse_into_structs!` macro to parse blobby data into a slice of structs. Define the struct with fields corresponding to the blobby data structure. ```rust blobby::parse_into_structs!( BLOBBY_DATA; #[define_struct] static ITEMS: &[Item { a, b, c, d }]; ); assert_eq!( ITEMS[0], Item { a: b"hello", b: b" ", c: b"", d: b"world!", }, ); assert_eq!( ITEMS[1], Item { a: b":::", b: b"world!", c: b"hello", d: b"", }, ); assert_eq!(ITEMS.len(), 2); ``` -------------------------------- ### Parse Blobby Data into Slice Source: https://github.com/rustcrypto/utils/blob/master/blobby/README.md Use `parse_into_slice!` macro to parse blobby data into a slice of byte slices. Ensure the data is defined as a static byte array. ```rust static BLOBBY_DATA: &[u8; 27] = b"\x08\x02\x05hello\x06world!\x01\x02 \x00\x03\x06:::\x03\x01\x00"; static SLICE: &[&[u8]] = blobby::parse_into_slice!(BLOBBY_DATA); assert_eq!(SLICE[0], b"hello".as_slice()); assert_eq!(SLICE[1], b" ".as_slice()); assert_eq!(SLICE[2], b"".as_slice()); assert_eq!(SLICE[3], b"world!".as_slice()); assert_eq!(SLICE[4], b":::".as_slice()); assert_eq!(SLICE[5], b"world!".as_slice()); assert_eq!(SLICE[6], b"hello".as_slice()); assert_eq!(SLICE[7], b"".as_slice()); assert_eq!(SLICE.len(), 8); ``` -------------------------------- ### Checking and Resetting EagerBuffer State Source: https://context7.com/rustcrypto/utils/llms.txt Inspect the current state of an `EagerBuffer`, including its total size, current data position, and remaining capacity. The buffer can be reset to its initial empty state using the `reset()` method. ```rust let mut buffer = EagerBuffer::::default(); // Check buffer state println!("Buffer size: {}", buffer.size()); // 64 println!("Current position: {}", buffer.get_pos()); // 0 println!("Remaining space: {}", buffer.remaining()); // 64 // Add some data buffer.digest_blocks(b"test data", |_| {}); // Get current buffered data let data = buffer.get_data(); println!("Buffered {} bytes", data.len()); // Reset buffer buffer.reset(); ``` -------------------------------- ### Compile-time Error: Odd Number of Hex Characters Source: https://github.com/rustcrypto/utils/blob/master/hex-literal/README.md Each hex literal provided to the `hex!` macro must contain an even number of hexadecimal characters. An odd number will cause a compilation error. ```rust hex_literal::hex!( "01234" "567" ); ``` -------------------------------- ### Compile-time Error: Unsupported Characters Source: https://github.com/rustcrypto/utils/blob/master/hex-literal/README.md The `hex!` macro will produce a compile-time error if unsupported characters, such as Cyrillic or Japanese spaces, are used within the hex literal. ```rust hex_literal::hex!("АА"); // Cyrillic "А" ``` ```rust hex_literal::hex!("11 22"); // Japanese space ``` -------------------------------- ### Compile-time Error: Comments in Literals Source: https://github.com/rustcrypto/utils/blob/master/hex-literal/README.md Comments are not permitted within the hex string literals passed to the `hex!` macro, and will result in a compilation error. ```rust hex_literal::hex!("0123 // foo"); ``` -------------------------------- ### Galois Field double operation with dbl Source: https://context7.com/rustcrypto/utils/llms.txt Demonstrates the `dbl::Dbl` trait for performing the double operation (multiply-by-x) in Galois Field GF(2^n). Used in AES-GCM and CMAC. ```rust use dbl::Dbl; fn dbl_example() { // Double operation in GF(2^128) for AES-GCM let mut block = [0u8; 16]; block[0] = 0x80; // Example input // Perform doubling (multiply by x in GF(2^128)) block.dbl(); // Used in CMAC subkey derivation let mut k1 = [0u8; 16]; // K1 = AES(K, 0) doubled in GF(2^128) k1.dbl(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.