Skip to main content

cougr_core/zk/
components.rs

1use soroban_sdk::{contracttype, Address, BytesN, Symbol, Vec};
2
3use super::types::{Groth16Proof, Scalar};
4
5/// Stores a Poseidon hash commitment of private game state.
6///
7/// Used for fog-of-war, hidden inventories, or any state that
8/// should be verifiable without revealing the actual data.
9#[contracttype]
10#[derive(Clone, Debug)]
11pub struct HiddenState {
12    /// Poseidon hash of the private state.
13    pub commitment: BytesN<32>,
14    /// Owner of this hidden state.
15    pub owner: Address,
16}
17
18/// A pending proof submission attached to an entity.
19///
20/// The proof must be verified before the deadline. Once verified,
21/// a `VerifiedMarker` is added and this component is removed.
22#[contracttype]
23#[derive(Clone, Debug)]
24pub struct ProofSubmission {
25    /// The Groth16 proof to be verified.
26    pub proof: Groth16Proof,
27    /// Public inputs for verification.
28    pub public_inputs: Vec<Scalar>,
29    /// Ledger timestamp when the proof was submitted.
30    pub submitted_at: u64,
31    /// Deadline ledger timestamp for verification.
32    pub deadline: u64,
33    /// Whether this proof has been verified.
34    pub verified: bool,
35}
36
37/// Marker component for entities with verified proofs.
38///
39/// Added after a `ProofSubmission` passes verification.
40/// Can be cleaned up after a configurable age.
41#[contracttype]
42#[derive(Clone, Debug)]
43pub struct VerifiedMarker {
44    /// Ledger timestamp when verification occurred.
45    pub verified_at: u64,
46    /// Type/category of the proof that was verified.
47    pub proof_type: Symbol,
48}
49
50/// Commit-reveal two-phase pattern component.
51///
52/// Phase 1 (Commit): Player submits a hash of their action.
53/// Phase 2 (Reveal): Player reveals the actual action + nonce.
54/// If the reveal deadline passes without a reveal, the commitment expires.
55#[contracttype]
56#[derive(Clone, Debug)]
57pub struct CommitReveal {
58    /// Hash of the committed action (e.g., Poseidon(action || nonce)).
59    pub commitment: BytesN<32>,
60    /// Deadline for revealing the committed action.
61    pub reveal_deadline: u64,
62    /// Whether the action has been revealed.
63    pub revealed: bool,
64}
65
66/// Well-known component type symbol for `HiddenState`.
67pub const HIDDEN_STATE_TYPE: &str = "zk_hidden";
68
69/// Well-known component type symbol for `ProofSubmission`.
70pub const PROOF_SUBMISSION_TYPE: &str = "zk_proof";
71
72/// Well-known component type symbol for `VerifiedMarker`.
73pub const VERIFIED_MARKER_TYPE: &str = "zk_veri";
74
75/// Well-known component type symbol for `CommitReveal`.
76pub const COMMIT_REVEAL_TYPE: &str = "zk_cr";
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81    use soroban_sdk::{symbol_short, testutils::Address as _, vec, BytesN, Env};
82
83    #[test]
84    fn test_hidden_state_creation() {
85        let env = Env::default();
86        let state = HiddenState {
87            commitment: BytesN::from_array(&env, &[0xABu8; 32]),
88            owner: Address::generate(&env),
89        };
90        assert_eq!(state.commitment.len(), 32);
91    }
92
93    #[test]
94    fn test_proof_submission_creation() {
95        let env = Env::default();
96        let g1 = super::super::types::G1Point {
97            bytes: BytesN::from_array(&env, &[0u8; 64]),
98        };
99        let g2 = super::super::types::G2Point {
100            bytes: BytesN::from_array(&env, &[0u8; 128]),
101        };
102        let proof = Groth16Proof {
103            a: g1.clone(),
104            b: g2,
105            c: g1,
106        };
107        let submission = ProofSubmission {
108            proof,
109            public_inputs: vec![&env],
110            submitted_at: 100,
111            deadline: 200,
112            verified: false,
113        };
114        assert!(!submission.verified);
115        assert_eq!(submission.submitted_at, 100);
116    }
117
118    #[test]
119    fn test_verified_marker() {
120        let _env = Env::default();
121        let marker = VerifiedMarker {
122            verified_at: 150,
123            proof_type: symbol_short!("movement"),
124        };
125        assert_eq!(marker.verified_at, 150);
126    }
127
128    #[test]
129    fn test_commit_reveal() {
130        let env = Env::default();
131        let cr = CommitReveal {
132            commitment: BytesN::from_array(&env, &[0xCDu8; 32]),
133            reveal_deadline: 500,
134            revealed: false,
135        };
136        assert!(!cr.revealed);
137        assert_eq!(cr.reveal_deadline, 500);
138    }
139}