1use exo_core::{Did, Timestamp};
20
21#[derive(Debug, thiserror::Error)]
23pub enum IdentityError {
24 #[error("DID already registered: {0}")]
25 DuplicateDid(Did),
26
27 #[error(
28 "DID registry capacity exceeded: max_documents={max_documents}, attempted_documents={attempted_documents}"
29 )]
30 RegistryCapacityExceeded {
31 max_documents: usize,
32 attempted_documents: usize,
33 },
34
35 #[error("DID document for {did} has invalid field {field}: {reason}")]
36 InvalidDidDocumentField {
37 did: String,
38 field: String,
39 reason: String,
40 },
41
42 #[error("DID document for {did} exceeds {field} bound: max={max}, actual={actual}")]
43 DidDocumentFieldTooLarge {
44 did: String,
45 field: String,
46 max: usize,
47 actual: usize,
48 },
49
50 #[error("DID not found: {0}")]
51 DidNotFound(Did),
52
53 #[error("DID has been revoked: {0}")]
54 DidRevoked(Did),
55
56 #[error("invalid signature")]
57 InvalidSignature,
58
59 #[error("non-monotonic timestamp for DID {did}: current={current}, proposed={proposed}")]
60 NonMonotonicTimestamp {
61 did: Did,
62 current: Timestamp,
63 proposed: Timestamp,
64 },
65
66 #[error("invalid revocation proof for DID: {0}")]
67 InvalidRevocationProof(Did),
68
69 #[error("invalid registration proof for DID {did}: {reason}")]
70 InvalidRegistrationProof { did: Did, reason: String },
71
72 #[error("registration proof payload encoding failed for DID {did}: {reason}")]
73 RegistrationProofPayloadEncoding { did: Did, reason: String },
74
75 #[error("revocation proof payload encoding failed for DID {did}: {reason}")]
76 RevocationProofPayloadEncoding { did: Did, reason: String },
77
78 #[error("key rotation proof payload encoding failed for DID {did}: {reason}")]
79 KeyRotationProofPayloadEncoding { did: Did, reason: String },
80
81 #[error("public key not found on DID: {0}")]
82 KeyNotFound(Did),
83
84 #[error("key already revoked")]
85 KeyAlreadyRevoked,
86
87 #[error("key already rotated")]
88 KeyAlreadyRotated,
89
90 #[error("invalid Shamir config: threshold={threshold}, shares={shares}")]
91 InvalidShamirConfig { threshold: u8, shares: u8 },
92
93 #[error(
94 "invalid Shamir entropy: min_bytes={min_bytes}, got_bytes={got_bytes}, reason={reason}"
95 )]
96 InvalidShamirEntropy {
97 min_bytes: usize,
98 got_bytes: usize,
99 reason: String,
100 },
101
102 #[error("Shamir input {field} exceeds deterministic encoding bound: max={max}, got={got}")]
103 ShamirInputTooLarge {
104 field: &'static str,
105 max: u64,
106 got: usize,
107 },
108
109 #[error("insufficient shares: need {need}, got {got}")]
110 InsufficientShares { need: u8, got: u8 },
111
112 #[error("invalid share index: {0}")]
113 InvalidShareIndex(u8),
114
115 #[error("share index {index} exceeds configured share count {shares}")]
116 ShareIndexOutOfRange { index: u8, shares: u8 },
117
118 #[error("invalid share length for index {index}: expected {expected}, got {got}")]
119 InvalidShareLength {
120 index: u8,
121 expected: usize,
122 got: usize,
123 },
124
125 #[error("share commitment mismatch at index {index}: expected {expected:?}, got {got:?}")]
126 ShareCommitmentMismatch {
127 index: u8,
128 expected: [u8; 32],
129 got: [u8; 32],
130 },
131
132 #[error("reconstructed secret commitment mismatch: expected {expected:?}, got {got:?}")]
133 ReconstructedSecretCommitmentMismatch { expected: [u8; 32], got: [u8; 32] },
134
135 #[error(
136 "invalid share value at index {index}, byte {byte_index}: expected {expected}, got {got}"
137 )]
138 InvalidShareValue {
139 index: u8,
140 byte_index: usize,
141 expected: u8,
142 got: u8,
143 },
144
145 #[error("duplicate share indices")]
146 DuplicateShareIndices,
147
148 #[error("invalid PACE config: {0}")]
149 InvalidPaceConfig(String),
150
151 #[error("cannot escalate: already at maximum level")]
152 CannotEscalate,
153
154 #[error("cannot de-escalate: already at Normal")]
155 CannotDeescalate,
156
157 #[error("risk attestation expired")]
158 AttestationExpired,
159
160 #[error("risk attestation signing payload encoding failed: {reason}")]
161 RiskAttestationSigningPayloadEncoding { reason: String },
162
163 #[error(
164 "risk attestation expiry overflow: now_physical_ms={now_physical_ms}, validity_ms={validity_ms}"
165 )]
166 RiskAttestationExpiryOverflow {
167 now_physical_ms: u64,
168 validity_ms: u64,
169 },
170
171 #[error("duplicate DID across PACE levels: {0}")]
172 DuplicatePaceDid(Did),
173
174 #[error("vault key derivation failed: {0}")]
175 VaultKeyDerivationFailed(String),
176
177 #[error("vault encryption requires a caller-supplied nonce")]
178 VaultNonceRequired,
179
180 #[error("invalid vault nonce: {reason}")]
181 InvalidVaultNonce { reason: String },
182
183 #[error("vault encryption failed: {0}")]
184 VaultEncryptionFailed(String),
185
186 #[error("vault decryption failed: authentication or ciphertext invalid")]
187 VaultDecryptionFailed,
188
189 #[error("vault ciphertext too short")]
190 VaultCiphertextTooShort,
191}