SoftwareKeyStore

Struct SoftwareKeyStore 

Source
pub struct SoftwareKeyStore { /* private fields */ }
Expand description

Software-based Ed25519 key storage (v1.4.2 - Red Team Hardened)

Keys are stored in process memory. Suitable for:

  • Development and testing
  • Low-security environments
  • Embedded systems without HSM

WARNING: Keys are lost on process termination. For persistence, use from_seed() with securely stored seed bytes.

CRITICAL SECURITY WARNING (v1.4.2): Private keys remain in memory until process termination. Use HSM (Hardware Security Module) for production deployments requiring memory safety guarantees.

§Security Properties (v1.4.2 Enhancements)

  • Algorithm: Ed25519 (Curve25519 + SHA-512)
  • Key Size: 32 bytes (private), 32 bytes (public)
  • Signature Size: 64 bytes
  • Constant-time: Yes (immune to timing attacks)
  • P0 Protection: PublicKey-SecretKey validation before signing (constant-time)
  • P2 Protection: Verify-after-sign fault detection
  • P3 Protection: Secure diagnostic logging (sanitized)
  • Memory Safety: Private key zeroed on drop (best-effort)

§Example

use _hope_core::crypto::{SoftwareKeyStore, KeyStore};

// Generate new keypair
let store = SoftwareKeyStore::generate().unwrap();

// Sign and verify (with automatic security checks)
let data = b"AI action data";
let sig = store.sign(data).unwrap();
assert!(store.verify(data, &sig).is_ok());

Implementations§

Source§

impl SoftwareKeyStore

Source

pub fn generate() -> Result<Self>

Generate a new random Ed25519 keypair (v1.4.1 - Hardened)

Uses OS-provided cryptographically secure random number generator. Automatically enables Fort Knox diagnostic mode for production safety.

Source

pub fn from_seed(seed: [u8; 32]) -> Result<Self>

Load keypair from 32-byte seed (v1.4.1 - Hardened)

Use case: Deterministic key generation or key persistence.

§Security Warning

The seed MUST be:

  • Generated from a CSPRNG (cryptographically secure RNG)
  • Stored securely (encrypted at rest, never logged)
  • Never transmitted over untrusted channels
§Example
use _hope_core::crypto::SoftwareKeyStore;

let seed = [42u8; 32]; // In production, use secure random seed!
let store = SoftwareKeyStore::from_seed(seed).unwrap();
Source

pub fn public_key_bytes_array(&self) -> [u8; 32]

Export the 32-byte Ed25519 public key

Source

pub fn private_key_bytes(&self) -> [u8; 32]

Export the 32-byte Ed25519 private key seed

§Security Warning

NEVER expose this in production! Use only for:

  • Secure key backup
  • Migration to HSM
  • Encrypted storage
Source

pub fn enable_diagnostic_mode(&mut self)

Enable Fort Knox diagnostic mode (v1.4.1 - P3)

When enabled, cryptographic operations log detailed traces for security incident post-mortem analysis.

Source

pub fn disable_diagnostic_mode(&mut self)

Disable diagnostic mode (use with caution)

Trait Implementations§

Source§

impl Clone for SoftwareKeyStore

Source§

fn clone(&self) -> SoftwareKeyStore

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Drop for SoftwareKeyStore

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl KeyStore for SoftwareKeyStore

Source§

fn sign(&self, data: &[u8]) -> Result<Vec<u8>>

Sign data with Ed25519 (v1.4.2 - Triple Protection + Constant-Time)

Security layers:

  1. P0: PublicKey-SecretKey validation (constant-time, prevents key leakage)
  2. Signature generation using ed25519-compact with random noise
  3. P2: Verify-after-sign check (detects fault attacks, sanitized logging)
§v1.4.2 Note: Non-Deterministic Signatures (P3.4)

This implementation uses random noise during signature generation, making signatures non-deterministic:

  • Same data + same key = DIFFERENT signatures each time
  • Security benefit: Prevents certain side-channel and fault attacks
  • Audit impact: Nonce-based replay protection handles this correctly
  • All signatures remain valid and verifiable

For deterministic signatures, use sign(data, None) in ed25519-compact, but this reduces security against advanced attacks.

Source§

fn verify(&self, data: &[u8], signature: &[u8]) -> Result<()>

Verify signature with the public key Read more
Source§

fn public_key_bytes(&self) -> Vec<u8>

Get the public key bytes (for export, verification by others) Read more
Source§

fn identifier(&self) -> String

Get a human-readable identifier for this key store Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V