Skip to main content

moloch_core/
lib.rs

1//! Moloch Core - Fundamental types for the Moloch audit chain.
2//!
3//! This crate provides the core data structures and cryptographic primitives
4//! used throughout the Moloch system:
5//!
6//! - [`crypto`] - Hashing (BLAKE3) and signatures (Ed25519)
7//! - [`event`] - Audit events (the atomic unit of the chain)
8//! - [`block`] - Blocks that batch events together
9//! - [`proof`] - Merkle proofs for inclusion verification
10//!
11//! # Example
12//!
13//! ```rust
14//! use moloch_core::{
15//!     crypto::SecretKey,
16//!     event::{ActorId, ActorKind, AuditEvent, EventType, ResourceId, ResourceKind},
17//!     block::BlockBuilder,
18//! };
19//!
20//! // Generate a key for signing
21//! let key = SecretKey::generate();
22//!
23//! // Create an audit event
24//! let actor = ActorId::new(key.public_key(), ActorKind::User);
25//! let resource = ResourceId::new(ResourceKind::Repository, "myrepo");
26//!
27//! let event = AuditEvent::builder()
28//!     .now()
29//!     .event_type(EventType::Push { force: false, commits: 1 })
30//!     .actor(actor)
31//!     .resource(resource)
32//!     .sign(&key)
33//!     .unwrap();
34//!
35//! // Create a block containing the event
36//! let sealer = moloch_core::block::SealerId::new(key.public_key());
37//! let block = BlockBuilder::new(sealer)
38//!     .events(vec![event])
39//!     .seal(&key);
40//!
41//! assert!(block.validate(None).is_ok());
42//! ```
43
44pub mod agent;
45pub mod aligned;
46pub mod arena;
47pub mod block;
48pub mod crypto;
49pub mod error;
50pub mod event;
51pub mod merkle;
52pub mod proof;
53pub mod rkyv_types;
54
55#[cfg(test)]
56mod proptest;
57
58// Re-exports for convenience
59pub use aligned::{AlignedHash, AlignedHashArray, CacheLinePadded, CACHE_LINE_SIZE};
60pub use arena::{BatchArena, CanonicalBytesArena, DEFAULT_ARENA_CAPACITY};
61pub use block::{
62    compute_events_root, compute_events_root_parallel, Block, BlockBuilder, BlockHash, BlockHeader,
63    SealerId,
64};
65pub use crypto::{
66    batch_verify, batch_verify_with_fallback, hash, hash_pair, BatchVerifyResult, Hash, PublicKey,
67    SecretKey, Sig,
68};
69pub use error::{Error, Result};
70pub use event::{
71    ActorId, ActorKind, AuditEvent, EventId, EventType, Outcome, ResourceId, ResourceKind,
72};
73pub use merkle::{compute_proof, compute_root_optimized, compute_roots_batch, verify_proof};
74pub use proof::{
75    BlockInclusionProof, ConsistencyProof, InclusionProof, MmrProof, Position, ProofNode,
76};
77
78// Agent accountability types
79pub use agent::{
80    ActionModifications, ActionOutcome, AgentAttestation, AgentAttestationBuilder, Alternative,
81    ApprovalContext, ApprovalDecision, ApprovalPolicy, ApprovalRequest, ApprovalRequestId,
82    ApprovalResponse, ApprovalStatus, AttestationError, AttestationRegistry, Attestor,
83    CancellationActor, Capability, CapabilityBuilder, CapabilityCheck, CapabilityConstraints,
84    CapabilityId, CapabilityKind, CapabilitySet, CapabilitySetId, CausalContext,
85    CausalContextBuilder, Confidence, CoordinatedAction, CoordinatedActionBuilder,
86    CoordinatedActionSpec, CoordinationEvent, CoordinationId, CoordinationMetrics,
87    CoordinationProtocol, CoordinationResult, CoordinationStatus, CoordinationType, Cost,
88    CrossSessionReference, DayOfWeek, Decision, DenialReason, DisputeStatus, DurationMs,
89    EmergencyAction, EmergencyEvent, EmergencyEventBuilder, EmergencyPriority, EmergencyResolution,
90    EmergencyTrigger, EscalationPolicy, Evidence, Factor, FailureHandling, Goal, GoalSource,
91    IdempotencyKey, IdempotencyRecord, ImpactAssessment, OutcomeAttestation,
92    OutcomeAttestationBuilder, OutcomeDispute, Participant, ParticipantRole, PostMortem,
93    PrincipalId, PrincipalKind, Priority, ProposedAction, ProposedActionBuilder, RateLimit,
94    ReasoningStep, ReasoningTrace, ReasoningTraceBuilder, RequiredCapability, Resolution,
95    ResourceScope, Responsibility, RuntimeAttestation, Session, SessionBuilder, SessionEndReason,
96    SessionId, SessionSummary, Severity, StepAction, SuspensionScope, Task, TaskDependency, TaskId,
97    TeeQuote, TeeType, TimeOfDay, TimeWindow, ToolAttestation, TraceId,
98};
99
100/// Batch-verify the signatures of multiple events.
101///
102/// This is 3-8x faster than calling `event.validate()` on each event individually.
103///
104/// # Example
105/// ```ignore
106/// let events: Vec<AuditEvent> = ...;
107/// batch_verify_events(&events)?;
108/// ```
109pub fn batch_verify_events(events: &[AuditEvent]) -> Result<()> {
110    if events.is_empty() {
111        return Ok(());
112    }
113
114    // Pre-compute canonical bytes (this is the expensive part)
115    let canonical: Vec<Vec<u8>> = events.iter().map(|e| e.canonical_bytes()).collect();
116
117    // Build verification tuples
118    let items: Vec<(&PublicKey, &[u8], &Sig)> = events
119        .iter()
120        .zip(canonical.iter())
121        .map(|(e, bytes)| (e.attester(), bytes.as_slice(), e.signature()))
122        .collect();
123
124    batch_verify(&items)
125}
126
127/// Batch-verify event signatures with parallel canonical bytes computation.
128///
129/// Uses Rayon to parallelize the canonical bytes serialization across cores,
130/// then uses batch verification for signatures. This is optimal for large batches.
131///
132/// # Performance
133/// - 100 events: ~1.5x faster than batch_verify_events
134/// - 1000 events: ~2-3x faster than batch_verify_events
135/// - Scales with available CPU cores
136pub fn batch_verify_events_parallel(events: &[AuditEvent]) -> Result<()> {
137    use rayon::prelude::*;
138
139    if events.is_empty() {
140        return Ok(());
141    }
142
143    // Parallel canonical bytes computation - this is the CPU-intensive part
144    let canonical: Vec<Vec<u8>> = events.par_iter().map(|e| e.canonical_bytes()).collect();
145
146    // Build verification tuples (fast, no parallelization needed)
147    let items: Vec<(&PublicKey, &[u8], &Sig)> = events
148        .iter()
149        .zip(canonical.iter())
150        .map(|(e, bytes)| (e.attester(), bytes.as_slice(), e.signature()))
151        .collect();
152
153    batch_verify(&items)
154}