Crate byte_array_ops

Crate byte_array_ops 

Source
Expand description

Welcome to the ByteArrayOps Library

§Introduction

This is a no_std-compatible library designed to provide an ergonomic and easy way to conduct operations on byte arrays. It is intended both for general use where data sensitivity is not important and for cryptographic use cases or other cases where privacy may be of concern.

§byte-array-ops

⚠️ Active Development Warning This library is under heavy active development. Core functionality (type conversions, bitwise operations) is stable and production-ready. Security-hardening features are planned for v0.2.0+.

§Overview

A no_std-compatible Rust library for ergonomic byte array operations with optional security hardening.

Design Philosophy:

  • Compile only what you need - Feature flags for graceful degradation. Basic conversions work without any features, bitwise operations require ops_algebra (enabled by default), and security features are opt-in.
  • Minimal dependencies - Keep compilation fast and dependency tree small for a pleasant development experience.
  • Test-driven development - No functionality is added without comprehensive test coverage. Untested or experimental features are gated behind the experimental flag (disabled by default and guarded with compile_error!).

§Features

FeaturePurposeDefaultStatusUse Cases
ops_algebraBitwise operations (XOR, AND, OR, NOT)✅ Yes✅ ImplementedCrypto implementations, data masking, general byte manipulation
sec_basic_hardeningBasic security tier (zeroize on drop)❌ No⏳ Planned (v0.2.0)Handling sensitive data like keys, passwords
sec_enhanced_hardeningEnhanced security (const-time ops + memlock)❌ No⏳ Planned (v0.2.0)Cryptographic operations, preventing timing attacks
sec_maximum_hardeningMaximum security (all features + memencrypt)❌ No⏳ Planned (v0.2.0)High-security environments, defense in depth
sec_harden_zeroizeSecure memory wiping❌ No⏳ PlannedUse tiers instead (individual feature for advanced users)
sec_harden_const_time_opsConstant-time comparisons❌ No⏳ PlannedUse tiers instead (individual feature for advanced users)
sec_harden_memlockMemory locking (prevent swap to disk)❌ No⏳ PlannedUse tiers instead (individual feature for advanced users)
sec_harden_memencryptIn-memory encryption❌ No⏳ PlannedUse tiers instead (individual feature for advanced users)
ops_simdSIMD-optimized operations❌ No⏳ Planned (v0.3.0)High-performance bulk operations
experimentalUnstable/experimental features❌ No🧪 OngoingDevelopment and testing only

Note on Feature Selection:

  • No features needed: Simple conversions (hex ↔ bytes, UTF-8 ↔ bytes) work with default-features = false
  • ops_algebra (default): Enabled by default for bitwise operations
  • Security tiers: Use when handling sensitive data (choose appropriate tier for your threat model)
  • Individual security features: For fine-grained control (advanced users only)

§Installation

[dependencies]
byte-array-ops = "0.1.0"

# Or disable default features for minimal build (conversions only)
byte-array-ops = { version = "0.1.0", default-features = false }

# For no_std environments with alloc and operations
byte-array-ops = { version = "0.1.0", default-features = false, features = ["ops_algebra"] }

§Quick Start

See the API documentation for comprehensive examples including:

  • Creating ByteArrays from hex, binary, UTF-8, and raw bytes
  • Bitwise operations (XOR, AND, OR, NOT)
  • Working with iterators
  • Using the builder pattern

§Basic Example

use byte_array_ops::ByteArray;
use byte_array_ops::errors::ByteArrayError;

fn main() -> Result<(),ByteArrayError> {

    // From hex string
    let from_hex: ByteArray = "0xdeadbeef".parse()?;
    assert_eq!(from_hex.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);

    // From UTF-8 string (no prefix)
    let from_utf8: ByteArray = "hello".parse()?;
    assert_eq!(from_utf8.as_bytes(), b"hello");

    // Bitwise operations (requires ops_algebra feature)
    let a: ByteArray = "0xff00".parse()?;
    let b: ByteArray = "0x0ff0".parse()?;
    let result = a ^ b; // XOR
    assert_eq!(result.as_bytes(), [0xf0, 0xf0]);
    
    Ok(())
}

§no_std Support

This library is no_std compatible and requires only the alloc crate. Perfect for:

  • Embedded systems with allocators (ESP32, ARM Cortex-M with heap)
  • Bootloaders and kernel development
  • WebAssembly environments
  • Any environment where std is unavailable

§Roadmap

Note on version stability: All versions post-0.2.0 are subject to change depending on whether breaking changes are necessary in previous versions. When no more breaking API changes are planned, the “Active Development Warning” banner above will be removed. This is expected to happen well before v1.0.0 as the API matures for ergonomic use.

§v0.1.0 (Old Milestone)

Core functionality with production-ready type conversions and bitwise operations:

  • ✅ Multiple input formats (hex, binary, UTF-8, raw bytes)
  • ✅ Bitwise operations (XOR, AND, OR, NOT)
  • ✅ Comprehensive iterator support
  • ✅ no_std compatibility with alloc

§v0.2.0 (Current)

API refinement and macro ergonomics:

  • Cleanup API and experiment with most efficient (and most used) APIs
  • Lay the groundwork for introducing the SecureReallocationProvider trait, which will encompass more secure implementations of vector methods that may require allocation
  • Introduce helper macros for ByteArray construction

§v0.3.0 (Planned - Possible Breaking Changes)

Security hardening for cryptographic and sensitive data use cases:

  • Secure memory wiping (zeroize on drop)
  • Memory locking (prevent swapping to disk)
  • Constant-time operations (timing attack prevention)
  • Hardened constructors and secure reallocation
  • Bugfixes and refinements

§v0.4.0 (Planned - Possible Breaking Changes)

Performance optimization for high-throughput scenarios:

  • SIMD-accelerated bitwise operations
  • Benchmark suite and regression testing
  • Performance tuning for large arrays

§v1.0.0 (Future)

Stable API with long-term compatibility guarantees:

  • API freeze after real-world usage validation
  • Security audit (if feasible - even major libraries like RustCrypto often lack formal audits)
  • Comprehensive test coverage and fuzzing
  • Multi-platform testing and verification

§License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

§Quick Start Examples

§Creating ByteArrays - Multiple Ways

use byte_array_ops::ByteArray;
use byte_array_ops::errors::ByteArrayError;

fn main() -> Result<(), ByteArrayError> {
    // From hex string (with 0x prefix)
    let from_hex: ByteArray = "0xdeadbeef".parse()?;
    assert_eq!(from_hex.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);

    // From binary string (with 0b prefix)
    let from_bin: ByteArray = "0b11110000".parse()?;
    assert_eq!(from_bin.as_bytes(), [0xf0]);

    // From UTF-8 string (no prefix)
    let from_utf8: ByteArray = "hello".parse()?;
    assert_eq!(from_utf8.as_bytes(), b"hello");

    // From byte slice using From trait
    let from_slice: ByteArray = [0x01, 0x02, 0x03].as_slice().into();
    assert_eq!(from_slice.len(), 3);

    // From Vec<u8> using From trait
    let from_vec: ByteArray = vec![0xaa, 0xbb, 0xcc].into();
    assert_eq!(from_vec.as_bytes(), [0xaa, 0xbb, 0xcc]);

    // From array literal using From trait
    let from_array: ByteArray = [0xff; 4].into();
    assert_eq!(from_array.as_bytes(), [0xff, 0xff, 0xff, 0xff]);

    // Using static constructor with hex
    let with_hex = ByteArray::from_hex("cafe")?;
    assert_eq!(with_hex.as_bytes(), [0xca, 0xfe]);

    // Using static constructor with binary
    let with_bin = ByteArray::from_bin("1010_0101")?;
    assert_eq!(with_bin.as_bytes(), [0xa5]);

    Ok(())
}

§Macro Examples

use byte_array_ops::{try_bytes, try_hex, try_bin};
use byte_array_ops::errors::ByteArrayError;

fn main() -> Result<(), ByteArrayError> {
    // try_bytes! - Parse with format detection (0x/0b prefix or UTF-8)
    let from_hex = try_bytes!("0xdeadbeef")?;
    assert_eq!(from_hex.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);

    let from_bin = try_bytes!("0b11110000")?;
    assert_eq!(from_bin.as_bytes(), [0xf0]);

    let from_utf8 = try_bytes!("hello")?;
    assert_eq!(from_utf8.as_bytes(), b"hello");

    // try_hex! - Parse as hex without prefix
    let hex_only = try_hex!("cafe")?;
    assert_eq!(hex_only.as_bytes(), [0xca, 0xfe]);

    // try_bin! - Parse as binary without prefix
    let bin_only = try_bin!("11110000")?;
    assert_eq!(bin_only.as_bytes(), [0xf0]);

    Ok(())
}

§XOR Encryption Example

use byte_array_ops::ByteArray;
use byte_array_ops::errors::ByteArrayError;

fn main() -> Result<(), ByteArrayError> {
    // Encrypt plaintext with a key using XOR
    let plaintext: ByteArray = "secret message".parse()?;
    let key: ByteArray = "0x_de_ad_be_ef_ca_fe_ba_be_01_02_03_04_05_06".parse()?;

    let mut cipher_out = vec![0u8; plaintext.len()];
    let encrypted_len = encrypt(plaintext.as_bytes(), key.as_bytes(), &mut cipher_out);

    assert_eq!(encrypted_len, plaintext.len());

    // Decrypt the ciphertext (XOR is symmetric)
    let mut decrypted_out = vec![0u8; encrypted_len];
    let decrypted_len = decrypt(&cipher_out[..encrypted_len], key.as_bytes(), &mut decrypted_out);

    assert_eq!(&decrypted_out[..decrypted_len], plaintext.as_bytes());
    Ok(())
}

fn encrypt(input: &[u8], key: &[u8], output: &mut [u8]) -> usize {
    // Simple XOR encryption (NOT secure, for demonstration only!)
    let input_ba: ByteArray = input.into();
    let key_ba: ByteArray = key.into();
    let result = input_ba ^ key_ba;

    let bytes_written = result.len().min(output.len());
    output[..bytes_written].copy_from_slice(&result.as_bytes()[..bytes_written]);
    bytes_written
}

fn decrypt(input: &[u8], key: &[u8], output: &mut [u8]) -> usize {
    // XOR is symmetric, so decrypt is the same as encrypt
    encrypt(input, key, output)
}

§Bitwise Operations

use byte_array_ops::ByteArray;

fn main() {
    let a: ByteArray = "0xff00".parse().unwrap();
    let b: ByteArray = "0x0ff0".parse().unwrap();

    // XOR operation
    let xor_result = a.clone() ^ b.clone();
    assert_eq!(xor_result.as_bytes(), [0xf0, 0xf0]);

    // AND operation
    let and_result = a.clone() & b.clone();
    assert_eq!(and_result.as_bytes(), [0x0f, 0x00]);

    // OR operation
    let or_result = a.clone() | b.clone();
    assert_eq!(or_result.as_bytes(), [0xff, 0xf0]);

    // NOT operation
    let not_result = !a;
    assert_eq!(not_result.as_bytes(), [0x00, 0xff]);
}

§Module Overview

This library is organized into the following modules:

§Key Types

§Core Types

  • ByteArray - Main byte array type with automatic capacity management
  • UninitByteArray - Builder for configuring ByteArray construction (odd-word padding)
  • ByteArrayOddWordPad - Padding direction for odd-length hex/binary inputs

§Iterators

§Error Types

§Trait Implementations

ByteArray implements many standard Rust traits for ergonomic usage:

Conversions:

  • From<&[u8]>, From<Vec<u8>>, From<&Vec<u8>>, From<[u8; N]> - Create from bytes
  • FromStr - Parse from strings (hex with 0x, binary with 0b, UTF-8 fallback)
  • Into<Vec<u8>> - Extract underlying bytes (zero-cost move)
  • AsRef<[u8]> - Borrow as byte slice

Operations (requires ops_algebra feature):

  • BitXor, BitXorAssign - XOR operations (^, ^=)
  • BitAnd, BitAndAssign - AND operations (&, &=)
  • BitOr, BitOrAssign - OR operations (|, |=)
  • Not - NOT operation (!)

Iteration:

  • IntoIterator - Iterate by reference (&ByteArray, &mut ByteArray)
  • ExactSizeIterator - Iterators with known length

Comparison:

  • PartialEq, Eq - Equality comparisons
  • Clone - Cloning support
  • Default - Default constructor (empty array)

Indexing:

  • Index<usize>, IndexMut<usize> - Array-style indexing (arr[0], arr[1] = 0xff)

§Implementation Notes

Feature Flags: Check Cargo.toml for hardening tiers. When implementing features, use individual feature flags (sec_harden_zeroize, sec_harden_const_time_ops, etc.) in #[cfg] attributes. Tiers (sec_basic_hardening, sec_enhanced_hardening, sec_maximum_hardening) are convenience bundles for users to activate multiple features at once.

Re-exports§

pub use byte_array::errors;
pub use byte_array::model::ByteArray;

Modules§

byte_array

Macros§

count_args
try_bin
try_bytes
try_hex