rezabarkhordary commited on
Commit
5573334
·
verified ·
1 Parent(s): 7119b66

Create sovereign_crypto_seal.py

Browse files
Files changed (1) hide show
  1. sovereign_crypto_seal.py +323 -0
sovereign_crypto_seal.py ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # sovereign_crypto_seal.py
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import hmac
7
+ import json
8
+ import os
9
+ import secrets
10
+ import time
11
+ from dataclasses import dataclass, asdict
12
+ from typing import Any, Dict, Optional
13
+
14
+
15
+ DEFAULT_SECRET_ENV = "SOVEREIGN_SEAL_SECRET"
16
+ DEFAULT_ALGO = "sha256"
17
+ DEFAULT_SCHEME = "hmac-sha256-v1"
18
+
19
+
20
+ def _utc_ts() -> str:
21
+ return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
22
+
23
+
24
+ def _canonical_json(obj: Any) -> str:
25
+ return json.dumps(
26
+ obj,
27
+ ensure_ascii=False,
28
+ sort_keys=True,
29
+ separators=(",", ":"),
30
+ default=str,
31
+ )
32
+
33
+
34
+ def _sha256_hex(data: str) -> str:
35
+ return hashlib.sha256(data.encode("utf-8")).hexdigest()
36
+
37
+
38
+ def _resolve_secret(explicit_secret: Optional[str] = None) -> str:
39
+ if explicit_secret:
40
+ return explicit_secret
41
+
42
+ env_secret = os.getenv(DEFAULT_SECRET_ENV, "").strip()
43
+ if env_secret:
44
+ return env_secret
45
+
46
+ # deterministic fallback would be dangerous; use generated process-local secret
47
+ # so the system remains functional in dev/test, but caller should set env in prod
48
+ return "dev-only-" + secrets.token_hex(32)
49
+
50
+
51
+ @dataclass
52
+ class SovereignSeal:
53
+ scheme: str
54
+ algorithm: str
55
+ created_at: str
56
+ object_type: str
57
+ object_digest: str
58
+ object_size: int
59
+ signer_hint: str
60
+ seal_digest: str
61
+ metadata: Dict[str, Any]
62
+
63
+ def as_dict(self) -> Dict[str, Any]:
64
+ return asdict(self)
65
+
66
+
67
+ class SovereignCryptoSeal:
68
+ """
69
+ Lightweight cryptographic sealing utility for Sovereign artifacts.
70
+
71
+ Capabilities:
72
+ - canonical digest of arbitrary JSON-serializable objects
73
+ - HMAC-based sealing
74
+ - verification of digest + seal
75
+ - manifest generation for evidence packages
76
+
77
+ Intended use:
78
+ - audit artifacts
79
+ - benchmark reports
80
+ - freeze cases
81
+ - runtime outputs
82
+ - technical identity packages
83
+ """
84
+
85
+ def __init__(
86
+ self,
87
+ secret: Optional[str] = None,
88
+ signer_hint: str = "sovereign-local-seal",
89
+ ) -> None:
90
+ self.secret = _resolve_secret(secret)
91
+ self.signer_hint = signer_hint
92
+
93
+ # ---------------------------------------------------------
94
+ # Core digest functions
95
+ # ---------------------------------------------------------
96
+ def canonicalize(self, obj: Any) -> str:
97
+ return _canonical_json(obj)
98
+
99
+ def object_digest(self, obj: Any) -> str:
100
+ canonical = self.canonicalize(obj)
101
+ return _sha256_hex(canonical)
102
+
103
+ def _seal_digest(self, object_digest: str, object_type: str, metadata: Optional[Dict[str, Any]] = None) -> str:
104
+ payload = {
105
+ "scheme": DEFAULT_SCHEME,
106
+ "algorithm": DEFAULT_ALGO,
107
+ "object_type": object_type,
108
+ "object_digest": object_digest,
109
+ "metadata": metadata or {},
110
+ }
111
+ msg = _canonical_json(payload).encode("utf-8")
112
+ return hmac.new(self.secret.encode("utf-8"), msg, hashlib.sha256).hexdigest()
113
+
114
+ # ---------------------------------------------------------
115
+ # Public seal / verify
116
+ # ---------------------------------------------------------
117
+ def seal_object(
118
+ self,
119
+ obj: Any,
120
+ object_type: str,
121
+ metadata: Optional[Dict[str, Any]] = None,
122
+ ) -> Dict[str, Any]:
123
+ canonical = self.canonicalize(obj)
124
+ digest = _sha256_hex(canonical)
125
+
126
+ seal = SovereignSeal(
127
+ scheme=DEFAULT_SCHEME,
128
+ algorithm=DEFAULT_ALGO,
129
+ created_at=_utc_ts(),
130
+ object_type=str(object_type).strip() or "unknown_object",
131
+ object_digest=digest,
132
+ object_size=len(canonical.encode("utf-8")),
133
+ signer_hint=self.signer_hint,
134
+ seal_digest=self._seal_digest(
135
+ object_digest=digest,
136
+ object_type=object_type,
137
+ metadata=metadata,
138
+ ),
139
+ metadata=metadata or {},
140
+ )
141
+
142
+ return {
143
+ "ok": True,
144
+ "sealed": True,
145
+ "object_type": object_type,
146
+ "canonical": canonical,
147
+ "seal": seal.as_dict(),
148
+ }
149
+
150
+ def verify_object(
151
+ self,
152
+ obj: Any,
153
+ seal: Dict[str, Any],
154
+ ) -> Dict[str, Any]:
155
+ if not isinstance(seal, dict):
156
+ return {
157
+ "ok": False,
158
+ "verified": False,
159
+ "error": "invalid_seal_format",
160
+ }
161
+
162
+ object_type = str(seal.get("object_type", "unknown_object"))
163
+ metadata = seal.get("metadata") if isinstance(seal.get("metadata"), dict) else {}
164
+
165
+ canonical = self.canonicalize(obj)
166
+ digest = _sha256_hex(canonical)
167
+
168
+ if digest != seal.get("object_digest"):
169
+ return {
170
+ "ok": False,
171
+ "verified": False,
172
+ "error": "object_digest_mismatch",
173
+ "expected_digest": seal.get("object_digest"),
174
+ "actual_digest": digest,
175
+ }
176
+
177
+ expected_seal_digest = self._seal_digest(
178
+ object_digest=digest,
179
+ object_type=object_type,
180
+ metadata=metadata,
181
+ )
182
+
183
+ if expected_seal_digest != seal.get("seal_digest"):
184
+ return {
185
+ "ok": False,
186
+ "verified": False,
187
+ "error": "seal_digest_mismatch",
188
+ "expected_seal_digest": expected_seal_digest,
189
+ "actual_seal_digest": seal.get("seal_digest"),
190
+ }
191
+
192
+ return {
193
+ "ok": True,
194
+ "verified": True,
195
+ "object_type": object_type,
196
+ "object_digest": digest,
197
+ "seal_digest": expected_seal_digest,
198
+ }
199
+
200
+ # ---------------------------------------------------------
201
+ # Convenience helpers
202
+ # ---------------------------------------------------------
203
+ def build_manifest(
204
+ self,
205
+ *,
206
+ manifest_type: str,
207
+ subject_name: str,
208
+ subject_version: str,
209
+ artifacts: Dict[str, Any],
210
+ metadata: Optional[Dict[str, Any]] = None,
211
+ ) -> Dict[str, Any]:
212
+ artifact_entries = {}
213
+ for name, obj in artifacts.items():
214
+ artifact_entries[name] = {
215
+ "digest": self.object_digest(obj),
216
+ "type": type(obj).__name__,
217
+ }
218
+
219
+ manifest = {
220
+ "manifest_type": manifest_type,
221
+ "subject_name": subject_name,
222
+ "subject_version": subject_version,
223
+ "generated_at": _utc_ts(),
224
+ "artifacts": artifact_entries,
225
+ "metadata": metadata or {},
226
+ }
227
+
228
+ sealed = self.seal_object(
229
+ manifest,
230
+ object_type=f"manifest:{manifest_type}",
231
+ metadata={
232
+ "subject_name": subject_name,
233
+ "subject_version": subject_version,
234
+ },
235
+ )
236
+
237
+ return {
238
+ "manifest": manifest,
239
+ "seal": sealed["seal"],
240
+ }
241
+
242
+ def seal_runtime_result(
243
+ self,
244
+ result: Dict[str, Any],
245
+ metadata: Optional[Dict[str, Any]] = None,
246
+ ) -> Dict[str, Any]:
247
+ return self.seal_object(
248
+ result,
249
+ object_type="runtime_result",
250
+ metadata=metadata or {},
251
+ )
252
+
253
+ def seal_freeze_case(
254
+ self,
255
+ freeze_case: Dict[str, Any],
256
+ metadata: Optional[Dict[str, Any]] = None,
257
+ ) -> Dict[str, Any]:
258
+ return self.seal_object(
259
+ freeze_case,
260
+ object_type="freeze_case",
261
+ metadata=metadata or {},
262
+ )
263
+
264
+ def seal_benchmark_report(
265
+ self,
266
+ report: Dict[str, Any],
267
+ metadata: Optional[Dict[str, Any]] = None,
268
+ ) -> Dict[str, Any]:
269
+ return self.seal_object(
270
+ report,
271
+ object_type="benchmark_report",
272
+ metadata=metadata or {},
273
+ )
274
+
275
+
276
+ DEFAULT_SEALER = SovereignCryptoSeal()
277
+
278
+
279
+ def seal_object(
280
+ obj: Any,
281
+ object_type: str,
282
+ metadata: Optional[Dict[str, Any]] = None,
283
+ ) -> Dict[str, Any]:
284
+ return DEFAULT_SEALER.seal_object(obj, object_type, metadata)
285
+
286
+
287
+ def verify_object(obj: Any, seal: Dict[str, Any]) -> Dict[str, Any]:
288
+ return DEFAULT_SEALER.verify_object(obj, seal)
289
+
290
+
291
+ def build_manifest(
292
+ *,
293
+ manifest_type: str,
294
+ subject_name: str,
295
+ subject_version: str,
296
+ artifacts: Dict[str, Any],
297
+ metadata: Optional[Dict[str, Any]] = None,
298
+ ) -> Dict[str, Any]:
299
+ return DEFAULT_SEALER.build_manifest(
300
+ manifest_type=manifest_type,
301
+ subject_name=subject_name,
302
+ subject_version=subject_version,
303
+ artifacts=artifacts,
304
+ metadata=metadata,
305
+ )
306
+
307
+
308
+ if __name__ == "__main__":
309
+ sample = {
310
+ "decision": "FREEZE",
311
+ "reason": "high-risk payment context",
312
+ "risk_score": 91,
313
+ }
314
+
315
+ sealed = seal_object(
316
+ sample,
317
+ "runtime_result",
318
+ metadata={"environment": "banking", "stage": "demo"},
319
+ )
320
+ print(json.dumps(sealed, indent=2, ensure_ascii=False))
321
+
322
+ verified = verify_object(sample, sealed["seal"])
323
+ print(json.dumps(verified, indent=2, ensure_ascii=False))