ProofAuditor

Struct ProofAuditor 

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

Proof verification engine with pluggable backends

The auditor performs cryptographic verification of IntegrityProof objects with multi-layer security:

  1. Signature Verification: Ed25519 cryptographic signatures (KeyStore)
  2. TTL Enforcement: Time-based proof expiry
  3. Replay Attack Prevention: Persistent nonce tracking (NonceStore)

§Architecture (v1.4.0)

┌─────────────────┐
│  ProofAuditor   │
└────────┬────────┘
         │
         ├─── KeyStore ───────> SoftwareKeyStore (Ed25519)
         │                      HsmKeyStore (PKCS#11)
         │
         └─── NonceStore ─────> MemoryNonceStore (testing)
                                RocksDbNonceStore (production)
                                RedisNonceStore (distributed)

§Example (Production Setup)

use _hope_core::auditor::ProofAuditor;
use _hope_core::crypto::SoftwareKeyStore;
use _hope_core::nonce_store::RocksDbNonceStore;

// Production setup: persistent nonce store
let key_store = SoftwareKeyStore::generate()?;
let nonce_store = RocksDbNonceStore::new("./hope_nonces.db")?;

let mut auditor = ProofAuditor::new(
    Box::new(key_store),
    Box::new(nonce_store),
);

// Verify proofs - nonces persist across restarts!
// auditor.verify_proof(&proof)?;

Implementations§

Source§

impl ProofAuditor

Source

pub fn new( key_store: Box<dyn KeyStore>, nonce_store: Box<dyn NonceStore>, ) -> Self

Create a new proof auditor with custom backends

§Arguments
  • key_store - Cryptographic key storage (SoftwareKeyStore, HsmKeyStore, etc.)
  • nonce_store - Nonce tracking storage (MemoryNonceStore, RocksDbNonceStore, etc.)
§Example
use _hope_core::auditor::ProofAuditor;
use _hope_core::crypto::SoftwareKeyStore;
use _hope_core::nonce_store::MemoryNonceStore;

let key_store = SoftwareKeyStore::generate().unwrap();
let nonce_store = MemoryNonceStore::new();

let auditor = ProofAuditor::new(
    Box::new(key_store),
    Box::new(nonce_store),
);
Source

pub fn verify_proof(&mut self, proof: &IntegrityProof) -> Result<()>

Verify a cryptographic proof

This performs comprehensive multi-layer verification:

  1. Signature Verification: Validates Ed25519 signature
  2. TTL Check: Ensures proof hasn’t expired
  3. Nonce Check: Prevents replay attacks (atomic check-and-insert)
§Arguments
  • proof - The IntegrityProof to verify
§Returns
  • Ok(()) if proof is valid and not replayed
  • Err(InvalidSignature) if signature verification fails
  • Err(ProofExpired) if proof TTL has expired
  • Err(NonceReused) if nonce was already used (replay attack)
§Security Guarantees
  • Constant-time: Ed25519 verification prevents timing attacks
  • Atomic nonce check: Race-condition free (even in distributed setup)
  • Persistent protection: With RocksDB/Redis, survives restarts
§Example
use _hope_core::auditor::ProofAuditor;
use _hope_core::crypto::{KeyStore, SoftwareKeyStore}; // KeyStore trait needed for .sign()
use _hope_core::nonce_store::MemoryNonceStore;
use _hope_core::proof::{Action, IntegrityProof};

let key_store = SoftwareKeyStore::generate().unwrap();
let nonce_store = MemoryNonceStore::new();
let mut auditor = ProofAuditor::new(
    Box::new(key_store.clone()),
    Box::new(nonce_store),
);

// Create and sign a proof
let action = Action::delete("test.txt");
let mut proof = IntegrityProof::new(&action, "capsule123".into(), 3600);
proof.signature = key_store.sign(&proof.signing_data()).unwrap();

// Verify proof
assert!(auditor.verify_proof(&proof).is_ok());

// Replay attack: blocked!
assert!(auditor.verify_proof(&proof).is_err());
Source

pub fn verify_signature(&self, proof: &IntegrityProof) -> Result<()>

Verify signature only (without nonce/TTL checks)

Use this for read-only verification without state changes. Does NOT mark nonce as used.

§Example
use _hope_core::auditor::ProofAuditor;
use _hope_core::crypto::{KeyStore, SoftwareKeyStore}; // KeyStore trait needed for .sign()
use _hope_core::nonce_store::MemoryNonceStore;
use _hope_core::proof::{Action, IntegrityProof};

let key_store = SoftwareKeyStore::generate().unwrap();
let nonce_store = MemoryNonceStore::new();
let auditor = ProofAuditor::new(
    Box::new(key_store.clone()),
    Box::new(nonce_store),
);

let action = Action::delete("test.txt");
let mut proof = IntegrityProof::new(&action, "capsule123".into(), 3600);
proof.signature = key_store.sign(&proof.signing_data()).unwrap();

// Verify signature multiple times (no nonce consumption)
assert!(auditor.verify_signature(&proof).is_ok());
assert!(auditor.verify_signature(&proof).is_ok());
Source

pub fn is_nonce_used(&self, nonce: &[u8; 32]) -> bool

Check if a nonce has been used

Read-only operation - does not modify state.

Source

pub fn used_nonce_count(&self) -> usize

Get count of used nonces

Useful for monitoring and debugging.

Source

pub fn clear_nonces(&mut self) -> Result<()>

Clear all nonces (DANGEROUS - use only for testing!)

§Security Warning

This allows replay attacks! Only use for:

  • Unit tests
  • Development reset
  • Maintenance with full system shutdown
Source

pub fn cleanup_expired_nonces(&mut self) -> Result<usize>

Cleanup expired nonces (optional maintenance)

Most backends handle this automatically (e.g., Redis TTL), but RocksDB may benefit from periodic cleanup.

§Returns

Number of nonces removed

Source

pub fn key_store_info(&self) -> String

Get key store identifier (for logging/debugging)

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> 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, 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