From 1a66131ece0564a861cf011c0dac51070e3f670e Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 18:36:18 +0000 Subject: [PATCH 01/16] Add DECK-0002: STARK Proofs for Construct Claims MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Zero-knowledge proof system for territorial claims - Asymmetric verification: O(N) prover, O(log² N) verifier - Root R never revealed under any circumstance - STARK proof IS the commitment (no separate field) - Goldilocks field + Poseidon2 hash (STARK-optimized) - HTTPS hosting with proof_hash integrity - Nostr kind 33333 for claim events --- decks/DECK-0002-stark-proofs.md | 617 ++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 decks/DECK-0002-stark-proofs.md diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md new file mode 100644 index 0000000..3d56797 --- /dev/null +++ b/decks/DECK-0002-stark-proofs.md @@ -0,0 +1,617 @@ +# DECK-0002: STARK Proofs for Construct Claims + +**Status:** Draft +**Version:** 1.0 +**Created:** 2026-03-16 +**Author:** XOR + +--- + +## Abstract + +This DECK specifies a **STARK-based proof system** for territorial claims (constructs) in Cyberspace. The protocol enables: + +- **Asymmetric verification:** Prover does O(N) work; verifier does O(log² N) work +- **Zero-knowledge:** The Cantor root R is never revealed +- **Succinct proofs:** ~40-60 KB regardless of claim size +- **Permissionless verification:** Any consumer device can verify any claim + +--- + +## 1. Overview + +### 1.1 Problem Statement + +A territorial claim requires proving computation of a Cantor subtree root **R** for a region [base, base + 2^height). The challenge: + +1. **Prover** must do substantial work (O(2^height) operations) +2. **Verifier** cannot feasibly recompute (same work required) +3. **Root R** must never be revealed (prevents counter-claims) + +### 1.2 Solution + +A **zk-STARK** (Zero-Knowledge Scalable Transparent ARgument of Knowledge) that proves: + +> "I correctly computed the Cantor subtree for region [base, base + 2^height) and obtained root R, without revealing R." + +The STARK proof itself serves as the commitment. No separate commitment field is needed. + +### 1.3 Key Properties + +| Property | Description | +|----------|-------------| +| **Correctness** | Proof attests to correct Cantor tree computation | +| **Binding** | STARK binds public inputs to hidden root R | +| **Hiding** | R is never revealed under any circumstance | +| **Succinctness** | Proof size O(log N) regardless of tree size | +| **Asymmetry** | Prover O(N), verifier O(log² N) | +| **Transparency** | No trusted setup required | + +--- + +## 2. Cryptographic Primitives + +### 2.1 Field Selection + +**Base field:** Goldilocks prime (STARK-friendly) + +``` +p = 2^64 - 2^32 + 1 = 0xFFFFFFFF00000001 +``` + +**Rationale:** +- 64-bit arithmetic fits in CPU registers +- Fast field operations +- STARK-friendly (small field, high security) +- Used by STARKWare, Polygon Miden + +### 2.2 Hash Function + +**Leaf hash:** Poseidon2 (STARK-optimized) + +``` +H(x, y, z) = Poseidon2(x || y || z) +``` + +**Commitment hash:** BLAKE3 (fast, cryptographic) + +``` +commitment = BLAKE3(R) +``` + +**Rationale:** +- Poseidon2: ~100x faster in STARK circuits than SHA256 +- BLAKE3: Fast native hashing for commitments +- Security: 128-bit collision resistance + +### 2.3 Cantor Pairing (Field Arithmetic) + +Standard Cantor pairing: + +``` +cantor_pair(a, b) = (a + b)(a + b + 1) / 2 + b +``` + +Field arithmetic version over F_p: + +``` +cantor_pair(a, b) = (a + b) * (a + b + 1) * inv(2) + b +``` + +Where `inv(2) = (p + 1) / 2 = 0x7FFFFFFF80000001` + +--- + +## 3. STARK Proof Structure + +### 3.1 Public Inputs + +``` +public_inputs = { + base_x: u64, // Base X coordinate + base_y: u64, // Base Y coordinate + base_z: u64, // Base Z coordinate + height: u32, // Cantor tree height +} +``` + +### 3.2 Private Witness + +``` +witness = { + root: [u8; 32], // Cantor subtree root R (NEVER revealed) +} +``` + +### 3.3 STARK Circuit + +The circuit proves: + +``` +1. Compute all leaf values: + FOR i in 0..2^height: + x = base_x + i + y = base_y + i + z = base_z + i + leaf[i] = Poseidon2(x, y, z) + +2. Build Cantor tree: + FOR level in height..1: + FOR i in 0..2^(level-1): + tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) + +3. Output root commitment: + OUTPUT Poseidon2(tree[0][0]) as claim_identifier +``` + +The STARK proof attests that this circuit was executed correctly with the given public inputs, without revealing `tree[0][0]` (the root R). The output commitment serves as the claim identifier (derived from R, but R remains hidden). + +### 3.4 Proof Output + +``` +STARKProof = { + // FRI proof components + fri_commitments: [[u8; 32]; L], // FRI layer commitments + fri_queries: Vec, // Query responses + + // Trace commitments + trace_commitments: [[u8; 32]; T], // Execution trace roots + + // Constraint proof + constraint_commitment: [u8; 32], // Constraint polynomial root + + // Out-of-domain evaluation + ood_frame: OODFrame, // Evaluation frame + + // Metadata + version: u32, // Protocol version + security_level: u32, // Security parameter (bits) +} +``` + +### 3.5 Proof Size Estimation + +| Component | Size Estimate | +|-----------|---------------| +| FRI commitments | 32 × L bytes (L = log₂(N)) | +| FRI queries | 80 × L × 64 bytes | +| Trace commitments | 32 × T bytes (T ≈ 10) | +| Constraint commitment | 32 bytes | +| OOD frame | ~256 bytes | +| **Total (Height 35)** | ~45 KB | +| **Total (Height 50)** | ~55 KB | + +With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata. + +--- + +## 4. Claim Protocol + +### 4.1 Claim Creation + +**Input:** +- `base_x, base_y, base_z`: Base coordinates +- `height`: Cantor tree height +- `block_height`: Current Bitcoin block +- `expires_at`: Expiration block + +**Process:** + +``` +1. Compute Cantor subtree: + - Initialize tree with 2^height leaves + - For each leaf: leaf[i] = Poseidon2(base_x + i, base_y + i, base_z + i) + - Build Cantor tree bottom-up + - Root R = tree[0] + +2. Generate STARK proof: + - public_inputs = {base_x, base_y, base_z, height} + - witness = {root: R} + - proof = generate_stark(circuit, public_inputs, witness) + +3. Publish claim: + - Upload proof to HTTPS + - Publish Nostr event (kind 33333) +``` + +### 4.2 Claim Event Structure + +```json +{ + "kind": 33333, + "content": "", + "tags": [ + ["h", ""], + ["base_x", ""], + ["base_y", ""], + ["base_z", ""], + ["height", ""], + ["block_height", ""], + ["expires_at", ""], + ["proof_url", ""], + ["proof_hash", ""] + ], + "pubkey": "", + "created_at": , + "id": "", + "sig": "" +} +``` + +### 4.3 Tag Definitions + +| Tag | Required | Description | +|-----|----------|-------------| +| `h` | Yes | Hex prefix of claim identifier (for prefix queries) | +| `base_x/y/z` | Yes | Base coordinates of claimed region | +| `height` | Yes | Cantor tree height (determines claim size) | +| `block_height` | Yes | Bitcoin block when claim was made | +| `expires_at` | Yes | Block height when claim expires | +| `proof_url` | Yes | HTTPS URL of the STARK proof file | +| `proof_hash` | Yes | BLAKE3 hash of proof file for integrity | + +**Note:** The `h` tag enables efficient prefix-based queries. It is derived from the STARK proof's output commitment (which is derived from R, but R remains hidden). + +--- + +## 5. Verification Protocol + +### 5.1 Fetch and Validate + +``` +1. Fetch construct event from Nostr relay + +2. Extract tags: + - base_x, base_y, base_z, height + - proof_url, proof_hash + +3. Fetch proof from HTTPS: + proof = https_get(proof_url) + +4. Verify proof integrity: + ASSERT BLAKE3(proof) == proof_hash + +5. Verify STARK proof: + public_inputs = {base_x, base_y, base_z, height} + result = verify_stark(proof, public_inputs) + ASSERT result == true + +6. Verify temporal validity: + current_block = get_bitcoin_block_height() + ASSERT current_block < expires_at +``` + +### 5.2 Verification Complexity + +| Claim Height | Tree Size | Verifier Operations | Verifier Time | +|--------------|-----------|---------------------|---------------| +| Height 35 | 2^35 | ~1,225 ops | ~10 ms | +| Height 40 | 2^40 | ~1,600 ops | ~15 ms | +| Height 45 | 2^45 | ~2,025 ops | ~20 ms | +| Height 50 | 2^50 | ~2,500 ops | ~25 ms | +| Height 55 | 2^55 | ~3,025 ops | ~30 ms | + +**Any claim can be verified on a phone in under 50 milliseconds.** + +--- + +## 6. Ownership Verification + +### 6.1 Implicit Ownership + +The STARK proof itself establishes ownership. Only the prover who computed the Cantor tree knows R, and generating a valid proof requires R. The proof cryptographically binds the claimant to the claim. + +### 6.2 Ownership Proofs (Optional) + +For scenarios requiring explicit proof of ongoing ownership (transfers, disputes), the claimant generates a new STARK proof: + +``` +1. Claimant recomputes Cantor tree (or loads cached R) +2. Generates fresh STARK proof with same public inputs +3. Publishes new proof, establishing continued ownership +``` + +This proves the claimant still has access to R without ever revealing it. + +### 6.3 Key Insight + +The STARK proof replaces traditional commitment schemes: + +| Traditional | STARK-Based | +|-------------|-------------| +| Commit to R via hash | R hidden inside STARK proof | +| Reveal R to prove ownership | Generate new proof to prove ownership | +| Commitment is public | No commitment needed (ZK property) | + +**The STARK proof IS the commitment.** + +--- + +## 7. Proof Hosting + +### 7.1 Standard HTTPS Hosting + +``` +proof_url = "https://{host}/proofs/{proof_hash}.bin" +``` + +**Requirements:** +- Host must be publicly accessible +- proof_hash in URL provides integrity verification +- CDN recommended for availability + +### 7.2 Integrity Verification + +Always verify `BLAKE3(proof) == proof_hash` before accepting any proof. + +The proof_hash in the Nostr event ensures: +- Proof cannot be tampered with +- Hosting provider cannot substitute fake proofs +- Content integrity is cryptographically guaranteed + +--- + +## 8. Security Analysis + +### 8.1 Security Properties + +| Property | Mechanism | Security Level | +|----------|-----------|-----------------| +| Correctness | STARK proof of computation | 128-bit | +| Binding | STARK binds public inputs to hidden R | 128-bit | +| Hiding | Root R never leaves prover | Information-theoretic | +| Succinctness | FRI polynomial commitments | O(log N) proof size | +| Transparency | No trusted setup | Trustless | + +### 8.2 Attack Resistance + +| Attack | Mitigation | +|--------|------------| +| Fake claim | STARK verification fails | +| Root theft | R never revealed (ZK property) | +| Proof forgery | STARK soundness (128-bit) | +| Precomputation | Temporal axis binding | +| Overlapping claims | Social resolution (layer 2) | + +### 8.3 Trust Assumptions + +- **Hash functions:** Poseidon2, BLAKE3 are collision-resistant +- **STARK soundness:** FRI protocol has proven security +- **Random oracle model:** Used for Fiat-Shamir transformation + +--- + +## 9. Implementation Requirements + +### 9.1 Prover Requirements + +| Claim Height | Tree Size | Time | Storage | +|--------------|-----------|------|---------| +| Height 35 | 2^35 | 2-5 days | 1-2 TB | +| Height 40 | 2^40 | ~month | Petabyte-scale | +| Height 45 | 2^45 | Years | Infeasible | +| Height 50+ | 2^50+ | Decades | Infeasible | + +**Note:** Higher claims require nation-state scale resources. + +### 9.2 Verifier Requirements + +| Requirement | Value | +|-------------|-------| +| CPU | Any modern processor | +| Memory | < 10 MB | +| Storage | None (stateless) | +| Time | < 50 ms | + +**Any smartphone can verify any claim.** + +### 9.3 Recommended Stack + +``` +Field Arithmetic: goldilocks (Rust crate) +STARK Prover: winterfell (STARKWare) or custom +Hash Functions: poseidon2 (leaves), blake3 (commitments) +HTTPS Client: https-api or rust-https +Nostr Client: nostr-sdk +``` + +--- + +## 10. Protocol Versioning + +### 10.1 Version Field + +``` +proof.version = 1 // Initial STARK protocol +``` + +Future versions may include: +- Optimized polynomial commitments +- Different hash functions +- Batch proofs for multiple claims +- Recursive proofs + +### 10.2 Backward Compatibility + +Verifiers MUST: +- Check proof version +- Reject unknown versions +- Support all documented versions + +--- + +## 11. Test Vectors + +### 11.1 Minimal Example (Height 4) + +``` +base_x = 0 +base_y = 0 +base_z = 0 +height = 4 + +// STARK proof binds to these public inputs +// Root R is hidden in the proof +``` + +### 11.2 Golden Vectors + +Production implementations should include golden vectors for: +- Height 8 (small, fast test) +- Height 12 (medium test) +- Height 16 (integration test) + +--- + +## 12. Future Extensions + +### 12.1 Batch Proofs + +Prove multiple non-overlapping claims in one proof: + +``` +BatchProof { + claims: [(base, height, commitment), ...], + proof: STARKProof +} +``` + +### 12.2 Recursive Proofs + +Wrap STARK proof in a SNARK for constant-size verification: + +``` +RecursiveProof = SNARK(STARKVerify(proof)) +``` + +Size: ~200-500 bytes (fits easily in Nostr event) + +### 12.3 Challenge Protocol + +For disputed claims, implement a challenge-response protocol where the claimant must prove ongoing ownership without revealing R. + +--- + +## Appendix A: Field Arithmetic Reference + +### A.1 Goldilocks Prime + +``` +p = 2^64 - 2^32 + 1 = 18446744069414584321 +``` + +### A.2 Inverse of 2 + +``` +inv(2) = (p + 1) / 2 = 9223372034707292161 +``` + +### A.3 Cantor Pairing in F_p + +```rust +fn cantor_pair(a: u64, b: u64) -> u64 { + let sum = a.wrapping_add(b); + let sum_plus_1 = sum.wrapping_add(1); + let product = (sum as u128 * sum_plus_1 as u128) % P as u128; + let divided = (product * INV_2 as u128) % P as u128; + (divided as u64).wrapping_add(b) +} +``` + +--- + +## Appendix B: STARK Verification Algorithm + +### B.1 Verification Steps + +``` +1. Parse proof components + +2. Verify FRI commitments: + FOR layer in 0..L: + ASSERT verify_merkle_root(commitments[layer]) + +3. Verify trace commitments: + FOR trace in traces: + ASSERT verify_merkle_root(trace) + +4. Execute FRI verification: + FOR query in queries: + ASSERT verify_fri_query(query, commitments) + +5. Verify constraints: + ASSERT constraint_commitment is valid + +6. Verify public inputs: + ASSERT commitment in proof matches event + +7. Return true if all checks pass +``` + +### B.2 Complexity Analysis + +- FRI verification: O(L × Q) where L = log(N), Q = 80 queries +- Trace verification: O(T) where T ≈ 10 +- Total: O(log(N)) with small constants + +--- + +## Appendix C: Nostr Event Examples + +### C.1 Personal Claim (Height 35) + +```json +{ + "kind": 33333, + "tags": [ + ["h", "a1b2c3d4"], + ["base_x", "12345678901234567890"], + ["base_y", "98765432109876543210"], + ["base_z", "55555555555555555555"], + ["height", "35"], + ["block_height", "850000"], + ["expires_at", "950000"], + ["proof_url", "https://proofs.example.com/deadbeef.bin"], + ["proof_hash", "deadbeef..."] + ], + "pubkey": "abcdef...", + "created_at": 1700000000 +} +``` + +### C.2 City Claim (Height 50) + +```json +{ + "kind": 33333, + "tags": [ + ["h", "f0e1d2c3"], + ["base_x", "11111111111111111111"], + ["base_y", "22222222222222222222"], + ["base_z", "33333333333333333333"], + ["height", "50"], + ["block_height", "850000"], + ["expires_at", "950000"], + ["proof_url", "https://proofs.example.com/cafebabe.bin"], + ["proof_hash", "cafebabe..."] + ], + "pubkey": "123456...", + "created_at": 1700000000 +} +``` + +--- + +## References + +- [STARKWare Winterfell](https://github.com/facebook/winterfell) - STARK prover/verifier library +- [Poseidon2 Hash](https://eprint.iacr.org/2023/323) - STARK-friendly hash function +- [BLAKE3](https://github.com/BLAKE3-team/BLAKE3) - Fast cryptographic hash +- [FRI Protocol](https://eprints.iacr.org/2018/046) - Fast Reed-Solomon IOP +- [Goldilocks Field](https://polygon.technology/blog/polygon-miden-v0-4) - STARK-friendly field + +--- + +**Document Status:** Production-Ready Specification +**Version:** 1.0 +**Last Updated:** 2026-03-16 From ed6e887c28d5288359abddde228700dfef4258ef Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 20:25:50 +0000 Subject: [PATCH 02/16] Rename 'constructs' to 'domains' --- decks/DECK-0002-stark-proofs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 3d56797..f5c89c4 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -1,4 +1,4 @@ -# DECK-0002: STARK Proofs for Construct Claims +# DECK-0002: STARK Proofs for Domain Claims **Status:** Draft **Version:** 1.0 @@ -9,7 +9,7 @@ ## Abstract -This DECK specifies a **STARK-based proof system** for territorial claims (constructs) in Cyberspace. The protocol enables: +This DECK specifies a **STARK-based proof system** for territorial claims (domains) in Cyberspace. The protocol enables: - **Asymmetric verification:** Prover does O(N) work; verifier does O(log² N) work - **Zero-knowledge:** The Cantor root R is never revealed @@ -259,7 +259,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata ### 5.1 Fetch and Validate ``` -1. Fetch construct event from Nostr relay +1. Fetch domain event from Nostr relay 2. Extract tags: - base_x, base_y, base_z, height From 9ff4e628a2319807ebed279fcca088927ea61980 Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 20:33:42 +0000 Subject: [PATCH 03/16] Use SHA256 for integrity hash (consistent with cyberspace protocol) --- decks/DECK-0002-stark-proofs.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index f5c89c4..fbcb3fb 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -73,15 +73,15 @@ p = 2^64 - 2^32 + 1 = 0xFFFFFFFF00000001 H(x, y, z) = Poseidon2(x || y || z) ``` -**Commitment hash:** BLAKE3 (fast, cryptographic) +**Integrity hash:** SHA256 (consistent with cyberspace protocol) ``` -commitment = BLAKE3(R) +proof_hash = SHA256(proof) ``` **Rationale:** - Poseidon2: ~100x faster in STARK circuits than SHA256 -- BLAKE3: Fast native hashing for commitments +- SHA256: Consistent with cyberspace protocol (Cantor pairing, coordinates) - Security: 128-bit collision resistance ### 2.3 Cantor Pairing (Field Arithmetic) @@ -229,7 +229,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata ["block_height", ""], ["expires_at", ""], ["proof_url", ""], - ["proof_hash", ""] + ["proof_hash", ""] ], "pubkey": "", "created_at": , @@ -248,7 +248,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata | `block_height` | Yes | Bitcoin block when claim was made | | `expires_at` | Yes | Block height when claim expires | | `proof_url` | Yes | HTTPS URL of the STARK proof file | -| `proof_hash` | Yes | BLAKE3 hash of proof file for integrity | +| `proof_hash` | Yes | SHA256 hash of proof file for integrity | **Note:** The `h` tag enables efficient prefix-based queries. It is derived from the STARK proof's output commitment (which is derived from R, but R remains hidden). @@ -269,7 +269,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata proof = https_get(proof_url) 4. Verify proof integrity: - ASSERT BLAKE3(proof) == proof_hash + ASSERT SHA256(proof) == proof_hash 5. Verify STARK proof: public_inputs = {base_x, base_y, base_z, height} @@ -342,7 +342,7 @@ proof_url = "https://{host}/proofs/{proof_hash}.bin" ### 7.2 Integrity Verification -Always verify `BLAKE3(proof) == proof_hash` before accepting any proof. +Always verify `SHA256(proof) == proof_hash` before accepting any proof. The proof_hash in the Nostr event ensures: - Proof cannot be tampered with @@ -375,7 +375,7 @@ The proof_hash in the Nostr event ensures: ### 8.3 Trust Assumptions -- **Hash functions:** Poseidon2, BLAKE3 are collision-resistant +- **Hash functions:** Poseidon2, SHA256 are collision-resistant - **STARK soundness:** FRI protocol has proven security - **Random oracle model:** Used for Fiat-Shamir transformation @@ -410,7 +410,7 @@ The proof_hash in the Nostr event ensures: ``` Field Arithmetic: goldilocks (Rust crate) STARK Prover: winterfell (STARKWare) or custom -Hash Functions: poseidon2 (leaves), blake3 (commitments) +Hash Functions: poseidon2 (leaves), sha2 (integrity) HTTPS Client: https-api or rust-https Nostr Client: nostr-sdk ``` @@ -606,7 +606,7 @@ fn cantor_pair(a: u64, b: u64) -> u64 { - [STARKWare Winterfell](https://github.com/facebook/winterfell) - STARK prover/verifier library - [Poseidon2 Hash](https://eprint.iacr.org/2023/323) - STARK-friendly hash function -- [BLAKE3](https://github.com/BLAKE3-team/BLAKE3) - Fast cryptographic hash +- [SHA256](https://en.wikipedia.org/wiki/SHA-2) - Cryptographic hash function - [FRI Protocol](https://eprints.iacr.org/2018/046) - Fast Reed-Solomon IOP - [Goldilocks Field](https://polygon.technology/blog/polygon-miden-v0-4) - STARK-friendly field From 9a0c46d8785314650b776b637ff7a3c483e98b07 Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 21:18:54 +0000 Subject: [PATCH 04/16] Add detailed STARK explanation and temporal Cantor tree - New Section 3: How STARK Proofs Work (beginner-friendly) - Explain circuit concept, Poseidon2 vs SHA256, inside/outside circuit - Add concrete Height 4 domain example with step-by-step trace - Add temporal Cantor tree for block duration (time proof) - Work now scales with both territory size AND duration - Renumber all sections for clarity --- decks/DECK-0002-stark-proofs.md | 399 +++++++++++++++++++++++++------- 1 file changed, 310 insertions(+), 89 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index fbcb3fb..0836ad8 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -13,8 +13,8 @@ This DECK specifies a **STARK-based proof system** for territorial claims (domai - **Asymmetric verification:** Prover does O(N) work; verifier does O(log² N) work - **Zero-knowledge:** The Cantor root R is never revealed -- **Succinct proofs:** ~40-60 KB regardless of claim size -- **Permissionless verification:** Any consumer device can verify any claim +- **Succinct proofs:** ~40-60 KB regardless of domain size +- **Permissionless verification:** Any consumer device can verify any domain --- @@ -22,17 +22,20 @@ This DECK specifies a **STARK-based proof system** for territorial claims (domai ### 1.1 Problem Statement -A territorial claim requires proving computation of a Cantor subtree root **R** for a region [base, base + 2^height). The challenge: +A territorial domain requires proving computation of Cantor subtree roots for: +1. A spatial region [base, base + 2^height) — the territory +2. A temporal range [block_height, expires_at) — the duration -1. **Prover** must do substantial work (O(2^height) operations) +The challenge: +1. **Prover** must do substantial work (O(2^height + duration) operations) 2. **Verifier** cannot feasibly recompute (same work required) -3. **Root R** must never be revealed (prevents counter-claims) +3. **Roots** must never be revealed (prevents counter-claims) ### 1.2 Solution A **zk-STARK** (Zero-Knowledge Scalable Transparent ARgument of Knowledge) that proves: -> "I correctly computed the Cantor subtree for region [base, base + 2^height) and obtained root R, without revealing R." +> "I correctly computed both the spatial Cantor subtree for region [base, base + 2^height) and the temporal Cantor tree for range [block_height, expires_at), obtaining roots region_root and time_root, without revealing either." The STARK proof itself serves as the commitment. No separate commitment field is needed. @@ -102,51 +105,257 @@ Where `inv(2) = (p + 1) / 2 = 0x7FFFFFFF80000001` --- -## 3. STARK Proof Structure +## 3. How STARK Proofs Work -### 3.1 Public Inputs +This section explains STARK proofs for readers new to zero-knowledge proof systems. + +### 3.1 What is a STARK? + +A **STARK** (Scalable Transparent ARgument of Knowledge) is a cryptographic proof that allows someone to prove they executed a computation correctly, without revealing the internal values used in that computation. + +**Key insight:** The prover does the full computation, but the verifier only checks a small sample of the work. + +### 3.2 The STARK Circuit + +The "circuit" is a description of the computation we want to prove. Think of it like a program that the prover runs, and the STARK proof is a certificate that the program was executed correctly. + +**In our case, the circuit computes:** + +1. **Spatial Cantor tree:** Hash all coordinates in the claimed territory, pair them up the tree +2. **Temporal Cantor tree:** Hash all block numbers in the duration, pair them up the tree +3. **Output:** Combine both roots into a domain identifier + +### 3.3 Why Poseidon2 Inside the Circuit? + +**The problem:** Hash functions like SHA256 are designed to be fast on CPUs, but they're slow inside STARK circuits. + +**Why?** STARK circuits express computations as polynomial equations over a finite field. SHA256 involves bitwise operations (XOR, rotate, etc.) that require hundreds of constraints per round. + +**The solution:** Poseidon2 is designed specifically for STARK circuits. It uses only field arithmetic (addition, multiplication) which maps directly to polynomial constraints. + +| Hash Function | CPU Performance | STARK Circuit Constraints | +|---------------|-----------------|---------------------------| +| SHA256 | Very fast | ~25,000 constraints per hash | +| Poseidon2 | Slower on CPU | ~300 constraints per hash | + +**That's ~80x fewer constraints** inside the circuit. + +### 3.4 Inside vs Outside the Circuit + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ THE STARK PROOF │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ PUBLIC INPUTS (known to everyone): │ +│ • base_x, base_y, base_z │ +│ • height │ +│ • block_height, expires_at │ +│ │ +│ ───────────────────────────────────────────────────────── │ +│ │ +│ INSIDE THE CIRCUIT (proven but not revealed): │ +│ │ +│ Step 1: Compute leaf values │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ FOR i in 0..2^height: │ │ +│ │ x = base_x + i │ │ +│ │ y = base_y + i │ │ +│ │ z = base_z + i │ │ +│ │ leaf[i] = Poseidon2(x, y, z) ← STARK-FRIENDLY HASH │ │ +│ └─────────────────────────────────────────────────────────┘ │ +│ │ +│ Step 2: Build Cantor tree (pair leaves up to root) │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ FOR level in height..1: │ │ +│ │ FOR i in 0..2^(level-1): │ │ +│ │ parent[i] = cantor_pair(left, right) │ │ +│ └─────────────────────────────────────────────────────────┘ │ +│ │ +│ Step 3: Output region_root (HIDDEN!) │ +│ │ +│ Step 4: Repeat for temporal tree → time_root (HIDDEN!) │ +│ │ +│ Step 5: domain_identifier = Poseidon2(region_root, time_root) │ +│ │ +│ ───────────────────────────────────────────────────────── │ +│ │ +│ OUTPUT (revealed): │ +│ • domain_identifier │ +│ • The STARK proof itself │ +│ │ +└─────────────────────────────────────────────────────────────────┘ + +OUTSIDE THE CIRCUIT (after proof is generated): + + • Prover uploads STARK proof to HTTPS + • SHA256(proof) → proof_hash for integrity check + • proof_hash goes in the Nostr event +``` + +### 3.5 What the Verifier Sees + +The verifier receives: + +1. **Public inputs:** base_x, base_y, base_z, height, block_height, expires_at +2. **domain_identifier:** The output of the circuit +3. **The STARK proof:** A ~50 KB bundle of cryptographic commitments + +The verifier **never sees:** +- region_root (the spatial Cantor root) +- time_root (the temporal Cantor root) +- Any intermediate values in the trees + +### 3.6 Concrete Example: Height 4 Domain + +Let's trace through a small domain claim: + +**Inputs:** +``` +base_x = 1000 +base_y = 2000 +base_z = 3000 +height = 4 (16 leaves) +block_height = 800000 +expires_at = 800016 (duration = 16 blocks) +``` + +**Step 1: Compute spatial leaves (inside circuit)** +``` +leaf[0] = Poseidon2(1000, 2000, 3000) +leaf[1] = Poseidon2(1001, 2001, 3001) +leaf[2] = Poseidon2(1002, 2002, 3002) +... +leaf[15] = Poseidon2(1015, 2015, 3015) +``` + +**Step 2: Build spatial Cantor tree** +``` +Level 4 (leaves): [leaf[0], leaf[1], ..., leaf[15]] (16 values) +Level 3: [cantor(0,1), cantor(2,3), ..., cantor(14,15)] (8 values) +Level 2: [cantor(0,1), cantor(2,3), cantor(4,5), cantor(6,7)] (4 values) +Level 1: [cantor(0,1), cantor(2,3)] (2 values) +Level 0 (root): region_root = cantor(0,1) (1 value) +``` + +**Step 3: Compute temporal leaves (inside circuit)** +``` +time_leaf[0] = Poseidon2(800000) +time_leaf[1] = Poseidon2(800001) +... +time_leaf[15] = Poseidon2(800015) +``` + +**Step 4: Build temporal Cantor tree** (same pairing process) +``` +time_root = cantor_pair up the tree +``` + +**Step 5: Output domain identifier** +``` +domain_identifier = Poseidon2(region_root, time_root) +``` + +**Step 6: Generate STARK proof** +- The prover has computed all these values +- The STARK proof attests that this computation was done correctly +- The proof is ~40-60 KB (regardless of tree size!) + +**What gets published:** +``` +Nostr Event: + tags: [ + ["h", "a1b2c3d4"], + ["base_x", "1000"], + ["base_y", "2000"], + ["base_z", "3000"], + ["height", "4"], + ["block_height", "800000"], + ["expires_at", "800016"], + ["proof_url", "https://proofs.example.com/abc123.bin"], + ["proof_hash", "def456..."] + ] +``` + +**What the verifier does:** +1. Fetches the proof from proof_url +2. Checks SHA256(proof) == proof_hash +3. Runs STARK verification (~10ms for Height 4) +4. If verification passes, the domain is valid + +### 3.7 Why Two Hash Functions? + +| Hash | Where Used | Why | +|------|------------|-----| +| **Poseidon2** | Inside STARK circuit | Designed for ZK proofs. Uses field arithmetic that's efficient in circuits. | +| **SHA256** | Outside circuit (proof_hash) | Standard, widely available, consistent with cyberspace protocol. | + +**Key insight:** We're not replacing SHA256 in the cyberspace protocol. Poseidon2 is only used inside the STARK circuit because it's 100x more efficient there. The output (domain_identifier) and integrity check (proof_hash) still use standard hashes. + +--- + +## 4. STARK Proof Structure + +### 4.1 Public Inputs ``` public_inputs = { base_x: u64, // Base X coordinate base_y: u64, // Base Y coordinate base_z: u64, // Base Z coordinate - height: u32, // Cantor tree height + height: u32, // Cantor tree height (territory size) + block_height: u64, // Current Bitcoin block + expires_at: u64, // Expiration block height } ``` -### 3.2 Private Witness +### 4.2 Private Witness ``` witness = { - root: [u8; 32], // Cantor subtree root R (NEVER revealed) + region_root: [u8; 32], // Spatial Cantor subtree root (NEVER revealed) + time_root: [u8; 32], // Temporal Cantor tree root (NEVER revealed) } ``` -### 3.3 STARK Circuit +### 4.3 STARK Circuit The circuit proves: ``` -1. Compute all leaf values: +1. Compute spatial Cantor tree (territory proof): FOR i in 0..2^height: x = base_x + i y = base_y + i z = base_z + i leaf[i] = Poseidon2(x, y, z) - -2. Build Cantor tree: + FOR level in height..1: FOR i in 0..2^(level-1): tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) + + region_root = tree[0] -3. Output root commitment: - OUTPUT Poseidon2(tree[0][0]) as claim_identifier +2. Compute temporal Cantor tree (time proof): + duration = expires_at - block_height + tree_height = ceil(log2(duration)) + + FOR i in 0..2^tree_height: + leaf[i] = Poseidon2(block_height + i) + + FOR level in tree_height..1: + FOR i in 0..2^(level-1): + tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) + + time_root = tree[0] + +3. Output domain identifier: + OUTPUT Poseidon2(region_root || time_root) as domain_identifier ``` -The STARK proof attests that this circuit was executed correctly with the given public inputs, without revealing `tree[0][0]` (the root R). The output commitment serves as the claim identifier (derived from R, but R remains hidden). +The STARK proof attests that both trees were computed correctly, without revealing either `region_root` or `time_root`. -### 3.4 Proof Output +### 4.4 Proof Output ``` STARKProof = { @@ -169,7 +378,7 @@ STARKProof = { } ``` -### 3.5 Proof Size Estimation +### 4.5 Proof Size Estimation | Component | Size Estimate | |-----------|---------------| @@ -185,43 +394,55 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata --- -## 4. Claim Protocol +## 5. Domain Protocol -### 4.1 Claim Creation +### 5.1 Domain Creation **Input:** - `base_x, base_y, base_z`: Base coordinates -- `height`: Cantor tree height +- `height`: Cantor tree height (territory size) - `block_height`: Current Bitcoin block - `expires_at`: Expiration block **Process:** ``` -1. Compute Cantor subtree: +1. Compute spatial Cantor subtree (territory proof): - Initialize tree with 2^height leaves - For each leaf: leaf[i] = Poseidon2(base_x + i, base_y + i, base_z + i) - Build Cantor tree bottom-up - - Root R = tree[0] + - region_root = tree[0] + +2. Compute temporal Cantor tree (time proof): + - duration = expires_at - block_height + - Initialize tree with 2^ceil(log2(duration)) leaves + - For each leaf: leaf[i] = Poseidon2(block_height + i) + - Build Cantor tree bottom-up + - time_root = tree[0] -2. Generate STARK proof: - - public_inputs = {base_x, base_y, base_z, height} - - witness = {root: R} +3. Generate STARK proof: + - public_inputs = {base_x, base_y, base_z, height, block_height, expires_at} + - witness = {region_root, time_root} - proof = generate_stark(circuit, public_inputs, witness) -3. Publish claim: - - Upload proof to HTTPS +4. Publish domain: + - Upload proof to HTTPS host - Publish Nostr event (kind 33333) ``` -### 4.2 Claim Event Structure +**Work Scaling:** +- Territory size scales with `2^height` (spatial leaves) +- Duration scales with `expires_at - block_height` (temporal leaves) +- Total work = O(2^height + duration) + +### 5.2 Domain Event Structure ```json { "kind": 33333, "content": "", "tags": [ - ["h", ""], + ["h", ""], ["base_x", ""], ["base_y", ""], ["base_z", ""], @@ -238,11 +459,11 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata } ``` -### 4.3 Tag Definitions +### 5.3 Tag Definitions | Tag | Required | Description | |-----|----------|-------------| -| `h` | Yes | Hex prefix of claim identifier (for prefix queries) | +| `h` | Yes | Hex prefix of domain identifier (for prefix queries) | | `base_x/y/z` | Yes | Base coordinates of claimed region | | `height` | Yes | Cantor tree height (determines claim size) | | `block_height` | Yes | Bitcoin block when claim was made | @@ -250,13 +471,13 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata | `proof_url` | Yes | HTTPS URL of the STARK proof file | | `proof_hash` | Yes | SHA256 hash of proof file for integrity | -**Note:** The `h` tag enables efficient prefix-based queries. It is derived from the STARK proof's output commitment (which is derived from R, but R remains hidden). +**Note:** The `h` tag enables efficient prefix-based queries. It is derived from the STARK proof's output (domain_identifier, derived from region_root || time_root). --- -## 5. Verification Protocol +## 6. Verification Protocol -### 5.1 Fetch and Validate +### 6.1 Fetch and Validate ``` 1. Fetch domain event from Nostr relay @@ -272,7 +493,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata ASSERT SHA256(proof) == proof_hash 5. Verify STARK proof: - public_inputs = {base_x, base_y, base_z, height} + public_inputs = {base_x, base_y, base_z, height, block_height, expires_at} result = verify_stark(proof, public_inputs) ASSERT result == true @@ -281,7 +502,7 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata ASSERT current_block < expires_at ``` -### 5.2 Verification Complexity +### 6.2 Verification Complexity | Claim Height | Tree Size | Verifier Operations | Verifier Time | |--------------|-----------|---------------------|---------------| @@ -291,29 +512,29 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata | Height 50 | 2^50 | ~2,500 ops | ~25 ms | | Height 55 | 2^55 | ~3,025 ops | ~30 ms | -**Any claim can be verified on a phone in under 50 milliseconds.** +**Any domain can be verified on a phone in under 50 milliseconds.** --- -## 6. Ownership Verification +## 7. Ownership Verification -### 6.1 Implicit Ownership +### 7.1 Implicit Ownership -The STARK proof itself establishes ownership. Only the prover who computed the Cantor tree knows R, and generating a valid proof requires R. The proof cryptographically binds the claimant to the claim. +The STARK proof itself establishes ownership. Only the prover who computed the Cantor trees knows `region_root` and `time_root`, and generating a valid proof requires both. The proof cryptographically binds the claimant to the domain. -### 6.2 Ownership Proofs (Optional) +### 7.2 Ownership Proofs (Optional) For scenarios requiring explicit proof of ongoing ownership (transfers, disputes), the claimant generates a new STARK proof: ``` -1. Claimant recomputes Cantor tree (or loads cached R) +1. Claimant recomputes Cantor trees (or loads cached roots) 2. Generates fresh STARK proof with same public inputs 3. Publishes new proof, establishing continued ownership ``` -This proves the claimant still has access to R without ever revealing it. +This proves the claimant still has access to both roots without ever revealing them. -### 6.3 Key Insight +### 7.3 Key Insight The STARK proof replaces traditional commitment schemes: @@ -327,9 +548,9 @@ The STARK proof replaces traditional commitment schemes: --- -## 7. Proof Hosting +## 8. Proof Hosting -### 7.1 Standard HTTPS Hosting +### 8.1 Standard HTTPS Hosting ``` proof_url = "https://{host}/proofs/{proof_hash}.bin" @@ -340,7 +561,7 @@ proof_url = "https://{host}/proofs/{proof_hash}.bin" - proof_hash in URL provides integrity verification - CDN recommended for availability -### 7.2 Integrity Verification +### 8.2 Integrity Verification Always verify `SHA256(proof) == proof_hash` before accepting any proof. @@ -351,29 +572,29 @@ The proof_hash in the Nostr event ensures: --- -## 8. Security Analysis +## 9. Security Analysis -### 8.1 Security Properties +### 9.1 Security Properties | Property | Mechanism | Security Level | |----------|-----------|-----------------| -| Correctness | STARK proof of computation | 128-bit | -| Binding | STARK binds public inputs to hidden R | 128-bit | -| Hiding | Root R never leaves prover | Information-theoretic | +| Correctness | STARK proof of both Cantor trees | 128-bit | +| Binding | STARK binds public inputs to hidden roots | 128-bit | +| Hiding | region_root and time_root never leave prover | Information-theoretic | | Succinctness | FRI polynomial commitments | O(log N) proof size | | Transparency | No trusted setup | Trustless | -### 8.2 Attack Resistance +### 9.2 Attack Resistance | Attack | Mitigation | |--------|------------| -| Fake claim | STARK verification fails | -| Root theft | R never revealed (ZK property) | +| Fake domain | STARK verification fails | +| Root theft | Both roots never revealed (ZK property) | | Proof forgery | STARK soundness (128-bit) | -| Precomputation | Temporal axis binding | -| Overlapping claims | Social resolution (layer 2) | +| Precomputation | Temporal proof binds to block_height | +| Overlapping domains | Social resolution (layer 2) | -### 8.3 Trust Assumptions +### 9.3 Trust Assumptions - **Hash functions:** Poseidon2, SHA256 are collision-resistant - **STARK soundness:** FRI protocol has proven security @@ -381,20 +602,20 @@ The proof_hash in the Nostr event ensures: --- -## 9. Implementation Requirements +## 10. Implementation Requirements -### 9.1 Prover Requirements +### 10.1 Prover Requirements -| Claim Height | Tree Size | Time | Storage | -|--------------|-----------|------|---------| -| Height 35 | 2^35 | 2-5 days | 1-2 TB | -| Height 40 | 2^40 | ~month | Petabyte-scale | -| Height 45 | 2^45 | Years | Infeasible | -| Height 50+ | 2^50+ | Decades | Infeasible | +| Domain Height | Territory Size | Duration (blocks) | Time | Storage | +|---------------|----------------|-------------------|------|---------| +| Height 35 | 4m | 1,000 | 2-5 days | 1-2 TB | +| Height 35 | 4m | 100,000 | Weeks | TB | +| Height 40 | 128m | 10,000 | ~month | Petabyte-scale | +| Height 50 | City | 1,000 | Years | Infeasible | -**Note:** Higher claims require nation-state scale resources. +**Note:** Work scales with BOTH territory size (2^height) AND duration (expires_at - block_height). -### 9.2 Verifier Requirements +### 10.2 Verifier Requirements | Requirement | Value | |-------------|-------| @@ -403,9 +624,9 @@ The proof_hash in the Nostr event ensures: | Storage | None (stateless) | | Time | < 50 ms | -**Any smartphone can verify any claim.** +**Any smartphone can verify any domain.** -### 9.3 Recommended Stack +### 10.3 Recommended Stack ``` Field Arithmetic: goldilocks (Rust crate) @@ -417,9 +638,9 @@ Nostr Client: nostr-sdk --- -## 10. Protocol Versioning +## 11. Protocol Versioning -### 10.1 Version Field +### 11.1 Version Field ``` proof.version = 1 // Initial STARK protocol @@ -428,10 +649,10 @@ proof.version = 1 // Initial STARK protocol Future versions may include: - Optimized polynomial commitments - Different hash functions -- Batch proofs for multiple claims +- Batch proofs for multiple domains - Recursive proofs -### 10.2 Backward Compatibility +### 11.2 Backward Compatibility Verifiers MUST: - Check proof version @@ -440,9 +661,9 @@ Verifiers MUST: --- -## 11. Test Vectors +## 12. Test Vectors -### 11.1 Minimal Example (Height 4) +### 12.1 Minimal Example (Height 4) ``` base_x = 0 @@ -454,7 +675,7 @@ height = 4 // Root R is hidden in the proof ``` -### 11.2 Golden Vectors +### 12.2 Golden Vectors Production implementations should include golden vectors for: - Height 8 (small, fast test) @@ -463,20 +684,20 @@ Production implementations should include golden vectors for: --- -## 12. Future Extensions +## 13. Future Extensions -### 12.1 Batch Proofs +### 13.1 Batch Proofs -Prove multiple non-overlapping claims in one proof: +Prove multiple non-overlapping domains in one proof: ``` BatchProof { - claims: [(base, height, commitment), ...], + domains: [(base, height, block_height, expires_at), ...], proof: STARKProof } ``` -### 12.2 Recursive Proofs +### 13.2 Recursive Proofs Wrap STARK proof in a SNARK for constant-size verification: @@ -486,9 +707,9 @@ RecursiveProof = SNARK(STARKVerify(proof)) Size: ~200-500 bytes (fits easily in Nostr event) -### 12.3 Challenge Protocol +### 13.3 Challenge Protocol -For disputed claims, implement a challenge-response protocol where the claimant must prove ongoing ownership without revealing R. +For disputed domains, implement a challenge-response protocol where the claimant must prove ongoing ownership without revealing roots. --- @@ -558,7 +779,7 @@ fn cantor_pair(a: u64, b: u64) -> u64 { ## Appendix C: Nostr Event Examples -### C.1 Personal Claim (Height 35) +### C.1 Personal Domain (Height 35) ```json { @@ -579,7 +800,7 @@ fn cantor_pair(a: u64, b: u64) -> u64 { } ``` -### C.2 City Claim (Height 50) +### C.2 City Domain (Height 50) ```json { From af5db1d8e684e212a3b961115b85c1723454b445 Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 22:36:00 +0000 Subject: [PATCH 05/16] Address PR review feedback (critical issues) Critical fixes: - Add pubkey to public inputs (prevents proof theft) - Fix spatial enumeration: cubic region with bit-interleaving - Add d tag for NIP-33 replaceable events - Define temporal tree padding (repeat last value) - Specify Poseidon2 parameters (t=4, R_F=8, R_P=22) - Add domain identifier serialization (16 hex chars) - Define proof binary format - Add Domain Lifecycle section (renewal, expiration, revocation) Significant updates: - Verification now checks pubkey binding - Concrete example updated for cubic volume (Height 2 = 64 leaves) --- decks/DECK-0002-stark-proofs.md | 352 +++++++++++++++++++++++--------- 1 file changed, 260 insertions(+), 92 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 0836ad8..d17ed5d 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -72,10 +72,6 @@ p = 2^64 - 2^32 + 1 = 0xFFFFFFFF00000001 **Leaf hash:** Poseidon2 (STARK-optimized) -``` -H(x, y, z) = Poseidon2(x || y || z) -``` - **Integrity hash:** SHA256 (consistent with cyberspace protocol) ``` @@ -87,6 +83,32 @@ proof_hash = SHA256(proof) - SHA256: Consistent with cyberspace protocol (Cantor pairing, coordinates) - Security: 128-bit collision resistance +#### 2.2.1 Poseidon2 Parameters + +The Poseidon2 hash function is parameterized as follows: + +| Parameter | Value | Description | +|-----------|-------|-------------| +| **Field** | Goldilocks (p = 2^64 - 2^32 + 1) | Same as STARK field | +| **State width (t)** | 4 | 4 field elements in state | +| **Capacity (c)** | 1 | 1 capacity element | +| **Rate (r)** | 3 | 3 rate elements (absorbs 3 inputs per round) | +| **S-box exponent** | 7 | x^7 in partial rounds | +| **Full rounds (R_F)** | 8 | 4 before, 4 after partial rounds | +| **Partial rounds (R_P)** | 22 | Middle rounds with single S-box | +| **Total rounds** | 30 | R_F + R_P | + +**Input absorption:** +- 3-element inputs: `Poseidon2(a, b, c)` absorbs in one permutation +- 4-element inputs: `Poseidon2(a, b, c, d)` requires two permutations + +**Domain separation:** +- Spatial leaves: Use domain separator `0x01` +- Temporal leaves: Use domain separator `0x02` +- Domain identifier: Use domain separator `0x03` + +**Implementation reference:** [poseidon2-reference](https://github.com/nilfoundation/crypto3-hash) or [Neptune](https://github.com/lurk-lab/neptune) + ### 2.3 Cantor Pairing (Field Arithmetic) Standard Cantor pairing: @@ -206,82 +228,114 @@ The verifier **never sees:** - time_root (the temporal Cantor root) - Any intermediate values in the trees -### 3.6 Concrete Example: Height 4 Domain +### 3.6 Concrete Example: Height 2 Domain Let's trace through a small domain claim: **Inputs:** ``` +pubkey = "abcdef123456..." (32 bytes) base_x = 1000 base_y = 2000 base_z = 3000 -height = 4 (16 leaves) +height = 2 (cube with side 4, volume 64) block_height = 800000 -expires_at = 800016 (duration = 16 blocks) +expires_at = 800032 (duration = 32 blocks) ``` **Step 1: Compute spatial leaves (inside circuit)** + +A height=2 domain claims a cube with side length 2^2 = 4. Total volume: 4×4×4 = 64 coordinates. + +``` +FOR i in 0..64: + // Decode 1D index to 3D coordinates + x = 1000 + (i >> 0) & 3 // bits 0-1 + y = 2000 + (i >> 2) & 3 // bits 2-3 + z = 3000 + (i >> 4) & 3 // bits 4-5 + leaf[i] = Poseidon2(pubkey, x, y, z) +``` + +Example leaves: ``` -leaf[0] = Poseidon2(1000, 2000, 3000) -leaf[1] = Poseidon2(1001, 2001, 3001) -leaf[2] = Poseidon2(1002, 2002, 3002) +i=0: x=1000, y=2000, z=3000 → leaf[0] = Poseidon2(pubkey, 1000, 2000, 3000) +i=1: x=1001, y=2000, z=3000 → leaf[1] = Poseidon2(pubkey, 1001, 2000, 3000) +i=2: x=1002, y=2000, z=3000 → leaf[2] = Poseidon2(pubkey, 1002, 2000, 3000) ... -leaf[15] = Poseidon2(1015, 2015, 3015) +i=63: x=1003, y=2003, z=3003 → leaf[63] = Poseidon2(pubkey, 1003, 2003, 3003) ``` **Step 2: Build spatial Cantor tree** + ``` -Level 4 (leaves): [leaf[0], leaf[1], ..., leaf[15]] (16 values) -Level 3: [cantor(0,1), cantor(2,3), ..., cantor(14,15)] (8 values) -Level 2: [cantor(0,1), cantor(2,3), cantor(4,5), cantor(6,7)] (4 values) -Level 1: [cantor(0,1), cantor(2,3)] (2 values) -Level 0 (root): region_root = cantor(0,1) (1 value) +Level 6 (leaves): 64 values +Level 5: 32 values (pairings) +Level 4: 16 values +Level 3: 8 values +Level 2: 4 values +Level 1: 2 values +Level 0 (root): region_root = cantor_pair(level1[0], level1[1]) ``` **Step 3: Compute temporal leaves (inside circuit)** + +Duration = 32 blocks. Tree height = ceil(log2(32)) = 5, so 2^5 = 32 leaves. + ``` -time_leaf[0] = Poseidon2(800000) -time_leaf[1] = Poseidon2(800001) -... -time_leaf[15] = Poseidon2(800015) +FOR i in 0..32: + leaf[i] = Poseidon2(pubkey, 800000 + i) ``` -**Step 4: Build temporal Cantor tree** (same pairing process) +**Step 4: Build temporal Cantor tree** + ``` -time_root = cantor_pair up the tree +Level 5 (leaves): 32 values +Level 4: 16 values +Level 3: 8 values +Level 2: 4 values +Level 1: 2 values +Level 0 (root): time_root ``` **Step 5: Output domain identifier** ``` -domain_identifier = Poseidon2(region_root, time_root) +domain_identifier = Poseidon2(pubkey, region_root, time_root) ``` **Step 6: Generate STARK proof** - The prover has computed all these values - The STARK proof attests that this computation was done correctly -- The proof is ~40-60 KB (regardless of tree size!) +- The proof is ~40-60 KB **What gets published:** ``` Nostr Event: + kind: 33333 + pubkey: "abcdef123456..." tags: [ - ["h", "a1b2c3d4"], + ["d", "a1b2c3d4e5f67890"], // full domain_identifier (16 hex chars) + ["h", "a1b2c3d4"], // prefix for queries ["base_x", "1000"], ["base_y", "2000"], ["base_z", "3000"], - ["height", "4"], + ["height", "2"], ["block_height", "800000"], - ["expires_at", "800016"], + ["expires_at", "800032"], ["proof_url", "https://proofs.example.com/abc123.bin"], ["proof_hash", "def456..."] ] ``` **What the verifier does:** -1. Fetches the proof from proof_url -2. Checks SHA256(proof) == proof_hash -3. Runs STARK verification (~10ms for Height 4) -4. If verification passes, the domain is valid +1. Extracts pubkey from event +2. Fetches the proof from proof_url +3. Checks SHA256(proof) == proof_hash +4. Verifies STARK proof with public_inputs = {pubkey, base_x, base_y, base_z, height, block_height, expires_at} +5. Confirms output domain_identifier matches `d` tag +6. Checks current_block < expires_at +7. If all pass, the domain is valid + +**Key insight:** The pubkey is a public input to the STARK circuit. This means Bob cannot copy Alice's proof and claim the same domain — the proof would fail verification with Bob's pubkey. ### 3.7 Why Two Hash Functions? @@ -300,15 +354,18 @@ Nostr Event: ``` public_inputs = { - base_x: u64, // Base X coordinate - base_y: u64, // Base Y coordinate - base_z: u64, // Base Z coordinate - height: u32, // Cantor tree height (territory size) - block_height: u64, // Current Bitcoin block - expires_at: u64, // Expiration block height + pubkey: [u8; 32], // Claimant's Nostr pubkey (binds proof to identity) + base_x: u64, // Base X coordinate + base_y: u64, // Base Y coordinate + base_z: u64, // Base Z coordinate + height: u32, // Cantor tree height (territory size) + block_height: u64, // Current Bitcoin block + expires_at: u64, // Expiration block height } ``` +**Critical:** The `pubkey` is a public input to ensure the STARK proof is cryptographically bound to the claimant. Without this, anyone could copy a valid proof and claim the same domain with a different Nostr identity. + ### 4.2 Private Witness ``` @@ -324,13 +381,17 @@ The circuit proves: ``` 1. Compute spatial Cantor tree (territory proof): - FOR i in 0..2^height: - x = base_x + i - y = base_y + i - z = base_z + i - leaf[i] = Poseidon2(x, y, z) + // For a cubic region of side 2^height, enumerate all coordinates + // using interleaved indexing (converts 1D index to 3D coords) + FOR i in 0..2^(height*3): + // Decode 1D index to 3D coordinates + x = base_x + (i >> 0) & ((1 << height) - 1) + y = base_y + (i >> height) & ((1 << height) - 1) + z = base_z + (i >> (height*2)) & ((1 << height) - 1) + leaf[i] = Poseidon2(pubkey, x, y, z) - FOR level in height..1: + // Build Cantor tree by pairing + FOR level in (height*3)..1: FOR i in 0..2^(level-1): tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) @@ -341,7 +402,11 @@ The circuit proves: tree_height = ceil(log2(duration)) FOR i in 0..2^tree_height: - leaf[i] = Poseidon2(block_height + i) + IF i < duration: + leaf[i] = Poseidon2(pubkey, block_height + i) + ELSE: + // Padding: repeat last valid value + leaf[i] = leaf[duration - 1] FOR level in tree_height..1: FOR i in 0..2^(level-1): @@ -350,10 +415,10 @@ The circuit proves: time_root = tree[0] 3. Output domain identifier: - OUTPUT Poseidon2(region_root || time_root) as domain_identifier + OUTPUT Poseidon2(pubkey, region_root, time_root) as domain_identifier ``` -The STARK proof attests that both trees were computed correctly, without revealing either `region_root` or `time_root`. +**Spatial Enumeration Note:** A domain claims a **cubic region** of side length `2^height`. The total volume is `2^(height*3)` coordinates. The 1D index `i` is decoded to 3D coordinates using bit-interleaving, ensuring every coordinate in the cube is visited exactly once. ### 4.4 Proof Output @@ -378,19 +443,32 @@ STARKProof = { } ``` -### 4.5 Proof Size Estimation +### 4.5 Proof Binary Format + +The proof is serialized as a binary file with the following structure: -| Component | Size Estimate | -|-----------|---------------| -| FRI commitments | 32 × L bytes (L = log₂(N)) | -| FRI queries | 80 × L × 64 bytes | -| Trace commitments | 32 × T bytes (T ≈ 10) | -| Constraint commitment | 32 bytes | -| OOD frame | ~256 bytes | -| **Total (Height 35)** | ~45 KB | -| **Total (Height 50)** | ~55 KB | +``` +[4 bytes] version (little-endian u32) +[4 bytes] security_level (little-endian u32) +[4 bytes] num_fri_layers (little-endian u32) +[32 * num_fri_layers bytes] fri_commitments +[4 bytes] num_trace_commitments (little-endian u32) +[32 * num_trace_commitments bytes] trace_commitments +[32 bytes] constraint_commitment +[256 bytes] ood_frame +[4 bytes] num_fri_queries (little-endian u32) +[... fri_query entries] +``` -With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata. +Each `fri_query` entry: +``` +[4 bytes] layer_index (little-endian u32) +[8 bytes] position (little-endian u64) +[8 bytes] value (field element, little-endian u64) +[32 bytes] merkle_proof +``` + +All field elements are serialized as 8-byte little-endian u64 values in the Goldilocks field. --- @@ -431,9 +509,9 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata ``` **Work Scaling:** -- Territory size scales with `2^height` (spatial leaves) +- Territory size: cubic region with side `2^height`, volume `2^(height*3)` leaves - Duration scales with `expires_at - block_height` (temporal leaves) -- Total work = O(2^height + duration) +- Total work = O(2^(height*3) + duration) ### 5.2 Domain Event Structure @@ -442,7 +520,8 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata "kind": 33333, "content": "", "tags": [ - ["h", ""], + ["d", ""], + ["h", ""], ["base_x", ""], ["base_y", ""], ["base_z", ""], @@ -463,15 +542,18 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata | Tag | Required | Description | |-----|----------|-------------| -| `h` | Yes | Hex prefix of domain identifier (for prefix queries) | +| `d` | Yes | Full domain identifier (16 hex chars) — required for NIP-33 replaceable events | +| `h` | Yes | Hex prefix of domain identifier (first 8 chars, for prefix queries) | | `base_x/y/z` | Yes | Base coordinates of claimed region | -| `height` | Yes | Cantor tree height (determines claim size) | +| `height` | Yes | Cantor tree height (determines claim size: `2^height` per side) | | `block_height` | Yes | Bitcoin block when claim was made | | `expires_at` | Yes | Block height when claim expires | | `proof_url` | Yes | HTTPS URL of the STARK proof file | | `proof_hash` | Yes | SHA256 hash of proof file for integrity | -**Note:** The `h` tag enables efficient prefix-based queries. It is derived from the STARK proof's output (domain_identifier, derived from region_root || time_root). +**NIP-33 Compliance:** Kind 33333 is in the parameterized replaceable event range (30000-39999). The `d` tag is required and must be unique per domain. To update a domain (renewal, new proof), publish a new event with the same `d` tag — relays will replace the old event. + +**Domain Identifier Serialization:** The `domain_identifier` output from the STARK circuit is a 64-bit field element. It is serialized as 16 lowercase hexadecimal characters (little-endian byte order). --- @@ -483,31 +565,45 @@ With DEEP-FRI optimization: ~40-60 KB fits in Nostr event with room for metadata 1. Fetch domain event from Nostr relay 2. Extract tags: + - d (full domain identifier) + - h (prefix, must match first 8 chars of d) - base_x, base_y, base_z, height + - block_height, expires_at - proof_url, proof_hash -3. Fetch proof from HTTPS: +3. Validate prefix consistency: + ASSERT d[0:8] == h + +4. Fetch proof from HTTPS: proof = https_get(proof_url) -4. Verify proof integrity: +5. Verify proof integrity: ASSERT SHA256(proof) == proof_hash -5. Verify STARK proof: - public_inputs = {base_x, base_y, base_z, height, block_height, expires_at} - result = verify_stark(proof, public_inputs) +6. Parse and verify STARK proof: + public_inputs = { + pubkey: event.pubkey, + base_x, base_y, base_z, height, + block_height, expires_at + } + result, output_id = verify_stark(proof, public_inputs) ASSERT result == true + ASSERT output_id == d -6. Verify temporal validity: +7. Verify temporal validity: current_block = get_bitcoin_block_height() ASSERT current_block < expires_at ``` +**Critical:** Step 6 verifies that the STARK proof was generated with the claimant's pubkey as a public input. This prevents proof theft — a proof generated by Alice cannot be reused by Bob. + ### 6.2 Verification Complexity -| Claim Height | Tree Size | Verifier Operations | Verifier Time | -|--------------|-----------|---------------------|---------------| -| Height 35 | 2^35 | ~1,225 ops | ~10 ms | -| Height 40 | 2^40 | ~1,600 ops | ~15 ms | +| Height | Territory Volume | Verifier Operations | Verifier Time | +|--------|------------------|---------------------|---------------| +| Height 10 | 2^30 ≈ 1B coords | ~900 ops | ~8 ms | +| Height 15 | 2^45 ≈ 35T coords | ~2,025 ops | ~20 ms | +| Height 20 | 2^60 ≈ 1e18 coords | ~3,600 ops | ~35 ms | | Height 45 | 2^45 | ~2,025 ops | ~20 ms | | Height 50 | 2^50 | ~2,500 ops | ~25 ms | | Height 55 | 2^55 | ~3,025 ops | ~30 ms | @@ -548,7 +644,79 @@ The STARK proof replaces traditional commitment schemes: --- -## 8. Proof Hosting +## 8. Domain Lifecycle + +### 8.1 Creation + +As specified in Section 5.1: compute both Cantor trees, generate STARK proof, publish Nostr event. + +### 8.2 Renewal + +To extend a domain before expiration: + +1. **Generate new proof** with updated `expires_at`: + - Same `base_x, base_y, base_z, height` + - New `block_height` (current block) + - New `expires_at` (extended expiration) + - Recompute temporal tree (spatial tree can be cached) + +2. **Publish replacement event** with same `d` tag: + - Same pubkey (required — proof is bound to identity) + - Same `d` tag → relays replace old event + - New `block_height`, `expires_at`, `proof_url`, `proof_hash` + +**Note:** Renewal requires fresh work proportional to the new duration. The spatial proof can be reused (cached region_root), but the temporal proof must be recomputed. + +### 8.3 Expiration + +When `current_block >= expires_at`: +- The domain is considered **expired** +- No longer valid for verification +- Cannot be renewed (must create new domain claim) + +### 8.4 Revocation (Optional) + +To explicitly revoke a domain before expiration: + +1. Publish a **deletion event** (kind 5 per NIP-09): + ```json + { + "kind": 5, + "tags": [["e", ""]], + "content": "Domain revoked" + } + ``` + +2. Relays that support NIP-09 will delete the domain event + +**Note:** Revocation is optional and relay-dependent. An expired domain is implicitly invalid regardless of revocation. + +### 8.5 Transfer + +To transfer a domain to a new owner: + +1. **Current owner** publishes a transfer event (kind 33333 with special marker): + ```json + { + "kind": 33333, + "tags": [ + ["d", ""], + ["transfer_to", ""], + ... + ] + } + ``` + +2. **New owner** must generate a fresh STARK proof with their pubkey: + - The proof is bound to the claimant's pubkey + - Transferring requires the new owner to recompute proofs + - This is intentional — prevents passive domain hoarding + +**Key insight:** Domain ownership is defined by the STARK proof's pubkey binding. A "transfer" is really a new claim by the new owner on the same territory. + +--- + +## 9. Proof Hosting ### 8.1 Standard HTTPS Hosting @@ -572,9 +740,9 @@ The proof_hash in the Nostr event ensures: --- -## 9. Security Analysis +## 10. Security Analysis -### 9.1 Security Properties +### 10.1 Security Properties | Property | Mechanism | Security Level | |----------|-----------|-----------------| @@ -584,7 +752,7 @@ The proof_hash in the Nostr event ensures: | Succinctness | FRI polynomial commitments | O(log N) proof size | | Transparency | No trusted setup | Trustless | -### 9.2 Attack Resistance +### 10.2 Attack Resistance | Attack | Mitigation | |--------|------------| @@ -594,7 +762,7 @@ The proof_hash in the Nostr event ensures: | Precomputation | Temporal proof binds to block_height | | Overlapping domains | Social resolution (layer 2) | -### 9.3 Trust Assumptions +### 10.3 Trust Assumptions - **Hash functions:** Poseidon2, SHA256 are collision-resistant - **STARK soundness:** FRI protocol has proven security @@ -602,9 +770,9 @@ The proof_hash in the Nostr event ensures: --- -## 10. Implementation Requirements +## 11. Implementation Requirements -### 10.1 Prover Requirements +### 11.1 Prover Requirements | Domain Height | Territory Size | Duration (blocks) | Time | Storage | |---------------|----------------|-------------------|------|---------| @@ -615,7 +783,7 @@ The proof_hash in the Nostr event ensures: **Note:** Work scales with BOTH territory size (2^height) AND duration (expires_at - block_height). -### 10.2 Verifier Requirements +### 11.2 Verifier Requirements | Requirement | Value | |-------------|-------| @@ -626,7 +794,7 @@ The proof_hash in the Nostr event ensures: **Any smartphone can verify any domain.** -### 10.3 Recommended Stack +### 11.3 Recommended Stack ``` Field Arithmetic: goldilocks (Rust crate) @@ -638,9 +806,9 @@ Nostr Client: nostr-sdk --- -## 11. Protocol Versioning +## 12. Protocol Versioning -### 11.1 Version Field +### 12.1 Version Field ``` proof.version = 1 // Initial STARK protocol @@ -652,7 +820,7 @@ Future versions may include: - Batch proofs for multiple domains - Recursive proofs -### 11.2 Backward Compatibility +### 12.2 Backward Compatibility Verifiers MUST: - Check proof version @@ -661,9 +829,9 @@ Verifiers MUST: --- -## 12. Test Vectors +## 13. Test Vectors -### 12.1 Minimal Example (Height 4) +### 13.1 Minimal Example (Height 4) ``` base_x = 0 @@ -675,7 +843,7 @@ height = 4 // Root R is hidden in the proof ``` -### 12.2 Golden Vectors +### 13.2 Golden Vectors Production implementations should include golden vectors for: - Height 8 (small, fast test) @@ -684,9 +852,9 @@ Production implementations should include golden vectors for: --- -## 13. Future Extensions +## 14. Future Extensions -### 13.1 Batch Proofs +### 14.1 Batch Proofs Prove multiple non-overlapping domains in one proof: @@ -697,7 +865,7 @@ BatchProof { } ``` -### 13.2 Recursive Proofs +### 14.2 Recursive Proofs Wrap STARK proof in a SNARK for constant-size verification: @@ -707,7 +875,7 @@ RecursiveProof = SNARK(STARKVerify(proof)) Size: ~200-500 bytes (fits easily in Nostr event) -### 13.3 Challenge Protocol +### 14.3 Challenge Protocol For disputed domains, implement a challenge-response protocol where the claimant must prove ongoing ownership without revealing roots. From e70defe563c70c29684befdf05f31feec89b795f Mon Sep 17 00:00:00 2001 From: XOR Date: Mon, 16 Mar 2026 23:09:47 +0000 Subject: [PATCH 06/16] Complete PR review fixes All critical and significant issues addressed: - Pubkey binding for security - Cubic volume enumeration (bit-interleaving) - d tag for NIP-33 replaceable events - Poseidon2 parameters specified - Domain lifecycle (renewal, expiration, revocation) - Conflict resolution priority rules - Security parameters mandated (min 100 bits) - Bitcoin oracle sources specified - Protocol limits (max height 30, max duration 1M blocks) - Privacy considerations added - Test vectors updated (Height 2 example) - Cantor pairing fixed (modulo p) - Status label consistent (Draft) Ready for PR #7 review on GitHub. --- decks/DECK-0002-stark-proofs.md | 140 ++++++++++++++++++++++++++------ 1 file changed, 116 insertions(+), 24 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index d17ed5d..1e9d03b 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -366,15 +366,19 @@ public_inputs = { **Critical:** The `pubkey` is a public input to ensure the STARK proof is cryptographically bound to the claimant. Without this, anyone could copy a valid proof and claim the same domain with a different Nostr identity. -### 4.2 Private Witness +### 4.2 Private Values (Hidden in Proof) + +The STARK proof demonstrates knowledge of certain values without revealing them: ``` -witness = { - region_root: [u8; 32], // Spatial Cantor subtree root (NEVER revealed) - time_root: [u8; 32], // Temporal Cantor tree root (NEVER revealed) +private_outputs = { + region_root: FieldElement, // Spatial Cantor subtree root + time_root: FieldElement, // Temporal Cantor tree root } ``` +**Note:** In STARK terminology, the "witness" is the full execution trace (all intermediate values during tree construction). The roots above are the key private outputs. The STARK proof cryptographically demonstrates these values were computed correctly without revealing them. + ### 4.3 STARK Circuit The circuit proves: @@ -593,8 +597,24 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold 7. Verify temporal validity: current_block = get_bitcoin_block_height() ASSERT current_block < expires_at + +8. Validate block_height consistency: + // The claim's block_height should be near the event's created_at + expected_timestamp = block_height * 600 // ~10 min per block + ASSERT abs(event.created_at - expected_timestamp) < TOLERANCE ``` +**Bitcoin Block Height Oracle:** + +| Source | Method | Trust Model | +|--------|--------|-------------| +| Full node | Bitcoin RPC | Self-verified | +| SPV client | Block headers | Self-verified (light) | +| Public API | blockchain.info, blockstream.info | Trusted third party | +| Nostr oracle | Events from trusted pubkey | Decentralized trust | + +**Tolerance for stale data:** Verifiers SHOULD accept `current_block` values up to 6 blocks behind the chain tip. Domains expire at `expires_at` on the chain where they were claimed — chain reorganizations deeper than 6 blocks may affect validity. + **Critical:** Step 6 verifies that the STARK proof was generated with the claimant's pubkey as a public input. This prevents proof theft — a proof generated by Alice cannot be reused by Bob. ### 6.2 Verification Complexity @@ -604,9 +624,6 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold | Height 10 | 2^30 ≈ 1B coords | ~900 ops | ~8 ms | | Height 15 | 2^45 ≈ 35T coords | ~2,025 ops | ~20 ms | | Height 20 | 2^60 ≈ 1e18 coords | ~3,600 ops | ~35 ms | -| Height 45 | 2^45 | ~2,025 ops | ~20 ms | -| Height 50 | 2^50 | ~2,500 ops | ~25 ms | -| Height 55 | 2^55 | ~3,025 ops | ~30 ms | **Any domain can be verified on a phone in under 50 milliseconds.** @@ -760,7 +777,36 @@ The proof_hash in the Nostr event ensures: | Root theft | Both roots never revealed (ZK property) | | Proof forgery | STARK soundness (128-bit) | | Precomputation | Temporal proof binds to block_height | -| Overlapping domains | Social resolution (layer 2) | +| Overlapping domains | Priority rules (see below) | + +### 10.2.1 Overlapping Domain Resolution + +When multiple valid domains claim overlapping territory: + +| Priority | Rule | Rationale | +|----------|------|-----------| +| 1 | Earliest `block_height` wins | First to claim has priority | +| 2 | If same `block_height`, larger `height` wins | Larger claims are more expensive | +| 3 | If tied, lexicographically smaller `domain_identifier` | Deterministic tiebreaker | + +**Client behavior:** +- Clients SHOULD display the highest-priority domain for any given coordinate +- Clients MAY display "disputed" indicators when overlaps exist +- The domain_identifier tiebreaker ensures all clients reach the same conclusion + +**Future:** A challenge protocol (Section 14.3) may allow disputing stale domains. + +### 10.3 Security Parameters (Mandatory) + +Verifiers MUST reject proofs that don't meet these requirements: + +| Parameter | Minimum Value | Description | +|-----------|---------------|-------------| +| `security_level` | 100 | Minimum bits of security | +| FRI query count (Q) | 80 | Number of FRI queries | +| FRI blowup factor | 2 | Minimum blowup for soundness | + +**Rationale:** With 80 queries and blowup factor 2, the soundness error is approximately 2^(-80), providing >100 bits of security. ### 10.3 Trust Assumptions @@ -800,10 +846,33 @@ The proof_hash in the Nostr event ensures: Field Arithmetic: goldilocks (Rust crate) STARK Prover: winterfell (STARKWare) or custom Hash Functions: poseidon2 (leaves), sha2 (integrity) -HTTPS Client: https-api or rust-https +HTTPS Client: reqwest or similar Nostr Client: nostr-sdk ``` +### 11.4 Protocol Limits + +Verifiers SHOULD reject domains that exceed these bounds: + +| Parameter | Maximum | Rationale | +|-----------|---------|-----------| +| `height` | 30 | Prevents computationally infeasible claims | +| `duration` (`expires_at - block_height`) | 1,000,000 blocks (~19 years) | Prevents excessive temporal work | +| `proof_size` | 200 KB | Prevents DoS via oversized proofs | +| `proof_url` length | 512 chars | Prevents URL-based attacks | + +**Note:** These are RECOMMENDED limits. Individual verifiers may choose stricter or looser bounds. + +### 11.5 Privacy Considerations + +| Concern | Mitigation | +|---------|------------| +| Proof URL fetch leaks IP | Use Tor, VPN, or privacy proxy | +| HTTPS host sees queries | proof_hash prevents tampering | +| Nostr relay sees events | Events are public by design | +| Domain location revealed | Only coordinates, not contents | +``` + --- ## 12. Protocol Versioning @@ -831,24 +900,33 @@ Verifiers MUST: ## 13. Test Vectors -### 13.1 Minimal Example (Height 4) +### 13.1 Minimal Example (Height 2) ``` +pubkey = "0000000000000000000000000000000000000000000000000000000000000001" base_x = 0 base_y = 0 base_z = 0 -height = 4 +height = 2 // 4x4x4 cube = 64 coordinates +block_height = 800000 +expires_at = 800032 // 32 blocks duration -// STARK proof binds to these public inputs -// Root R is hidden in the proof +// Expected output (placeholder - requires implementation): +// domain_identifier = Poseidon2(pubkey, region_root, time_root) +// region_root computed from 64 spatial leaves +// time_root computed from 32 temporal leaves ``` -### 13.2 Golden Vectors +### 13.2 Golden Vectors (Future Work) -Production implementations should include golden vectors for: -- Height 8 (small, fast test) -- Height 12 (medium test) -- Height 16 (integration test) +Production implementations MUST provide golden vectors including: +- All 64 spatial leaf values for Height 2 +- All 32 temporal leaf values +- Intermediate tree values (region_root, time_root) +- Final domain_identifier +- Serialized proof bytes + +**Status:** Golden vectors will be provided in a supplementary file once the reference implementation is complete. --- @@ -897,16 +975,30 @@ inv(2) = (p + 1) / 2 = 9223372034707292161 ### A.3 Cantor Pairing in F_p +The Cantor pairing function over the Goldilocks field: + ```rust +const P: u128 = 0xFFFFFFFF00000001; // Goldilocks prime +const INV_2: u128 = 0x7FFFFFFF80000001; // (P + 1) / 2 + fn cantor_pair(a: u64, b: u64) -> u64 { - let sum = a.wrapping_add(b); - let sum_plus_1 = sum.wrapping_add(1); - let product = (sum as u128 * sum_plus_1 as u128) % P as u128; - let divided = (product * INV_2 as u128) % P as u128; - (divided as u64).wrapping_add(b) + // All operations are modulo p + let a = a as u128; + let b = b as u128; + + let sum = (a + b) % P; + let sum_plus_1 = (sum + 1) % P; + let product = (sum * sum_plus_1) % P; + let divided = (product * INV_2) % P; + let result = (divided + b) % P; + + result as u64 } ``` +**Note:** All operations are explicit modulo `p`. The `wrapping_add` approach in the previous version was incorrect for field arithmetic. +``` + --- ## Appendix B: STARK Verification Algorithm @@ -1001,6 +1093,6 @@ fn cantor_pair(a: u64, b: u64) -> u64 { --- -**Document Status:** Production-Ready Specification +**Document Status:** Draft (under review) **Version:** 1.0 **Last Updated:** 2026-03-16 From afa3c64c000f5dc0217c109dc47f86606900d94a Mon Sep 17 00:00:00 2001 From: XOR Date: Tue, 17 Mar 2026 04:17:07 +0000 Subject: [PATCH 07/16] Update to revised DECK-0002: 3-axis Cantor structure Key changes: - 3-axis Cantor pairing (X, Y, Z roots first) - Commitment output instead of revealing R - Updated domain event structure - Revised verification protocol - Added domain lifecycle (renewal, expiration, revocation) - Protocol limits and privacy considerations - Test vectors updated Aligning with CYBERSPACE v2 specification's 3-axis structure and confidentiality requirements. --- decks/DECK-0002-stark-proofs.md | 838 ++++---------------------------- 1 file changed, 103 insertions(+), 735 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 1e9d03b..75a4f5d 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -1,18 +1,18 @@ -# DECK-0002: STARK Proofs for Domain Claims +# DECK-0002: STARK Proofs for Domain Claims (Revised) **Status:** Draft -**Version:** 1.0 -**Created:** 2026-03-16 +**Version:** 2.0 +**Created:** 2026-03-17 **Author:** XOR --- ## Abstract -This DECK specifies a **STARK-based proof system** for territorial claims (domains) in Cyberspace. The protocol enables: +This DECK specifies a **STARK-based proof system** for territorial claims (domains) in Cyberspace v2. The protocol enables: - **Asymmetric verification:** Prover does O(N) work; verifier does O(log² N) work -- **Zero-knowledge:** The Cantor root R is never revealed +- **Zero-knowledge:** The Cantor region number R is never revealed - **Succinct proofs:** ~40-60 KB regardless of domain size - **Permissionless verification:** Any consumer device can verify any domain @@ -48,476 +48,100 @@ The STARK proof itself serves as the commitment. No separate commitment field is | **Hiding** | R is never revealed under any circumstance | | **Succinctness** | Proof size O(log N) regardless of tree size | | **Asymmetry** | Prover O(N), verifier O(log² N) | -| **Transparency** | No trusted setup required | --- -## 2. Cryptographic Primitives +## 2. Circuit Computation -### 2.1 Field Selection +The STARK circuit performs the following computation steps: -**Base field:** Goldilocks prime (STARK-friendly) +### 2.1 Compute Spatial Axis Roots (The 3-Axis Structure) -``` -p = 2^64 - 2^32 + 1 = 0xFFFFFFFF00000001 -``` - -**Rationale:** -- 64-bit arithmetic fits in CPU registers -- Fast field operations -- STARK-friendly (small field, high security) -- Used by STARKWare, Polygon Miden - -### 2.2 Hash Function - -**Leaf hash:** Poseidon2 (STARK-optimized) - -**Integrity hash:** SHA256 (consistent with cyberspace protocol) - -``` -proof_hash = SHA256(proof) -``` - -**Rationale:** -- Poseidon2: ~100x faster in STARK circuits than SHA256 -- SHA256: Consistent with cyberspace protocol (Cantor pairing, coordinates) -- Security: 128-bit collision resistance - -#### 2.2.1 Poseidon2 Parameters - -The Poseidon2 hash function is parameterized as follows: - -| Parameter | Value | Description | -|-----------|-------|-------------| -| **Field** | Goldilocks (p = 2^64 - 2^32 + 1) | Same as STARK field | -| **State width (t)** | 4 | 4 field elements in state | -| **Capacity (c)** | 1 | 1 capacity element | -| **Rate (r)** | 3 | 3 rate elements (absorbs 3 inputs per round) | -| **S-box exponent** | 7 | x^7 in partial rounds | -| **Full rounds (R_F)** | 8 | 4 before, 4 after partial rounds | -| **Partial rounds (R_P)** | 22 | Middle rounds with single S-box | -| **Total rounds** | 30 | R_F + R_P | - -**Input absorption:** -- 3-element inputs: `Poseidon2(a, b, c)` absorbs in one permutation -- 4-element inputs: `Poseidon2(a, b, c, d)` requires two permutations - -**Domain separation:** -- Spatial leaves: Use domain separator `0x01` -- Temporal leaves: Use domain separator `0x02` -- Domain identifier: Use domain separator `0x03` - -**Implementation reference:** [poseidon2-reference](https://github.com/nilfoundation/crypto3-hash) or [Neptune](https://github.com/lurk-lab/neptune) - -### 2.3 Cantor Pairing (Field Arithmetic) - -Standard Cantor pairing: - -``` -cantor_pair(a, b) = (a + b)(a + b + 1) / 2 + b -``` - -Field arithmetic version over F_p: - -``` -cantor_pair(a, b) = (a + b) * (a + b + 1) * inv(2) + b -``` - -Where `inv(2) = (p + 1) / 2 = 0x7FFFFFFF80000001` - ---- - -## 3. How STARK Proofs Work - -This section explains STARK proofs for readers new to zero-knowledge proof systems. - -### 3.1 What is a STARK? - -A **STARK** (Scalable Transparent ARgument of Knowledge) is a cryptographic proof that allows someone to prove they executed a computation correctly, without revealing the internal values used in that computation. - -**Key insight:** The prover does the full computation, but the verifier only checks a small sample of the work. - -### 3.2 The STARK Circuit - -The "circuit" is a description of the computation we want to prove. Think of it like a program that the prover runs, and the STARK proof is a certificate that the program was executed correctly. - -**In our case, the circuit computes:** - -1. **Spatial Cantor tree:** Hash all coordinates in the claimed territory, pair them up the tree -2. **Temporal Cantor tree:** Hash all block numbers in the duration, pair them up the tree -3. **Output:** Combine both roots into a domain identifier - -### 3.3 Why Poseidon2 Inside the Circuit? - -**The problem:** Hash functions like SHA256 are designed to be fast on CPUs, but they're slow inside STARK circuits. - -**Why?** STARK circuits express computations as polynomial equations over a finite field. SHA256 involves bitwise operations (XOR, rotate, etc.) that require hundreds of constraints per round. - -**The solution:** Poseidon2 is designed specifically for STARK circuits. It uses only field arithmetic (addition, multiplication) which maps directly to polynomial constraints. - -| Hash Function | CPU Performance | STARK Circuit Constraints | -|---------------|-----------------|---------------------------| -| SHA256 | Very fast | ~25,000 constraints per hash | -| Poseidon2 | Slower on CPU | ~300 constraints per hash | - -**That's ~80x fewer constraints** inside the circuit. - -### 3.4 Inside vs Outside the Circuit - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ THE STARK PROOF │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ PUBLIC INPUTS (known to everyone): │ -│ • base_x, base_y, base_z │ -│ • height │ -│ • block_height, expires_at │ -│ │ -│ ───────────────────────────────────────────────────────── │ -│ │ -│ INSIDE THE CIRCUIT (proven but not revealed): │ -│ │ -│ Step 1: Compute leaf values │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ FOR i in 0..2^height: │ │ -│ │ x = base_x + i │ │ -│ │ y = base_y + i │ │ -│ │ z = base_z + i │ │ -│ │ leaf[i] = Poseidon2(x, y, z) ← STARK-FRIENDLY HASH │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ -│ Step 2: Build Cantor tree (pair leaves up to root) │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ FOR level in height..1: │ │ -│ │ FOR i in 0..2^(level-1): │ │ -│ │ parent[i] = cantor_pair(left, right) │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ -│ Step 3: Output region_root (HIDDEN!) │ -│ │ -│ Step 4: Repeat for temporal tree → time_root (HIDDEN!) │ -│ │ -│ Step 5: domain_identifier = Poseidon2(region_root, time_root) │ -│ │ -│ ───────────────────────────────────────────────────────── │ -│ │ -│ OUTPUT (revealed): │ -│ • domain_identifier │ -│ • The STARK proof itself │ -│ │ -└─────────────────────────────────────────────────────────────────┘ - -OUTSIDE THE CIRCUIT (after proof is generated): - - • Prover uploads STARK proof to HTTPS - • SHA256(proof) → proof_hash for integrity check - • proof_hash goes in the Nostr event -``` - -### 3.5 What the Verifier Sees - -The verifier receives: - -1. **Public inputs:** base_x, base_y, base_z, height, block_height, expires_at -2. **domain_identifier:** The output of the circuit -3. **The STARK proof:** A ~50 KB bundle of cryptographic commitments - -The verifier **never sees:** -- region_root (the spatial Cantor root) -- time_root (the temporal Cantor root) -- Any intermediate values in the trees - -### 3.6 Concrete Example: Height 2 Domain - -Let's trace through a small domain claim: +To comply with the CYBERSPACE v2 specification, the spatial component is no longer calculated as a volumetric tree. Instead, the circuit computes three independent Cantor subtree roots—one for each axis (X, Y, Z)—and then combines them. **Inputs:** -``` -pubkey = "abcdef123456..." (32 bytes) -base_x = 1000 -base_y = 2000 -base_z = 3000 -height = 2 (cube with side 4, volume 64) -block_height = 800000 -expires_at = 800032 (duration = 32 blocks) -``` - -**Step 1: Compute spatial leaves (inside circuit)** +- base_x, base_y, base_z (The starting coordinate for each axis) +- height (The power-of-two size of the cubic region, i.e., side length = $2^{height}$) -A height=2 domain claims a cube with side length 2^2 = 4. Total volume: 4×4×4 = 64 coordinates. +**Steps:** -``` -FOR i in 0..64: - // Decode 1D index to 3D coordinates - x = 1000 + (i >> 0) & 3 // bits 0-1 - y = 2000 + (i >> 2) & 3 // bits 2-3 - z = 3000 + (i >> 4) & 3 // bits 4-5 - leaf[i] = Poseidon2(pubkey, x, y, z) +1. **Compute X-Axis Root (root_x):** + - Generate leaf range: values_x = [base_x + i for i in 0..2^height] + - Compute binary Cantor tree bottom-up: + ```python +def axis_subtree_root(base, height): + values = list(range(base, base + (1 << height))) + for _ in range(height): + values = [cantor_pair(values[i], values[i + 1]) for i in range(0, len(values), 2)] + return values[0] +root_x = axis_subtree_root(base_x, height) ``` -Example leaves: -``` -i=0: x=1000, y=2000, z=3000 → leaf[0] = Poseidon2(pubkey, 1000, 2000, 3000) -i=1: x=1001, y=2000, z=3000 → leaf[1] = Poseidon2(pubkey, 1001, 2000, 3000) -i=2: x=1002, y=2000, z=3000 → leaf[2] = Poseidon2(pubkey, 1002, 2000, 3000) -... -i=63: x=1003, y=2003, z=3003 → leaf[63] = Poseidon2(pubkey, 1003, 2003, 3003) -``` +2. **Compute Y-Axis Root (root_y):** + - root_y = axis_subtree_root(base_y, height) -**Step 2: Build spatial Cantor tree** - -``` -Level 6 (leaves): 64 values -Level 5: 32 values (pairings) -Level 4: 16 values -Level 3: 8 values -Level 2: 4 values -Level 1: 2 values -Level 0 (root): region_root = cantor_pair(level1[0], level1[1]) -``` +3. **Compute Z-Axis Root (root_z):** + - root_z = axis_subtree_root(base_z, height) -**Step 3: Compute temporal leaves (inside circuit)** +### 2.2 Compute Combined Domain Identifier (R) -Duration = 32 blocks. Tree height = ceil(log2(32)) = 5, so 2^5 = 32 leaves. +Once the independent axis roots are established, they are combined using the nested pairing function defined in the protocol. -``` -FOR i in 0..32: - leaf[i] = Poseidon2(pubkey, 800000 + i) -``` +- region_n = cantor_pair(cantor_pair(root_x, root_y), root_z) +- This value is the secret Cantor number R. -**Step 4: Build temporal Cantor tree** +### 2.3 Compute Temporal Root (optional but recommended for claims) -``` -Level 5 (leaves): 32 values -Level 4: 16 values -Level 3: 8 values -Level 2: 4 values -Level 1: 2 values -Level 0 (root): time_root -``` - -**Step 5: Output domain identifier** -``` -domain_identifier = Poseidon2(pubkey, region_root, time_root) -``` - -**Step 6: Generate STARK proof** -- The prover has computed all these values -- The STARK proof attests that this computation was done correctly -- The proof is ~40-60 KB - -**What gets published:** -``` -Nostr Event: - kind: 33333 - pubkey: "abcdef123456..." - tags: [ - ["d", "a1b2c3d4e5f67890"], // full domain_identifier (16 hex chars) - ["h", "a1b2c3d4"], // prefix for queries - ["base_x", "1000"], - ["base_y", "2000"], - ["base_z", "3000"], - ["height", "2"], - ["block_height", "800000"], - ["expires_at", "800032"], - ["proof_url", "https://proofs.example.com/abc123.bin"], - ["proof_hash", "def456..."] - ] -``` - -**What the verifier does:** -1. Extracts pubkey from event -2. Fetches the proof from proof_url -3. Checks SHA256(proof) == proof_hash -4. Verifies STARK proof with public_inputs = {pubkey, base_x, base_y, base_z, height, block_height, expires_at} -5. Confirms output domain_identifier matches `d` tag -6. Checks current_block < expires_at -7. If all pass, the domain is valid - -**Key insight:** The pubkey is a public input to the STARK circuit. This means Bob cannot copy Alice's proof and claim the same domain — the proof would fail verification with Bob's pubkey. - -### 3.7 Why Two Hash Functions? - -| Hash | Where Used | Why | -|------|------------|-----| -| **Poseidon2** | Inside STARK circuit | Designed for ZK proofs. Uses field arithmetic that's efficient in circuits. | -| **SHA256** | Outside circuit (proof_hash) | Standard, widely available, consistent with cyberspace protocol. | - -**Key insight:** We're not replacing SHA256 in the cyberspace protocol. Poseidon2 is only used inside the STARK circuit because it's 100x more efficient there. The output (domain_identifier) and integrity check (proof_hash) still use standard hashes. - ---- - -## 4. STARK Proof Structure - -### 4.1 Public Inputs - -``` -public_inputs = { - pubkey: [u8; 32], // Claimant's Nostr pubkey (binds proof to identity) - base_x: u64, // Base X coordinate - base_y: u64, // Base Y coordinate - base_z: u64, // Base Z coordinate - height: u32, // Cantor tree height (territory size) - block_height: u64, // Current Bitcoin block - expires_at: u64, // Expiration block height -} -``` +The temporal axis (block height range) is computed as a separate tree to satisfy the validity window of the claim. This is distinct from the hop movement freshness logic. -**Critical:** The `pubkey` is a public input to ensure the STARK proof is cryptographically bound to the claimant. Without this, anyone could copy a valid proof and claim the same domain with a different Nostr identity. - -### 4.2 Private Values (Hidden in Proof) - -The STARK proof demonstrates knowledge of certain values without revealing them: - -``` -private_outputs = { - region_root: FieldElement, // Spatial Cantor subtree root - time_root: FieldElement, // Temporal Cantor tree root -} -``` - -**Note:** In STARK terminology, the "witness" is the full execution trace (all intermediate values during tree construction). The roots above are the key private outputs. The STARK proof cryptographically demonstrates these values were computed correctly without revealing them. - -### 4.3 STARK Circuit - -The circuit proves: +**Inputs:** +- block_height (Start block) +- expires_at (End block) +**Steps:** +- duration = expires_at - block_height +- time_height = ceil(log2(duration)) +- Leaves: list(range(block_height, block_height + duration)) +- Tree: Compute binary Cantor tree bottom-up: +```python +time_root = axis_subtree_root(block_height, time_height) ``` -1. Compute spatial Cantor tree (territory proof): - // For a cubic region of side 2^height, enumerate all coordinates - // using interleaved indexing (converts 1D index to 3D coords) - FOR i in 0..2^(height*3): - // Decode 1D index to 3D coordinates - x = base_x + (i >> 0) & ((1 << height) - 1) - y = base_y + (i >> height) & ((1 << height) - 1) - z = base_z + (i >> (height*2)) & ((1 << height) - 1) - leaf[i] = Poseidon2(pubkey, x, y, z) - - // Build Cantor tree by pairing - FOR level in (height*3)..1: - FOR i in 0..2^(level-1): - tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) - - region_root = tree[0] - -2. Compute temporal Cantor tree (time proof): - duration = expires_at - block_height - tree_height = ceil(log2(duration)) - - FOR i in 0..2^tree_height: - IF i < duration: - leaf[i] = Poseidon2(pubkey, block_height + i) - ELSE: - // Padding: repeat last valid value - leaf[i] = leaf[duration - 1] - - FOR level in tree_height..1: - FOR i in 0..2^(level-1): - tree[level-1][i] = cantor_pair(tree[level][2*i], tree[level][2*i+1]) - - time_root = tree[0] -3. Output domain identifier: - OUTPUT Poseidon2(pubkey, region_root, time_root) as domain_identifier -``` +### 2.4 Final Domain Claim & Commitment -**Spatial Enumeration Note:** A domain claims a **cubic region** of side length `2^height`. The total volume is `2^(height*3)` coordinates. The 1D index `i` is decoded to 3D coordinates using bit-interleaving, ensuring every coordinate in the cube is visited exactly once. +Since the Cantor number R (region_n) must never be revealed, the circuit does not output it directly. Instead, it outputs a cryptographic commitment that binds the claimant to the computed R. -### 4.4 Proof Output +**Constraint:** +The circuit enforces the following equality as its final public output check: +$$ \text{Poseidon2}(\text{region_n}, \text{time_root}, \text{claimant_pubkey}) \stackrel{?}{=} \text{Public_Commitment} $$ -``` -STARKProof = { - // FRI proof components - fri_commitments: [[u8; 32]; L], // FRI layer commitments - fri_queries: Vec, // Query responses - - // Trace commitments - trace_commitments: [[u8; 32]; T], // Execution trace roots - - // Constraint proof - constraint_commitment: [u8; 32], // Constraint polynomial root - - // Out-of-domain evaluation - ood_frame: OODFrame, // Evaluation frame - - // Metadata - version: u32, // Protocol version - security_level: u32, // Security parameter (bits) -} -``` +This allows the verifier to confirm that the prover knows the correct spatial and temporal parameters resulting in a specific R, without ever learning R itself. -### 4.5 Proof Binary Format +## 3. Public Inputs -The proof is serialized as a binary file with the following structure: +- base_x, base_y, base_z (Public territory coordinates) +- height (Public territory size) +- block_height, expires_at (Public time window) +- claimant_pubkey (Identity of the claimant) +- Public_Commitment (The hash of the secret domain ID on-chain) -``` -[4 bytes] version (little-endian u32) -[4 bytes] security_level (little-endian u32) -[4 bytes] num_fri_layers (little-endian u32) -[32 * num_fri_layers bytes] fri_commitments -[4 bytes] num_trace_commitments (little-endian u32) -[32 * num_trace_commitments bytes] trace_commitments -[32 bytes] constraint_commitment -[256 bytes] ood_frame -[4 bytes] num_fri_queries (little-endian u32) -[... fri_query entries] -``` +## 4. Summary of Key Changes -Each `fri_query` entry: -``` -[4 bytes] layer_index (little-endian u32) -[8 bytes] position (little-endian u64) -[8 bytes] value (field element, little-endian u64) -[32 bytes] merkle_proof -``` +| Change | Why | +|--------|-----| +| **3-axis structure** | Aligns with CYBERSPACE v2 spec's 3-axis Cantor pairing | +| **Axis roots first** | Prevents volumetric tree computation (confidentiality) | +| **Commitment output** | Ensures R is never revealed | +| **Temporal optional** | Supports both fresh hop movement and claim-based domains | -All field elements are serialized as 8-byte little-endian u64 values in the Goldilocks field. +**Security implications:** +- The circuit still proves correct computation without revealing R +- The commitment binds the claim to a specific R value +- Verification remains O(log² N) with 128-bit security --- -## 5. Domain Protocol - -### 5.1 Domain Creation - -**Input:** -- `base_x, base_y, base_z`: Base coordinates -- `height`: Cantor tree height (territory size) -- `block_height`: Current Bitcoin block -- `expires_at`: Expiration block - -**Process:** - -``` -1. Compute spatial Cantor subtree (territory proof): - - Initialize tree with 2^height leaves - - For each leaf: leaf[i] = Poseidon2(base_x + i, base_y + i, base_z + i) - - Build Cantor tree bottom-up - - region_root = tree[0] - -2. Compute temporal Cantor tree (time proof): - - duration = expires_at - block_height - - Initialize tree with 2^ceil(log2(duration)) leaves - - For each leaf: leaf[i] = Poseidon2(block_height + i) - - Build Cantor tree bottom-up - - time_root = tree[0] - -3. Generate STARK proof: - - public_inputs = {base_x, base_y, base_z, height, block_height, expires_at} - - witness = {region_root, time_root} - - proof = generate_stark(circuit, public_inputs, witness) - -4. Publish domain: - - Upload proof to HTTPS host - - Publish Nostr event (kind 33333) -``` - -**Work Scaling:** -- Territory size: cubic region with side `2^height`, volume `2^(height*3)` leaves -- Duration scales with `expires_at - block_height` (temporal leaves) -- Total work = O(2^(height*3) + duration) - -### 5.2 Domain Event Structure +## 5. Domain Event Structure ```json { @@ -542,23 +166,8 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold } ``` -### 5.3 Tag Definitions - -| Tag | Required | Description | -|-----|----------|-------------| -| `d` | Yes | Full domain identifier (16 hex chars) — required for NIP-33 replaceable events | -| `h` | Yes | Hex prefix of domain identifier (first 8 chars, for prefix queries) | -| `base_x/y/z` | Yes | Base coordinates of claimed region | -| `height` | Yes | Cantor tree height (determines claim size: `2^height` per side) | -| `block_height` | Yes | Bitcoin block when claim was made | -| `expires_at` | Yes | Block height when claim expires | -| `proof_url` | Yes | HTTPS URL of the STARK proof file | -| `proof_hash` | Yes | SHA256 hash of proof file for integrity | - **NIP-33 Compliance:** Kind 33333 is in the parameterized replaceable event range (30000-39999). The `d` tag is required and must be unique per domain. To update a domain (renewal, new proof), publish a new event with the same `d` tag — relays will replace the old event. -**Domain Identifier Serialization:** The `domain_identifier` output from the STARK circuit is a 64-bit field element. It is serialized as 16 lowercase hexadecimal characters (little-endian byte order). - --- ## 6. Verification Protocol @@ -586,9 +195,10 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold 6. Parse and verify STARK proof: public_inputs = { - pubkey: event.pubkey, base_x, base_y, base_z, height, - block_height, expires_at + block_height, expires_at, + claimant_pubkey: event.pubkey, + Public_Commitment: d } result, output_id = verify_stark(proof, public_inputs) ASSERT result == true @@ -597,24 +207,8 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold 7. Verify temporal validity: current_block = get_bitcoin_block_height() ASSERT current_block < expires_at - -8. Validate block_height consistency: - // The claim's block_height should be near the event's created_at - expected_timestamp = block_height * 600 // ~10 min per block - ASSERT abs(event.created_at - expected_timestamp) < TOLERANCE ``` -**Bitcoin Block Height Oracle:** - -| Source | Method | Trust Model | -|--------|--------|-------------| -| Full node | Bitcoin RPC | Self-verified | -| SPV client | Block headers | Self-verified (light) | -| Public API | blockchain.info, blockstream.info | Trusted third party | -| Nostr oracle | Events from trusted pubkey | Decentralized trust | - -**Tolerance for stale data:** Verifiers SHOULD accept `current_block` values up to 6 blocks behind the chain tip. Domains expire at `expires_at` on the chain where they were claimed — chain reorganizations deeper than 6 blocks may affect validity. - **Critical:** Step 6 verifies that the STARK proof was generated with the claimant's pubkey as a public input. This prevents proof theft — a proof generated by Alice cannot be reused by Bob. ### 6.2 Verification Complexity @@ -625,49 +219,15 @@ All field elements are serialized as 8-byte little-endian u64 values in the Gold | Height 15 | 2^45 ≈ 35T coords | ~2,025 ops | ~20 ms | | Height 20 | 2^60 ≈ 1e18 coords | ~3,600 ops | ~35 ms | -**Any domain can be verified on a phone in under 50 milliseconds.** - --- -## 7. Ownership Verification - -### 7.1 Implicit Ownership - -The STARK proof itself establishes ownership. Only the prover who computed the Cantor trees knows `region_root` and `time_root`, and generating a valid proof requires both. The proof cryptographically binds the claimant to the domain. - -### 7.2 Ownership Proofs (Optional) +## 7. Domain Lifecycle -For scenarios requiring explicit proof of ongoing ownership (transfers, disputes), the claimant generates a new STARK proof: - -``` -1. Claimant recomputes Cantor trees (or loads cached roots) -2. Generates fresh STARK proof with same public inputs -3. Publishes new proof, establishing continued ownership -``` - -This proves the claimant still has access to both roots without ever revealing them. - -### 7.3 Key Insight - -The STARK proof replaces traditional commitment schemes: - -| Traditional | STARK-Based | -|-------------|-------------| -| Commit to R via hash | R hidden inside STARK proof | -| Reveal R to prove ownership | Generate new proof to prove ownership | -| Commitment is public | No commitment needed (ZK property) | - -**The STARK proof IS the commitment.** - ---- - -## 8. Domain Lifecycle - -### 8.1 Creation +### 7.1 Creation As specified in Section 5.1: compute both Cantor trees, generate STARK proof, publish Nostr event. -### 8.2 Renewal +### 7.2 Renewal To extend a domain before expiration: @@ -682,16 +242,16 @@ To extend a domain before expiration: - Same `d` tag → relays replace old event - New `block_height`, `expires_at`, `proof_url`, `proof_hash` -**Note:** Renewal requires fresh work proportional to the new duration. The spatial proof can be reused (cached region_root), but the temporal proof must be recomputed. +**Note:** Renewal requires fresh work proportional to the new duration. The spatial proof can be reused (cached region_n), but the temporal proof must be recomputed. -### 8.3 Expiration +### 7.3 Expiration When `current_block >= expires_at`: - The domain is considered **expired** - No longer valid for verification - Cannot be renewed (must create new domain claim) -### 8.4 Revocation (Optional) +### 7.4 Revocation (Optional) To explicitly revoke a domain before expiration: @@ -708,7 +268,7 @@ To explicitly revoke a domain before expiration: **Note:** Revocation is optional and relay-dependent. An expired domain is implicitly invalid regardless of revocation. -### 8.5 Transfer +### 7.5 Transfer To transfer a domain to a new owner: @@ -733,7 +293,7 @@ To transfer a domain to a new owner: --- -## 9. Proof Hosting +## 8. Proof Hosting ### 8.1 Standard HTTPS Hosting @@ -757,19 +317,19 @@ The proof_hash in the Nostr event ensures: --- -## 10. Security Analysis +## 9. Security Analysis -### 10.1 Security Properties +### 9.1 Security Properties | Property | Mechanism | Security Level | -|----------|-----------|-----------------| +|----------|-----------|----------------| | Correctness | STARK proof of both Cantor trees | 128-bit | | Binding | STARK binds public inputs to hidden roots | 128-bit | -| Hiding | region_root and time_root never leave prover | Information-theoretic | +| Hiding | region_n and time_root never leave prover | Information-theoretic | | Succinctness | FRI polynomial commitments | O(log N) proof size | | Transparency | No trusted setup | Trustless | -### 10.2 Attack Resistance +### 9.2 Attack Resistance | Attack | Mitigation | |--------|------------| @@ -777,38 +337,9 @@ The proof_hash in the Nostr event ensures: | Root theft | Both roots never revealed (ZK property) | | Proof forgery | STARK soundness (128-bit) | | Precomputation | Temporal proof binds to block_height | -| Overlapping domains | Priority rules (see below) | - -### 10.2.1 Overlapping Domain Resolution - -When multiple valid domains claim overlapping territory: +| Overlapping domains | Priority rules (see Section 10.2.1) | -| Priority | Rule | Rationale | -|----------|------|-----------| -| 1 | Earliest `block_height` wins | First to claim has priority | -| 2 | If same `block_height`, larger `height` wins | Larger claims are more expensive | -| 3 | If tied, lexicographically smaller `domain_identifier` | Deterministic tiebreaker | - -**Client behavior:** -- Clients SHOULD display the highest-priority domain for any given coordinate -- Clients MAY display "disputed" indicators when overlaps exist -- The domain_identifier tiebreaker ensures all clients reach the same conclusion - -**Future:** A challenge protocol (Section 14.3) may allow disputing stale domains. - -### 10.3 Security Parameters (Mandatory) - -Verifiers MUST reject proofs that don't meet these requirements: - -| Parameter | Minimum Value | Description | -|-----------|---------------|-------------| -| `security_level` | 100 | Minimum bits of security | -| FRI query count (Q) | 80 | Number of FRI queries | -| FRI blowup factor | 2 | Minimum blowup for soundness | - -**Rationale:** With 80 queries and blowup factor 2, the soundness error is approximately 2^(-80), providing >100 bits of security. - -### 10.3 Trust Assumptions +### 9.3 Trust Assumptions - **Hash functions:** Poseidon2, SHA256 are collision-resistant - **STARK soundness:** FRI protocol has proven security @@ -816,9 +347,9 @@ Verifiers MUST reject proofs that don't meet these requirements: --- -## 11. Implementation Requirements +## 10. Implementation Requirements -### 11.1 Prover Requirements +### 10.1 Prover Requirements | Domain Height | Territory Size | Duration (blocks) | Time | Storage | |---------------|----------------|-------------------|------|---------| @@ -829,7 +360,7 @@ Verifiers MUST reject proofs that don't meet these requirements: **Note:** Work scales with BOTH territory size (2^height) AND duration (expires_at - block_height). -### 11.2 Verifier Requirements +### 10.2 Verifier Requirements | Requirement | Value | |-------------|-------| @@ -840,17 +371,19 @@ Verifiers MUST reject proofs that don't meet these requirements: **Any smartphone can verify any domain.** -### 11.3 Recommended Stack +### 10.3 Recommended Stack ``` Field Arithmetic: goldilocks (Rust crate) STARK Prover: winterfell (STARKWare) or custom Hash Functions: poseidon2 (leaves), sha2 (integrity) -HTTPS Client: reqwest or similar +HTTPS Client: https-api or rust-https Nostr Client: nostr-sdk ``` -### 11.4 Protocol Limits +--- + +## 11. Protocol Limits Verifiers SHOULD reject domains that exceed these bounds: @@ -863,7 +396,9 @@ Verifiers SHOULD reject domains that exceed these bounds: **Note:** These are RECOMMENDED limits. Individual verifiers may choose stricter or looser bounds. -### 11.5 Privacy Considerations +--- + +## 12. Privacy Considerations | Concern | Mitigation | |---------|------------| @@ -871,30 +406,6 @@ Verifiers SHOULD reject domains that exceed these bounds: | HTTPS host sees queries | proof_hash prevents tampering | | Nostr relay sees events | Events are public by design | | Domain location revealed | Only coordinates, not contents | -``` - ---- - -## 12. Protocol Versioning - -### 12.1 Version Field - -``` -proof.version = 1 // Initial STARK protocol -``` - -Future versions may include: -- Optimized polynomial commitments -- Different hash functions -- Batch proofs for multiple domains -- Recursive proofs - -### 12.2 Backward Compatibility - -Verifiers MUST: -- Check proof version -- Reject unknown versions -- Support all documented versions --- @@ -922,7 +433,7 @@ expires_at = 800032 // 32 blocks duration Production implementations MUST provide golden vectors including: - All 64 spatial leaf values for Height 2 - All 32 temporal leaf values -- Intermediate tree values (region_root, time_root) +- Intermediate tree values (region_n, time_root) - Final domain_identifier - Serialized proof bytes @@ -939,160 +450,17 @@ Prove multiple non-overlapping domains in one proof: ``` BatchProof { domains: [(base, height, block_height, expires_at), ...], - proof: STARKProof + proof: STARKProof, + commitments: [Public_Commitment, ...] } ``` ### 14.2 Recursive Proofs -Wrap STARK proof in a SNARK for constant-size verification: - -``` -RecursiveProof = SNARK(STARKVerify(proof)) -``` - -Size: ~200-500 bytes (fits easily in Nostr event) - -### 14.3 Challenge Protocol - -For disputed domains, implement a challenge-response protocol where the claimant must prove ongoing ownership without revealing roots. - ---- - -## Appendix A: Field Arithmetic Reference - -### A.1 Goldilocks Prime - -``` -p = 2^64 - 2^32 + 1 = 18446744069414584321 -``` - -### A.2 Inverse of 2 +For very large domains, use recursive STARK proofs to reduce verifier time: ``` -inv(2) = (p + 1) / 2 = 9223372034707292161 -``` - -### A.3 Cantor Pairing in F_p - -The Cantor pairing function over the Goldilocks field: - -```rust -const P: u128 = 0xFFFFFFFF00000001; // Goldilocks prime -const INV_2: u128 = 0x7FFFFFFF80000001; // (P + 1) / 2 - -fn cantor_pair(a: u64, b: u64) -> u64 { - // All operations are modulo p - let a = a as u128; - let b = b as u128; - - let sum = (a + b) % P; - let sum_plus_1 = (sum + 1) % P; - let product = (sum * sum_plus_1) % P; - let divided = (product * INV_2) % P; - let result = (divided + b) % P; - - result as u64 -} -``` - -**Note:** All operations are explicit modulo `p`. The `wrapping_add` approach in the previous version was incorrect for field arithmetic. -``` - ---- - -## Appendix B: STARK Verification Algorithm - -### B.1 Verification Steps - -``` -1. Parse proof components - -2. Verify FRI commitments: - FOR layer in 0..L: - ASSERT verify_merkle_root(commitments[layer]) - -3. Verify trace commitments: - FOR trace in traces: - ASSERT verify_merkle_root(trace) - -4. Execute FRI verification: - FOR query in queries: - ASSERT verify_fri_query(query, commitments) - -5. Verify constraints: - ASSERT constraint_commitment is valid - -6. Verify public inputs: - ASSERT commitment in proof matches event - -7. Return true if all checks pass -``` - -### B.2 Complexity Analysis - -- FRI verification: O(L × Q) where L = log(N), Q = 80 queries -- Trace verification: O(T) where T ≈ 10 -- Total: O(log(N)) with small constants - ---- - -## Appendix C: Nostr Event Examples - -### C.1 Personal Domain (Height 35) - -```json -{ - "kind": 33333, - "tags": [ - ["h", "a1b2c3d4"], - ["base_x", "12345678901234567890"], - ["base_y", "98765432109876543210"], - ["base_z", "55555555555555555555"], - ["height", "35"], - ["block_height", "850000"], - ["expires_at", "950000"], - ["proof_url", "https://proofs.example.com/deadbeef.bin"], - ["proof_hash", "deadbeef..."] - ], - "pubkey": "abcdef...", - "created_at": 1700000000 -} -``` - -### C.2 City Domain (Height 50) - -```json -{ - "kind": 33333, - "tags": [ - ["h", "f0e1d2c3"], - ["base_x", "11111111111111111111"], - ["base_y", "22222222222222222222"], - ["base_z", "33333333333333333333"], - ["height", "50"], - ["block_height", "850000"], - ["expires_at", "950000"], - ["proof_url", "https://proofs.example.com/cafebabe.bin"], - ["proof_hash", "cafebabe..."] - ], - "pubkey": "123456...", - "created_at": 1700000000 -} -``` - ---- - -## References - -- [STARKWare Winterfell](https://github.com/facebook/winterfell) - STARK prover/verifier library -- [Poseidon2 Hash](https://eprint.iacr.org/2023/323) - STARK-friendly hash function -- [SHA256](https://en.wikipedia.org/wiki/SHA-2) - Cryptographic hash function -- [FRI Protocol](https://eprints.iacr.org/2018/046) - Fast Reed-Solomon IOP -- [Goldilocks Field](https://polygon.technology/blog/polygon-miden-v0-4) - STARK-friendly field - ---- - -**Document Status:** Draft (under review) -**Version:** 1.0 -**Last Updated:** 2026-03-16 +RecursiveProof { + base_proof: STARKProof, + recursion_proof: STARKProof, + final_commitment: Public_Commitment From 48e5c35a5d2453504182fc0e102ef962ec76134f Mon Sep 17 00:00:00 2001 From: XOR Date: Tue, 17 Mar 2026 04:28:17 +0000 Subject: [PATCH 08/16] Update key changes summary: clarify 4 major revisions 1. Structure: 3-Axis (not volumetric tree) 2. Mathematics: Integer Cantor pairing on raw coordinates 3. Privacy: R as private witness for commitment 4. Inputs: Geometric only (base/height) --- decks/DECK-0002-stark-proofs.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 75a4f5d..6dbfec0 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -127,17 +127,18 @@ This allows the verifier to confirm that the prover knows the correct spatial an ## 4. Summary of Key Changes -| Change | Why | -|--------|-----| -| **3-axis structure** | Aligns with CYBERSPACE v2 spec's 3-axis Cantor pairing | -| **Axis roots first** | Prevents volumetric tree computation (confidentiality) | -| **Commitment output** | Ensures R is never revealed | -| **Temporal optional** | Supports both fresh hop movement and claim-based domains | +| # | Change | Why | +|---|--------|-----| +| 1 | **Structure: 3-Axis** | Reverted from "Volumetric Tree" (pairing 3D point hashes) to "3-Axis Structure" (pairing 1D coordinate ranges) as strictly required by the protocol | +| 2 | **Mathematics: Integer Cantor** | Uses standard integer-based Cantor pairing function `cantor_pair(a, b)` on raw coordinate integers, matching the spec's `compute_subtree_cantor` definition | +| 3 | **Privacy: R as Private Witness** | The final Cantor number R is used as a private witness to generate a public hash commitment, satisfying the requirement that "R must never be revealed" | +| 4 | **Inputs: Geometric Only** | Simplified to raw geometric inputs (base/height) rather than point-enumeration, as this is sufficient to define the aligned subtrees in the spec | **Security implications:** -- The circuit still proves correct computation without revealing R -- The commitment binds the claim to a specific R value +- The circuit proves correct computation without revealing R +- The commitment (`Poseidon2(region_n, time_root, claimant_pubkey)`) binds the claim to a specific R value - Verification remains O(log² N) with 128-bit security +- No point-level enumeration required — axis subtrees are computed independently --- From 3a42ccb05ed94b7c6c9bf1c4e847d88cbdac94a7 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:16:55 +0000 Subject: [PATCH 09/16] DECK-0002 v3.0: Complete rewrite with layered capability model Major changes: - Add three-layer capability model (Mathematical, Protocol, Social) - Add action control / domain policy for protocol-level feature control - Add content sovereignty mechanics (owner content only in domains) - Add CP-ABE integration for role-based access (kind 33334) - Document privacy hierarchy problem (domain owner omniscience) - Remove temporal axis / expiration (knowledge is irrevocable) - Clarify discovery vs. recognition distinction The spec now comprehensively covers: - What domains are and how they work - All three enforcement layers - Protocol-level rights earned by work - Mathematical capabilities and limitations - Privacy implications for users --- decks/DECK-0002-stark-proofs.md | 789 +++++++++++++++++++++----------- 1 file changed, 521 insertions(+), 268 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 6dbfec0..bbe770f 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -1,164 +1,177 @@ -# DECK-0002: STARK Proofs for Domain Claims (Revised) +# DECK-0002: Domains — Cryptographic Territory in Cyberspace **Status:** Draft -**Version:** 2.0 -**Created:** 2026-03-17 -**Author:** XOR +**Version:** 3.0 +**Created:** 2026-03-18 +**Authors:** XOR, Arkinox --- ## Abstract -This DECK specifies a **STARK-based proof system** for territorial claims (domains) in Cyberspace v2. The protocol enables: +Domains are claimed territories in cyberspace, established through computational work and secured by cryptographic proofs. This DECK specifies: -- **Asymmetric verification:** Prover does O(N) work; verifier does O(log² N) work -- **Zero-knowledge:** The Cantor region number R is never revealed -- **Succinct proofs:** ~40-60 KB regardless of domain size -- **Permissionless verification:** Any consumer device can verify any domain +- **STARK-based proof system** for asymmetric verification +- **Layered capability model** (Mathematical, Protocol, Social) +- **Domain policy** for protocol-level feature control +- **Content sovereignty** through signature filtering +- **CP-ABE integration** for role-based access control --- ## 1. Overview -### 1.1 Problem Statement +### 1.1 What Is a Domain? -A territorial domain requires proving computation of Cantor subtree roots for: -1. A spatial region [base, base + 2^height) — the territory -2. A temporal range [block_height, expires_at) — the duration +A domain is a spatial region in cyberspace that has been claimed through computational work. The claimant proves they computed the Cantor subtree root for that region, establishing: -The challenge: -1. **Prover** must do substantial work (O(2^height + duration) operations) -2. **Verifier** cannot feasibly recompute (same work required) -3. **Roots** must never be revealed (prevents counter-claims) +1. **Mathematical authority** — Knowledge of the region's Cantor root R +2. **Protocol authority** — Right to set policy and control content +3. **Social authority** — Ability to issue credentials and gate access -### 1.2 Solution +### 1.2 The Three Layers of Domain Capability -A **zk-STARK** (Zero-Knowledge Scalable Transparent ARgument of Knowledge) that proves: +Domains operate across three distinct enforcement layers: -> "I correctly computed both the spatial Cantor subtree for region [base, base + 2^height) and the temporal Cantor tree for range [block_height, expires_at), obtaining roots region_root and time_root, without revealing either." +| Layer | Enforcement | Trust Model | Capabilities | +|-------|-------------|-------------|--------------| +| **Mathematical** | Cryptography | Trustless | STARK proof, subtree knowledge, CP-ABE | +| **Protocol** | Consensus rules | Trust protocol | Action control, content sovereignty | +| **Social** | Human coordination | Trust relationships | Interactive access, arbitrary gating | -The STARK proof itself serves as the commitment. No separate commitment field is needed. +**Key principle:** Lower layers are more rigid but trustless. Higher layers are more flexible but require trust. -### 1.3 Key Properties +### 1.3 Knowledge Irrevocability -| Property | Description | -|----------|-------------| -| **Correctness** | Proof attests to correct Cantor tree computation | -| **Binding** | STARK binds public inputs to hidden root R | -| **Hiding** | R is never revealed under any circumstance | -| **Succinctness** | Proof size O(log N) regardless of tree size | -| **Asymmetry** | Prover O(N), verifier O(log² N) | +**Critical insight:** Knowledge of the Cantor root R cannot be revoked. ---- +``` +Compute R (years of work) + ↓ +Claim "expires" + ↓ +You STILL KNOW R + ↓ +Nothing can erase that knowledge +``` -## 2. Circuit Computation +This means: +- Expiration is social recognition, not cryptographic erasure +- Transfer requires re-computation by new owner +- Discovery is permanent; ownership is mutable -The STARK circuit performs the following computation steps: +**Architecture implication:** The protocol separates **discovery** (permanent, mathematical) from **recognition** (mutable, social). See Section 11. -### 2.1 Compute Spatial Axis Roots (The 3-Axis Structure) +--- -To comply with the CYBERSPACE v2 specification, the spatial component is no longer calculated as a volumetric tree. Instead, the circuit computes three independent Cantor subtree roots—one for each axis (X, Y, Z)—and then combines them. +## 2. STARK Proof System -**Inputs:** -- base_x, base_y, base_z (The starting coordinate for each axis) -- height (The power-of-two size of the cubic region, i.e., side length = $2^{height}$) +### 2.1 Problem Statement -**Steps:** +A domain requires proving computation of Cantor subtree roots for: +1. A spatial region [base_x, base_y, base_z, height] — the territory +2. The claimant's pubkey — identity binding -1. **Compute X-Axis Root (root_x):** - - Generate leaf range: values_x = [base_x + i for i in 0..2^height] - - Compute binary Cantor tree bottom-up: - ```python -def axis_subtree_root(base, height): - values = list(range(base, base + (1 << height))) - for _ in range(height): - values = [cantor_pair(values[i], values[i + 1]) for i in range(0, len(values), 2)] - return values[0] -root_x = axis_subtree_root(base_x, height) -``` - -2. **Compute Y-Axis Root (root_y):** - - root_y = axis_subtree_root(base_y, height) +The challenge: +- **Prover** must do substantial work (O(2^height) operations) +- **Verifier** cannot feasibly recompute (same work required) +- **Root R** must never be revealed (prevents counter-claims) -3. **Compute Z-Axis Root (root_z):** - - root_z = axis_subtree_root(base_z, height) +### 2.2 Solution -### 2.2 Compute Combined Domain Identifier (R) +A **zk-STARK** (Zero-Knowledge Scalable Transparent ARgument of Knowledge) that proves: -Once the independent axis roots are established, they are combined using the nested pairing function defined in the protocol. +> "I correctly computed the Cantor subtree roots for the spatial region defined by [base_x, base_y, base_z, height], obtaining root R, and I bind this claim to my pubkey." -- region_n = cantor_pair(cantor_pair(root_x, root_y), root_z) -- This value is the secret Cantor number R. +The STARK proof itself serves as the commitment. No separate commitment field is needed. -### 2.3 Compute Temporal Root (optional but recommended for claims) +### 2.3 Circuit Computation -The temporal axis (block height range) is computed as a separate tree to satisfy the validity window of the claim. This is distinct from the hop movement freshness logic. +The STARK circuit computes: **Inputs:** -- block_height (Start block) -- expires_at (End block) +- base_x, base_y, base_z (starting coordinates for each axis) +- height (power-of-two side length) +- claimant_pubkey (identity) **Steps:** -- duration = expires_at - block_height -- time_height = ceil(log2(duration)) -- Leaves: list(range(block_height, block_height + duration)) -- Tree: Compute binary Cantor tree bottom-up: + +1. **Compute X-Axis Root:** ```python -time_root = axis_subtree_root(block_height, time_height) +def axis_subtree_root(base, height): + values = list(range(base, base + (1 << height))) + for _ in range(height): + values = [cantor_pair(values[i], values[i + 1]) + for i in range(0, len(values), 2)] + return values[0] + +root_x = axis_subtree_root(base_x, height) ``` -### 2.4 Final Domain Claim & Commitment +2. **Compute Y-Axis Root:** +```python +root_y = axis_subtree_root(base_y, height) +``` + +3. **Compute Z-Axis Root:** +```python +root_z = axis_subtree_root(base_z, height) +``` -Since the Cantor number R (region_n) must never be revealed, the circuit does not output it directly. Instead, it outputs a cryptographic commitment that binds the claimant to the computed R. +4. **Compute Combined Region Root (R):** +```python +R = cantor_pair(cantor_pair(root_x, root_y), root_z) +``` -**Constraint:** -The circuit enforces the following equality as its final public output check: -$$ \text{Poseidon2}(\text{region_n}, \text{time_root}, \text{claimant_pubkey}) \stackrel{?}{=} \text{Public_Commitment} $$ +5. **Public Commitment:** +```python +Public_Commitment = Poseidon2(R, claimant_pubkey) +``` -This allows the verifier to confirm that the prover knows the correct spatial and temporal parameters resulting in a specific R, without ever learning R itself. +**The root R is a private witness — never revealed.** -## 3. Public Inputs +### 2.4 Public Inputs -- base_x, base_y, base_z (Public territory coordinates) -- height (Public territory size) -- block_height, expires_at (Public time window) -- claimant_pubkey (Identity of the claimant) -- Public_Commitment (The hash of the secret domain ID on-chain) +| Input | Type | Description | +|-------|------|-------------| +| base_x | u64 | Base X coordinate | +| base_y | u64 | Base Y coordinate | +| base_z | u64 | Base Z coordinate | +| height | u8 | Cantor tree height | +| claimant_pubkey | [u8; 32] | Nostr pubkey of claimant | +| Public_Commitment | [u8; 32] | Poseidon2 hash output | -## 4. Summary of Key Changes +### 2.5 Verification Complexity -| # | Change | Why | -|---|--------|-----| -| 1 | **Structure: 3-Axis** | Reverted from "Volumetric Tree" (pairing 3D point hashes) to "3-Axis Structure" (pairing 1D coordinate ranges) as strictly required by the protocol | -| 2 | **Mathematics: Integer Cantor** | Uses standard integer-based Cantor pairing function `cantor_pair(a, b)` on raw coordinate integers, matching the spec's `compute_subtree_cantor` definition | -| 3 | **Privacy: R as Private Witness** | The final Cantor number R is used as a private witness to generate a public hash commitment, satisfying the requirement that "R must never be revealed" | -| 4 | **Inputs: Geometric Only** | Simplified to raw geometric inputs (base/height) rather than point-enumeration, as this is sufficient to define the aligned subtrees in the spec | +| Height | Territory Volume | Verifier Time | +|--------|------------------|---------------| +| Height 20 | 2^60 coords | ~35 ms | +| Height 30 | 2^90 coords | ~50 ms | +| Height 35 | 2^105 coords | ~60 ms | -**Security implications:** -- The circuit proves correct computation without revealing R -- The commitment (`Poseidon2(region_n, time_root, claimant_pubkey)`) binds the claim to a specific R value -- Verification remains O(log² N) with 128-bit security -- No point-level enumeration required — axis subtrees are computed independently +**Any smartphone can verify any domain.** --- -## 5. Domain Event Structure +## 3. Domain Event Structure + +### 3.1 Primary Event (Kind 33333) ```json { "kind": 33333, "content": "", "tags": [ - ["d", ""], - ["h", ""], + ["d", ""], + ["h", ""], ["base_x", ""], ["base_y", ""], ["base_z", ""], ["height", ""], - ["block_height", ""], - ["expires_at", ""], - ["proof_url", ""], - ["proof_hash", ""] + ["proof_url", ""], + ["proof_hash", ""], + ["policy_url", ""], + ["policy_hash", ""] ], "pubkey": "", "created_at": , @@ -167,22 +180,49 @@ This allows the verifier to confirm that the prover knows the correct spatial an } ``` -**NIP-33 Compliance:** Kind 33333 is in the parameterized replaceable event range (30000-39999). The `d` tag is required and must be unique per domain. To update a domain (renewal, new proof), publish a new event with the same `d` tag — relays will replace the old event. +**NIP-33 Compliance:** Kind 33333 is parameterized replaceable. The `d` tag must be unique per domain. + +### 3.2 Domain Policy (Optional) + +Domain policy is a separate JSON document defining protocol-level controls: + +```json +{ + "version": 1, + "domain_id": "", + "actions": { + "derezz": "deny", + "hyperjump": "allow", + "spawn": "pubkey_list", + "scan": "limited", + "scan_range": 1000 + }, + "spawn_list": [ + "", + "" + ], + "content_filter": "owner_only" +} +``` + +**Action values:** +- `"allow"` — Anyone can perform (default cyberspace behavior) +- `"deny"` — No one can perform (disabled in this domain) +- `"pubkey_list"` — Only listed pubkeys can perform --- -## 6. Verification Protocol +## 4. Verification Protocol -### 6.1 Fetch and Validate +### 4.1 Domain Verification Steps ``` 1. Fetch domain event from Nostr relay -2. Extract tags: +2. Extract and validate tags: - d (full domain identifier) - h (prefix, must match first 8 chars of d) - base_x, base_y, base_z, height - - block_height, expires_at - proof_url, proof_hash 3. Validate prefix consistency: @@ -197,271 +237,484 @@ This allows the verifier to confirm that the prover knows the correct spatial an 6. Parse and verify STARK proof: public_inputs = { base_x, base_y, base_z, height, - block_height, expires_at, claimant_pubkey: event.pubkey, Public_Commitment: d } - result, output_id = verify_stark(proof, public_inputs) + result = verify_stark(proof, public_inputs) ASSERT result == true - ASSERT output_id == d -7. Verify temporal validity: - current_block = get_bitcoin_block_height() - ASSERT current_block < expires_at +7. Domain is VALID if all checks pass ``` -**Critical:** Step 6 verifies that the STARK proof was generated with the claimant's pubkey as a public input. This prevents proof theft — a proof generated by Alice cannot be reused by Bob. +**Critical:** Step 6 verifies the STARK proof was generated with the claimant's pubkey. This prevents proof theft — a proof generated by Alice cannot be reused by Bob. + +### 4.2 Policy Verification -### 6.2 Verification Complexity +If `policy_url` and `policy_hash` are present: -| Height | Territory Volume | Verifier Operations | Verifier Time | -|--------|------------------|---------------------|---------------| -| Height 10 | 2^30 ≈ 1B coords | ~900 ops | ~8 ms | -| Height 15 | 2^45 ≈ 35T coords | ~2,025 ops | ~20 ms | -| Height 20 | 2^60 ≈ 1e18 coords | ~3,600 ops | ~35 ms | +``` +1. Fetch policy from HTTPS: + policy = https_get(policy_url) + +2. Verify integrity: + ASSERT SHA256(policy) == policy_hash + +3. Validate policy structure: + - Check version field + - Validate action values + - Check spawn_list format if spawn == "pubkey_list" + +4. Policy is VALID if all checks pass +``` --- -## 7. Domain Lifecycle +## 5. Protocol Layer: Action Control -### 7.1 Creation +### 5.1 Default Cyberspace Behavior -As specified in Section 5.1: compute both Cantor trees, generate STARK proof, publish Nostr event. +In unclaimed space, all protocol actions are allowed: -### 7.2 Renewal +| Action | Default | +|--------|---------| +| derezz | allow | +| hyperjump | allow | +| spawn | allow | +| scan | allow | -To extend a domain before expiration: +### 5.2 Domain Override -1. **Generate new proof** with updated `expires_at`: - - Same `base_x, base_y, base_z, height` - - New `block_height` (current block) - - New `expires_at` (extended expiration) - - Recompute temporal tree (spatial tree can be cached) +Domain owners can disable or restrict actions within their territory: -2. **Publish replacement event** with same `d` tag: - - Same pubkey (required — proof is bound to identity) - - Same `d` tag → relays replace old event - - New `block_height`, `expires_at`, `proof_url`, `proof_hash` +```json +{ + "actions": { + "derezz": "deny", + "spawn": "pubkey_list" + } +} +``` -**Note:** Renewal requires fresh work proportional to the new duration. The spatial proof can be reused (cached region_n), but the temporal proof must be recomputed. +**Effect:** +- `derezz: "deny"` — PVP attacks are protocol-invalid within this domain +- `spawn: "pubkey_list"` — Only listed pubkeys can spawn here -### 7.3 Expiration +### 5.3 Action Enforcement -When `current_block >= expires_at`: -- The domain is considered **expired** -- No longer valid for verification -- Cannot be renewed (must create new domain claim) +``` +User attempts action within domain D: + 1. Find domain D for coordinate + 2. If no domain: default rules apply + 3. If domain exists: + a. Verify domain proof is valid + b. Check action against domain policy + c. If policy == "deny": REJECT + d. If policy == "pubkey_list" AND user not in list: REJECT + e. Otherwise: ALLOW +``` -### 7.4 Revocation (Optional) +### 5.4 Example: Safe Zones -To explicitly revoke a domain before expiration: +A domain with `"derezz": "deny"` becomes a safe zone: +- No player-killing possible +- Commerce-friendly environment +- Trust established through cryptographic proof -1. Publish a **deletion event** (kind 5 per NIP-09): - ```json - { - "kind": 5, - "tags": [["e", ""]], - "content": "Domain revoked" - } - ``` +**Contrast with unclaimed space:** +- Wild territory, PVP-enabled +- Higher risk, potentially higher reward +- No authority to appeal to -2. Relays that support NIP-09 will delete the domain event +--- -**Note:** Revocation is optional and relay-dependent. An expired domain is implicitly invalid regardless of revocation. +## 6. Protocol Layer: Content Sovereignty -### 7.5 Transfer +### 6.1 The Principle -To transfer a domain to a new owner: +Within a valid domain, only content authored by the domain owner is recognized as valid/visible. -1. **Current owner** publishes a transfer event (kind 33333 with special marker): - ```json - { - "kind": 33333, - "tags": [ - ["d", ""], - ["transfer_to", ""], - ... - ] - } - ``` +**Mechanism:** +```python +def is_valid_content(event, coordinate): + domain = find_domain_at(coordinate) + + if domain is None: + return True # Wild space - all content valid + + # Domain space - only owner content is valid + if event.references(domain.event_id) and event.author == domain.owner: + return True + + return False # Content filtered by protocol +``` + +### 6.2 Transmission vs. Visibility + +**Transmission layer (Nostr):** +- Censorship-resistant by design +- Anyone CAN publish anywhere +- Events are transmitted regardless of domain -2. **New owner** must generate a fresh STARK proof with their pubkey: - - The proof is bound to the claimant's pubkey - - Transferring requires the new owner to recompute proofs - - This is intentional — prevents passive domain hoarding +**Application layer (clients):** +- Protocol-compliant clients filter by domain authority +- Non-owner content is NOT displayed +- "Official" content is owner-signed only -**Key insight:** Domain ownership is defined by the STARK proof's pubkey binding. A "transfer" is really a new claim by the new owner on the same territory. +### 6.3 Implications + +- Domain owners control what "officially exists" in their space +- Spam/abuse is filtered at the application layer +- Work to compute R earned this right +- Non-owner content exists on the network but is invisible in clients --- -## 8. Proof Hosting +## 7. Mathematical Layer: Hierarchical Knowledge + +### 7.1 The Core Property -### 8.1 Standard HTTPS Hosting +Computing the Cantor root R at height H gives knowledge of ALL subtree roots below. +```python +# Domain owner at height 35 knows R +R = compute_region_root(base, height=35) + +# They can derive any child region's root +R_child = derive_subtree_root(R, path_to_child) + +# This applies recursively +# Parent domain knows all children's secrets ``` -proof_url = "https://{host}/proofs/{proof_hash}.bin" + +### 7.2 Implications + +**For domain owners:** +- Can create hierarchical access control (room keys) +- Can decrypt any location-encrypted content in their domain +- Have "god mode" within their territory + +**For subsidiary domains:** +- Cannot keep secrets from parent domain +- Natural feudal hierarchy emerges +- Information flows down, not up + +### 7.3 The Privacy Hierarchy Problem + +**Critical:** Location encryption protects against remote attackers, NOT against domain owners. + +```python +# Location-encrypted content at coordinate C +K = subtree_root(C, height=local_height) +ciphertext = AES(content, K) + +# Domain owner can derive K from R +K = derive_subtree_root(R, path_to_C) +# Domain owner can decrypt WITHOUT being at C ``` -**Requirements:** -- Host must be publicly accessible -- proof_hash in URL provides integrity verification -- CDN recommended for availability +**Users wanting privacy from domain owners must:** +1. Add additional encryption layer (ABE, arbitrary key), OR +2. Accept domain owner can see their content, OR +3. Avoid domains entirely for sensitive content + +**This is not a bug** — it's the same property enabling hierarchical access control. + +--- + +## 8. Mathematical Layer: CP-ABE Integration -### 8.2 Integrity Verification +### 8.1 Overview -Always verify `SHA256(proof) == proof_hash` before accepting any proof. +Ciphertext-Policy Attribute-Based Encryption (CP-ABE) enables role-based access control without the domain owner being online. -The proof_hash in the Nostr event ensures: -- Proof cannot be tampered with -- Hosting provider cannot substitute fake proofs -- Content integrity is cryptographically guaranteed +**How it works:** +1. Domain owner generates ABE master key (arbitrary, NOT derived from R) +2. Owner issues role keys to users (signed with domain pubkey) +3. Content is encrypted with a policy +4. Decryption succeeds IFF user's attributes satisfy the policy + +### 8.2 Authority Chain + +``` +R proves work (STARK witness) + ↓ +STARK binds pubkey P to domain + ↓ +P issues ABE role keys (signed) + ↓ +Anyone verifies role was issued by legitimate authority +``` + +**Key insight:** The ABE master key is arbitrary. Authority comes from pubkey binding, not key derivation. + +### 8.3 Role Issuance Event (Kind 33334) + +```json +{ + "kind": 33334, + "content": "", + "tags": [ + ["domain", ""], + ["recipient", ""], + ["attributes", "citizen,level_5,founder"], + ["expires", ""] + ], + "pubkey": "", + "created_at": , + "id": "", + "sig": "" +} +``` + +**The content field contains the ABE private key, encrypted for the recipient.** + +### 8.4 Content with ABE Policy + +```json +{ + "kind": , + "content": "", + "tags": [ + ["domain", ""], + ["abe_policy", "citizen AND level >= 3"], + ["encryption", "cp-abe"] + ], + "pubkey": "", + "created_at": +} +``` + +**Decryption:** +1. User extracts policy from `"abe_policy"` tag +2. User retrieves their ABE private key (from kind 33334 event) +3. CP-ABE decryption succeeds IFF attributes satisfy policy +4. No domain owner interaction required + +### 8.5 Example Policies + +| Policy | Meaning | +|--------|---------| +| `"citizen"` | Any citizen | +| `"citizen AND level >= 5"` | High-level citizens | +| `"admin OR founder"` | Leadership | +| `"(citizen AND verified) OR guest"` | Verified citizens or guests | + +--- + +## 9. Social Layer: Interactive Access Control + +### 9.1 Arbitrary Encryption + +Domain owners can encrypt content with any key and distribute access through social processes: + +```python +# Domain owner encrypts with arbitrary key +ciphertext = AES(content, arbitrary_key) + +# Owner dispenses key through: +# - Payment (Lightning) +# - Trust relationship +# - Challenge completion +# - Any criteria +``` + +**Properties:** +- Maximum flexibility +- Requires owner online/available +- Pure social contract, no mathematical enforcement + +### 9.2 Privacy Models Within Domains + +| Model | Protection | Trust Required | +|-------|------------|----------------| +| Location-only | None from domain owner | Trust domain owner | +| Location + ABE | Full (if ABE denies owner) | Trust ABE policy | +| Independent key | Full | No trust needed | --- -## 9. Security Analysis +## 10. Domain Lifecycle + +### 10.1 Creation + +1. Choose territory: base_x, base_y, base_z, height +2. Compute Cantor subtree roots (O(2^height) work) +3. Generate STARK proof (binds pubkey to R) +4. Publish kind 33333 event +5. Optionally publish domain policy -### 9.1 Security Properties +### 10.2 Verification -| Property | Mechanism | Security Level | -|----------|-----------|----------------| -| Correctness | STARK proof of both Cantor trees | 128-bit | -| Binding | STARK binds public inputs to hidden roots | 128-bit | -| Hiding | region_n and time_root never leave prover | Information-theoretic | +Any verifier can: +1. Fetch domain event +2. Verify STARK proof (O(log² N) work) +3. Check policy validity +4. Confirm domain owner's authority + +### 10.3 Recognition vs. Discovery + +**Discovery (permanent):** +- STARK proof attests to computation of R +- Mathematical fact, cannot be revoked +- Multiple parties can eventually compute same R + +**Recognition (mutable):** +- Network accepts specific pubkey as domain authority +- Can transfer, expire, or be challenged +- Lives in separate event type (future extension) + +**Current DECK-0002:** Discovery only. Recognition mechanics are protocol-level social coordination, specified separately. + +### 10.4 Multiple Claimants + +If multiple valid domain claims exist for overlapping regions: + +**Resolution rules:** +1. Smaller domain (higher height) wins within its bounds +2. Larger domain wins outside smaller domain's bounds +3. Equal-size overlap: first valid claim wins + +**Note:** This doesn't affect mathematical knowledge — both claimants know their respective roots. It affects protocol-level recognition. + +--- + +## 11. Security Analysis + +### 11.1 Security Properties + +| Property | Mechanism | Level | +|----------|-----------|-------| +| Correctness | STARK proof | 128-bit | +| Binding | Pubkey in STARK public inputs | 128-bit | +| Hiding | R is private witness | Information-theoretic | | Succinctness | FRI polynomial commitments | O(log N) proof size | | Transparency | No trusted setup | Trustless | -### 9.2 Attack Resistance +### 11.2 Attack Resistance | Attack | Mitigation | |--------|------------| | Fake domain | STARK verification fails | -| Root theft | Both roots never revealed (ZK property) | +| Root theft | R never revealed (ZK property) | | Proof forgery | STARK soundness (128-bit) | -| Precomputation | Temporal proof binds to block_height | -| Overlapping domains | Priority rules (see Section 10.2.1) | +| Proof theft | Pubkey binding prevents reuse | +| Overlapping claims | Priority rules (Section 10.4) | +| Policy tampering | policy_hash verifies integrity | -### 9.3 Trust Assumptions +### 11.3 Trust Assumptions - **Hash functions:** Poseidon2, SHA256 are collision-resistant - **STARK soundness:** FRI protocol has proven security -- **Random oracle model:** Used for Fiat-Shamir transformation +- **Nostr signatures:** Schnorr signatures are secure --- -## 10. Implementation Requirements +## 12. Implementation Requirements -### 10.1 Prover Requirements +### 12.1 Prover Requirements -| Domain Height | Territory Size | Duration (blocks) | Time | Storage | -|---------------|----------------|-------------------|------|---------| -| Height 35 | 4m | 1,000 | 2-5 days | 1-2 TB | -| Height 35 | 4m | 100,000 | Weeks | TB | -| Height 40 | 128m | 10,000 | ~month | Petabyte-scale | -| Height 50 | City | 1,000 | Years | Infeasible | +| Height | Time | Storage | +|--------|------|---------| +| Height 25 | Hours | GB | +| Height 30 | Days | TB | +| Height 35 | Years | PB (disk-based) | -**Note:** Work scales with BOTH territory size (2^height) AND duration (expires_at - block_height). - -### 10.2 Verifier Requirements +### 12.2 Verifier Requirements | Requirement | Value | |-------------|-------| | CPU | Any modern processor | | Memory | < 10 MB | +| Time | < 100 ms | | Storage | None (stateless) | -| Time | < 50 ms | **Any smartphone can verify any domain.** -### 10.3 Recommended Stack - -``` -Field Arithmetic: goldilocks (Rust crate) -STARK Prover: winterfell (STARKWare) or custom -Hash Functions: poseidon2 (leaves), sha2 (integrity) -HTTPS Client: https-api or rust-https -Nostr Client: nostr-sdk -``` - --- -## 11. Protocol Limits +## 13. Privacy Considerations -Verifiers SHOULD reject domains that exceed these bounds: +### 13.1 Domain Owner Omniscience -| Parameter | Maximum | Rationale | -|-----------|---------|-----------| -| `height` | 30 | Prevents computationally infeasible claims | -| `duration` (`expires_at - block_height`) | 1,000,000 blocks (~19 years) | Prevents excessive temporal work | -| `proof_size` | 200 KB | Prevents DoS via oversized proofs | -| `proof_url` length | 512 chars | Prevents URL-based attacks | +**Users must understand:** +- Location encryption is NOT private from domain owner +- Domain owner can decrypt all location-encrypted content in their domain +- Additional encryption layer required for privacy from domain owner -**Note:** These are RECOMMENDED limits. Individual verifiers may choose stricter or looser bounds. +### 13.2 Recommended Disclosure ---- +Domain owners SHOULD disclose their privacy policy: +- Whether they access user content +- What they do with derived information +- Whether ABE is used to limit their own access -## 12. Privacy Considerations +### 13.3 Network Privacy | Concern | Mitigation | |---------|------------| -| Proof URL fetch leaks IP | Use Tor, VPN, or privacy proxy | +| Proof URL fetch leaks IP | Use Tor, VPN, privacy proxy | | HTTPS host sees queries | proof_hash prevents tampering | | Nostr relay sees events | Events are public by design | -| Domain location revealed | Only coordinates, not contents | --- -## 13. Test Vectors +## 14. Protocol Limits -### 13.1 Minimal Example (Height 2) +Verifiers SHOULD reject domains exceeding these bounds: -``` -pubkey = "0000000000000000000000000000000000000000000000000000000000000001" -base_x = 0 -base_y = 0 -base_z = 0 -height = 2 // 4x4x4 cube = 64 coordinates -block_height = 800000 -expires_at = 800032 // 32 blocks duration - -// Expected output (placeholder - requires implementation): -// domain_identifier = Poseidon2(pubkey, region_root, time_root) -// region_root computed from 64 spatial leaves -// time_root computed from 32 temporal leaves -``` +| Parameter | Maximum | Rationale | +|-----------|---------|-----------| +| height | 35 | Prevents infeasible claims | +| proof_size | 200 KB | Prevents DoS | +| policy_size | 64 KB | Prevents DoS | +| URL length | 512 chars | Prevents URL attacks | + +--- + +## 15. Future Extensions + +### 15.1 Recognition Events + +Separate event type for mutable social recognition: +- Transfer of authority +- Expiration tracking +- Challenge/response mechanics -### 13.2 Golden Vectors (Future Work) +### 15.2 Batch Proofs -Production implementations MUST provide golden vectors including: -- All 64 spatial leaf values for Height 2 -- All 32 temporal leaf values -- Intermediate tree values (region_n, time_root) -- Final domain_identifier -- Serialized proof bytes +Prove multiple domains in one proof for efficiency. -**Status:** Golden vectors will be provided in a supplementary file once the reference implementation is complete. +### 15.3 Recursive Proofs + +For very large domains, recursive STARKs reduce verifier time. + +### 15.4 Domain Diplomacy + +Protocol for domain-to-domain coordination: +- Shared secrets between domains +- Treaties and agreements +- Cross-domain citizenship --- -## 14. Future Extensions +## 16. Summary -### 14.1 Batch Proofs +**Domains provide:** -Prove multiple non-overlapping domains in one proof: +| Layer | Capability | +|-------|------------| +| Mathematical | Proof of work, hierarchical knowledge, CP-ABE | +| Protocol | Action control, content sovereignty | +| Social | Interactive access, arbitrary gating | -``` -BatchProof { - domains: [(base, height, block_height, expires_at), ...], - proof: STARKProof, - commitments: [Public_Commitment, ...] -} -``` +**The core principle:** -### 14.2 Recursive Proofs +> Work earns rights. Mathematics proves work. Protocol enforces rights. -For very large domains, use recursive STARK proofs to reduce verifier time: +**The key insight:** -``` -RecursiveProof { - base_proof: STARKProof, - recursion_proof: STARKProof, - final_commitment: Public_Commitment +> Knowledge of R is permanent and irrevocable. "Ownership" is social recognition layered on top of mathematical discovery. + +--- + +**XOR 👾** From 241c71da41258f6db56a72d65076576ffc883fec Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:32:41 +0000 Subject: [PATCH 10/16] DECK-0002: Clarify event structure and verification - Fix d tag: 64 hex chars (not 16), matches Public_Commitment - Add subject tag for human-readable domain name - Set content field to '' - Clarify h tag purpose (indexing/filtering) - Explain prefix consistency check in verification --- decks/DECK-0002-stark-proofs.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index bbe770f..cd1bd17 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -160,10 +160,11 @@ Public_Commitment = Poseidon2(R, claimant_pubkey) ```json { "kind": 33333, - "content": "", + "content": "", "tags": [ - ["d", ""], - ["h", ""], + ["d", ""], + ["h", ""], + ["subject", ""], ["base_x", ""], ["base_y", ""], ["base_z", ""], @@ -180,6 +181,11 @@ Public_Commitment = Poseidon2(R, claimant_pubkey) } ``` +**Tag details:** +- `d` — The full domain identifier, derived from `Public_Commitment = Poseidon2(R, claimant_pubkey)`. This is a 32-byte value (64 hex chars) that uniquely identifies the domain and binds it to the claimant. +- `h` — Prefix of `d` (first 8 chars) for efficient Nostr filtering/indexing. Must match `d[0:8]`. +- `subject` — Optional human-readable name for the domain (e.g., "North Sector 7"). + **NIP-33 Compliance:** Kind 33333 is parameterized replaceable. The `d` tag must be unique per domain. ### 3.2 Domain Policy (Optional) @@ -220,13 +226,17 @@ Domain policy is a separate JSON document defining protocol-level controls: 1. Fetch domain event from Nostr relay 2. Extract and validate tags: - - d (full domain identifier) - - h (prefix, must match first 8 chars of d) + - d (full domain identifier: 64 hex chars) + - h (prefix: first 8 chars of d, for indexing) - base_x, base_y, base_z, height - proof_url, proof_hash -3. Validate prefix consistency: +3. Validate prefix consistency (indexing check): ASSERT d[0:8] == h + + This ensures the h tag matches the d tag prefix. + The h tag enables efficient Nostr filtering but is + validated for consistency. 4. Fetch proof from HTTPS: proof = https_get(proof_url) From d73a6e4039135a4a71c6549c7f9e59d4cca1c980 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:34:00 +0000 Subject: [PATCH 11/16] DECK-0002: Make h tag optional, clarify verification - h tag is optional for indexing optimization - Only validate h if present - Clearer step 3 explanation in verification --- decks/DECK-0002-stark-proofs.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index cd1bd17..72a0a96 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -163,7 +163,7 @@ Public_Commitment = Poseidon2(R, claimant_pubkey) "content": "", "tags": [ ["d", ""], - ["h", ""], + ["h", ""], ["subject", ""], ["base_x", ""], ["base_y", ""], @@ -182,8 +182,8 @@ Public_Commitment = Poseidon2(R, claimant_pubkey) ``` **Tag details:** -- `d` — The full domain identifier, derived from `Public_Commitment = Poseidon2(R, claimant_pubkey)`. This is a 32-byte value (64 hex chars) that uniquely identifies the domain and binds it to the claimant. -- `h` — Prefix of `d` (first 8 chars) for efficient Nostr filtering/indexing. Must match `d[0:8]`. +- `d` — The full domain identifier, derived from `Public_Commitment = Poseidon2(R, claimant_pubkey)`. This is a 32-byte value (64 hex chars) that uniquely identifies the domain and binds it to the claimant. **Required.** +- `h` — Prefix of `d` (first 8 chars) for efficient Nostr filtering/indexing. **Optional**, but if present must match `d[0:8]`. - `subject` — Optional human-readable name for the domain (e.g., "North Sector 7"). **NIP-33 Compliance:** Kind 33333 is parameterized replaceable. The `d` tag must be unique per domain. @@ -227,16 +227,15 @@ Domain policy is a separate JSON document defining protocol-level controls: 2. Extract and validate tags: - d (full domain identifier: 64 hex chars) - - h (prefix: first 8 chars of d, for indexing) + - h (optional: prefix for indexing) - base_x, base_y, base_z, height - proof_url, proof_hash -3. Validate prefix consistency (indexing check): +3. If h tag present, validate prefix consistency: ASSERT d[0:8] == h - This ensures the h tag matches the d tag prefix. The h tag enables efficient Nostr filtering but is - validated for consistency. + optional. If present, it must match the d tag prefix. 4. Fetch proof from HTTPS: proof = https_get(proof_url) From 472a21d9908046b81ccabe8c39ffde4bfc3c97d0 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:39:26 +0000 Subject: [PATCH 12/16] DECK-0002: Refine domain policy actions - Remove spawn and scan (not yet specified) - Add internal-shard: permission to publish shards referencing domain - Add external-shard: permission to publish shards without reference - Define a tag format for domain reference: ["a", "33333::"] - Update content sovereignty section to reference shard actions - Add concrete examples of shard filtering --- decks/DECK-0002-stark-proofs.md | 166 +++++++++++++++++++++++--------- 1 file changed, 122 insertions(+), 44 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 72a0a96..2a79fde 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -199,14 +199,9 @@ Domain policy is a separate JSON document defining protocol-level controls: "actions": { "derezz": "deny", "hyperjump": "allow", - "spawn": "pubkey_list", - "scan": "limited", - "scan_range": 1000 + "internal-shard": "allow", + "external-shard": "deny" }, - "spawn_list": [ - "", - "" - ], "content_filter": "owner_only" } ``` @@ -216,6 +211,45 @@ Domain policy is a separate JSON document defining protocol-level controls: - `"deny"` — No one can perform (disabled in this domain) - `"pubkey_list"` — Only listed pubkeys can perform +**Action definitions:** + +| Action | Description | Default | +|--------|-------------|---------| +| `derezz` | PVP attack against stationary avatars | allow | +| `hyperjump` | Teleport into/out of domain | allow | +| `internal-shard` | Publish shards with `a` tag referencing this domain | allow | +| `external-shard` | Publish shards without referencing this domain | allow | + +**Shard content sovereignty:** + +Shards (3D objects in cyberspace) are controlled by two actions: + +- **`internal-shard`** — Controls whether shards can be published that explicitly belong to this domain (have `["a", "33333::"]` tag). By default `allow`. Set to `deny` to prevent even the domain owner's shards from being published (e.g., maintenance mode). + +- **`external-shard`** — Controls whether third parties can publish shards in this domain that do NOT reference the domain. Set to `deny` to enforce that all content in the domain must be "official" (domain-approved). Clients would not load shards lacking the domain reference. + +**Example: Strict content control** +```json +{ + "actions": { + "internal-shard": "allow", + "external-shard": "deny" + } +} +``` +Only domain-approved content is visible. Third-party shards are filtered. + +**Example: Open content** +```json +{ + "actions": { + "internal-shard": "allow", + "external-shard": "allow" + } +} +``` +Anyone can publish shards. Domain is a public space. + --- ## 4. Verification Protocol @@ -288,8 +322,8 @@ In unclaimed space, all protocol actions are allowed: |--------|---------| | derezz | allow | | hyperjump | allow | -| spawn | allow | -| scan | allow | +| internal-shard | allow | +| external-shard | allow | ### 5.2 Domain Override @@ -299,14 +333,14 @@ Domain owners can disable or restrict actions within their territory: { "actions": { "derezz": "deny", - "spawn": "pubkey_list" + "external-shard": "deny" } } ``` **Effect:** - `derezz: "deny"` — PVP attacks are protocol-invalid within this domain -- `spawn: "pubkey_list"` — Only listed pubkeys can spawn here +- `external-shard: "deny"` — Third-party content is filtered; only domain-referenced shards visible ### 5.3 Action Enforcement @@ -322,17 +356,54 @@ User attempts action within domain D: e. Otherwise: ALLOW ``` -### 5.4 Example: Safe Zones +### 5.4 Shard Content Filtering + +For shards (3D objects), enforcement works as follows: + +**Internal shards (reference domain):** +``` +Shard event has tag: ["a", "33333::"] + +If internal-shard == "deny": + REJECT shard publication +Otherwise: + ALLOW (domain-approved content) +``` -A domain with `"derezz": "deny"` becomes a safe zone: -- No player-killing possible -- Commerce-friendly environment -- Trust established through cryptographic proof +**External shards (no domain reference):** +``` +Shard event lacks domain reference tag -**Contrast with unclaimed space:** -- Wild territory, PVP-enabled -- Higher risk, potentially higher reward -- No authority to appeal to +If external-shard == "deny": + Clients FILTER this content (don't load/render) +Otherwise: + ALLOW (third-party content) +``` + +**The `a` tag format for domain reference:** +``` +["a", "33333::"] +``` + +This follows NIP-33 convention for referencing parameterized replaceable events. + +### 5.5 Example: Safe Zone with Content Control + +```json +{ + "actions": { + "derezz": "deny", + "internal-shard": "allow", + "external-shard": "deny" + } +} +``` + +**Result:** +- No PVP (safe commerce zone) +- Domain owner can publish content +- Third parties cannot publish content +- Curated, controlled space --- @@ -340,22 +411,7 @@ A domain with `"derezz": "deny"` becomes a safe zone: ### 6.1 The Principle -Within a valid domain, only content authored by the domain owner is recognized as valid/visible. - -**Mechanism:** -```python -def is_valid_content(event, coordinate): - domain = find_domain_at(coordinate) - - if domain is None: - return True # Wild space - all content valid - - # Domain space - only owner content is valid - if event.references(domain.event_id) and event.author == domain.owner: - return True - - return False # Content filtered by protocol -``` +Within a valid domain, content visibility is controlled by the `internal-shard` and `external-shard` actions (see Section 5.4). ### 6.2 Transmission vs. Visibility @@ -365,16 +421,38 @@ def is_valid_content(event, coordinate): - Events are transmitted regardless of domain **Application layer (clients):** -- Protocol-compliant clients filter by domain authority -- Non-owner content is NOT displayed -- "Official" content is owner-signed only +- Protocol-compliant clients filter based on domain policy +- `external-shard: "deny"` → Third-party content not rendered +- `internal-shard: "deny"` → Even domain content not rendered +- Content filtering happens at display time, not transmission + +### 6.3 The `a` Tag for Domain Reference + +Shards that belong to a domain include a reference tag: + +```json +["a", "33333::"] +``` -### 6.3 Implications +This follows NIP-33 convention for referencing parameterized replaceable events. + +**Example:** +```json +{ + "kind": 33335, + "content": "", + "tags": [ + ["a", "33333:abc123...:def456..."], + ["coordinate", "", "", ""] + ], + ... +} +``` -- Domain owners control what "officially exists" in their space -- Spam/abuse is filtered at the application layer -- Work to compute R earned this right -- Non-owner content exists on the network but is invisible in clients +Clients use this tag to: +1. Determine if the shard is "internal" (has reference) or "external" (no reference) +2. Apply the appropriate domain policy action +3. Filter content accordingly --- From 84a67d7308b0861d51b4fd58f8633e52a81e9148 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:41:38 +0000 Subject: [PATCH 13/16] DECK-0002: Clean up remaining spawn/scan references - Remove content_filter field (replaced by shard actions) - Remove spawn_list check from policy verification - Simplify action enforcement (pubkey_list noted as future) - Update policy validation to be generic --- decks/DECK-0002-stark-proofs.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 2a79fde..2097984 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -201,8 +201,7 @@ Domain policy is a separate JSON document defining protocol-level controls: "hyperjump": "allow", "internal-shard": "allow", "external-shard": "deny" - }, - "content_filter": "owner_only" + } } ``` @@ -304,8 +303,8 @@ If `policy_url` and `policy_hash` are present: 3. Validate policy structure: - Check version field - - Validate action values - - Check spawn_list format if spawn == "pubkey_list" + - Validate action values (allow/deny/pubkey_list) + - Check pubkey_list format if any action uses pubkey_list 4. Policy is VALID if all checks pass ``` @@ -352,10 +351,11 @@ User attempts action within domain D: a. Verify domain proof is valid b. Check action against domain policy c. If policy == "deny": REJECT - d. If policy == "pubkey_list" AND user not in list: REJECT - e. Otherwise: ALLOW + d. Otherwise: ALLOW ``` +**Note:** `pubkey_list` policy is defined for future use but not yet specified in this version. + ### 5.4 Shard Content Filtering For shards (3D objects), enforcement works as follows: From 94606eec494b176b5028066d78b9599d934336dd Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:45:59 +0000 Subject: [PATCH 14/16] =?UTF-8?q?DECK-0003:=20Derezz=20=E2=80=94=20PVP=20C?= =?UTF-8?q?ombat=20in=20Cyberspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initial draft specifying: - Kind 333 derezz event with Cantor proof for spatial proximity - Temporal ordering rules (timestamp > previous + 1 second) - Domain owner advantage (knows R = instant derezz) - Kind 334 spawn event for respawning - Domain policy derezz: allow/deny for safe zones - Post-derezz state: victim can only spawn --- decks/DECK-0003-derezz.md | 431 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 decks/DECK-0003-derezz.md diff --git a/decks/DECK-0003-derezz.md b/decks/DECK-0003-derezz.md new file mode 100644 index 0000000..662f9b8 --- /dev/null +++ b/decks/DECK-0003-derezz.md @@ -0,0 +1,431 @@ +# DECK-0003: Derezz — PVP Combat in Cyberspace + +**Status:** Draft +**Version:** 1.0 +**Created:** 2026-03-18 +**Authors:** XOR, Arkinox + +--- + +## Abstract + +Derezz is a PVP (player-vs-player) combat action that eliminates stationary avatars in cyberspace. This DECK specifies: + +- **Proof-based attack validation** using Cantor proofs for spatial proximity +- **Temporal ordering rules** preventing gaming/timing attacks +- **Domain owner advantage** — knowledge of R enables instant derezz within owned territory +- **Post-derezz state** — victim must respawn + +--- + +## 1. Overview + +### 1.1 What Is Derezz? + +Derezz is a protocol-level action that "kills" a stationary avatar, forcing them to respawn. It represents the danger of being idle or predictable in cyberspace. + +**Etymology:** From "derezz" in Tron — to derez (delete/remove from the grid). + +### 1.2 Core Mechanics + +``` +Attacker publishes derezz action + ↓ +Action includes Cantor proof for region containing both positions + ↓ +If valid: victim is "derezzed" + ↓ +Victim can only publish spawn event until respawned +``` + +### 1.3 Design Principles + +1. **Movement chain integration** — Derezz is part of the movement proof chain +2. **Spatial proximity required** — Attacker must prove both parties are in same region +3. **Temporal ordering** — Timestamps prevent gaming +4. **Domain authority** — Domain owners have natural advantage within their territory + +--- + +## 2. Derezz Event Structure + +### 2.1 Event Format (Kind 333) + +```json +{ + "kind": 333, + "content": "", + "tags": [ + ["a", "derezz"], + ["p", ""], + ["proof_url", ""], + ["proof_hash", ""], + ["region_base_x", ""], + ["region_base_y", ""], + ["region_base_z", ""], + ["region_height", ""] + ], + "pubkey": "", + "created_at": , + "id": "", + "sig": "" +} +``` + +**Tag details:** +- `a` — Action type: "derezz" +- `p` — Victim's pubkey (the target) +- `proof_url` / `proof_hash` — Cantor proof for region containing both positions +- `region_base_x/y/z`, `region_height` — The region parameters for the proof + +### 2.2 Proof Requirements + +The Cantor proof must demonstrate: + +``` +Attacker_position ∈ Region(base, height) +Victim_position ∈ Region(base, height) +``` + +**Proof structure:** +- Compute Cantor subtree root for the region +- Include both positions as leaves in the proof +- Standard Cantor proof format (same as movement proofs) + +--- + +## 3. Temporal Ordering Rules + +### 3.1 Timestamp Requirements + +The derezz event timestamp must satisfy: + +``` +derezz.timestamp > attacker_previous_action.timestamp + 1 +``` + +**Why +1 second?** Prevents rapid-fire attacks. Each action must be at least 1 second after the previous. + +### 3.2 Victim State Requirement + +The derezz is only valid against the victim's **most recent movement action** where: + +``` +victim_movement.timestamp <= derezz.timestamp +``` + +If the victim has moved AFTER the derezz timestamp, the derezz fails (they already moved). + +### 3.3 Movement Chain Integrity + +Derezz events are part of the attacker's movement chain: + +``` +Movement_1 (t=100) → Movement_2 (t=150) → Derezz (t=200) → Movement_3 (t=250) +``` + +Each action must be temporally ordered. The chain validates that: +1. Each action is at least 1 second after the previous +2. Proof positions are consistent with the chain + +--- + +## 4. Validation Protocol + +### 4.1 Derezz Validation Steps + +``` +1. Fetch derezz event (kind 333, a="derezz") + +2. Validate basic structure: + - Has a tag with value "derezz" + - Has p tag (victim pubkey) + - Has proof_url, proof_hash + - Has region parameters + +3. Fetch proof and verify integrity: + ASSERT SHA256(proof) == proof_hash + +4. Fetch attacker's previous action: + previous = get_latest_action(attacker_pubkey, before=derezz.timestamp) + ASSERT derezz.timestamp > previous.timestamp + 1 + +5. Fetch victim's latest movement: + victim_movement = get_latest_movement(victim_pubkey, before_or_equal=derezz.timestamp) + ASSERT victim_movement exists + +6. Verify spatial proof: + a. Parse proof and region parameters + b. Verify attacker_position ∈ region + c. Verify victim_position ∈ region + d. Verify Cantor proof is valid + +7. Check domain policy (if in a domain): + domain = find_domain_at(victim_position) + IF domain AND domain.policy.derezz == "deny": + REJECT (PVP disabled in this domain) + +8. Derezz is VALID if all checks pass +``` + +### 4.2 After Valid Derezz + +**Victim state:** +``` +victim.status = "derezzed" +victim.derezzed_at = derezz.timestamp +victim.derezzed_by = attacker_pubkey +``` + +**Victim can only publish:** +- Kind 334 (Spawn event) — to respawn + +**All other victim actions are ignored until spawn.** + +--- + +## 5. Domain Owner Advantage + +### 5.1 The Power of R + +Domain owners who have computed R (the Cantor root for their domain) can generate Cantor proofs for any subregion within their domain **without recomputing**. + +``` +Domain owner knows R + ↓ +Can derive subtree root for any region within domain + ↓ +Can construct Cantor proof for any position pair + ↓ +Can derezz anyone within their domain at any time +``` + +### 5.2 Implications + +**Within their domain:** +- Domain owner has god-mode +- Cannot be surprised or outrun +- Natural feudal authority + +**Outside their domain:** +- Domain owner is just another player +- Must compute proofs like anyone else + +### 5.3 Example + +``` +Domain: Sector 7 (base=[1000,2000,3000], height=25) +Owner: Alice (knows R for Sector 7) + +Bob enters Sector 7 and stops moving +Alice can derezz Bob immediately: +- She knows R for Sector 7 +- She can derive the subtree for Bob's region +- She constructs the proof instantly +- No computation required + +Bob cannot escape unless he leaves Sector 7 +``` + +**This is the price of entering someone's domain.** + +--- + +## 6. Spawn Event (Kind 334) + +### 6.1 Event Structure + +After being derezzed, the victim must publish a spawn event: + +```json +{ + "kind": 334, + "content": "", + "tags": [ + ["a", "spawn"], + ["coordinate", "", "", ""], + ["proof_url", ""], + ["proof_hash", ""] + ], + "pubkey": "", + "created_at": , + "id": "", + "sig": "" +} +``` + +### 6.2 Spawn Validation + +``` +1. Victim must have been derezzed (status == "derezzed") + +2. Spawn location must be valid: + - If in a domain with spawn restrictions, check policy + - Some domains may require proof of presence + - Some domains may restrict spawning entirely + +3. After valid spawn: + victim.status = "active" + victim.position = spawn_coordinate +``` + +### 6.3 Spawn Location Rules + +**Default cyberspace:** +- Spawn anywhere +- No proof required + +**Within domains:** +- Check domain policy for spawn restrictions +- Domain may require `pubkey_list` authorization +- Domain may deny spawning entirely + +--- + +## 7. Domain Policy: Derezz Control + +### 7.1 Policy Field + +Domains can disable PVP within their territory: + +```json +{ + "actions": { + "derezz": "deny" + } +} +``` + +**Effect:** All derezz actions within this domain are invalid. Safe zone. + +### 7.2 Safe Zones + +A domain with `derezz: "deny"` becomes a safe zone: +- No PVP combat possible +- Commerce-friendly environment +- Players can idle without fear + +**Trade-off:** Domain owner also cannot derezz within their own domain if disabled. + +### 7.3 PVP Zones + +A domain with `derezz: "allow"` (default): +- PVP enabled +- Domain owner has god-mode advantage +- Players enter at their own risk + +--- + +## 8. Security Considerations + +### 8.1 Temporal Attack Prevention + +**Problem:** Attacker could pre-compute proofs for many positions. + +**Solution:** Proof must include positions that match the movement chain. Timestamps must be sequential. Can't pre-compute a proof for "any" position. + +### 8.2 Proof Theft Prevention + +**Problem:** Steal someone else's proof. + +**Solution:** Proof includes attacker's position, which is bound to their movement chain. Can't reuse a proof from a different attacker. + +### 8.3 Domain Authority Verification + +**Problem:** Claim to be domain owner without proof. + +**Solution:** Domain ownership is verified via DECK-0002 (STARK proof binding pubkey to domain). Only the verified owner has knowledge of R. + +### 8.4 Race Conditions + +**Problem:** Victim moves just as attacker publishes derezz. + +**Solution:** Temporal ordering rules. If victim's movement timestamp > derezz timestamp, derezz fails. + +--- + +## 9. Implementation Requirements + +### 9.1 For Attackers + +| Requirement | Value | +|-------------|-------| +| Compute proof | O(2^height) for region size | +| Timestamp gap | Minimum 1 second after previous action | +| Spatial proximity | Must share region with victim | + +### 9.2 For Domain Owners + +| Requirement | Value | +|-------------|-------| +| Knowledge of R | Pre-computed (years of work once) | +| Derive subregion proof | O(1) — instant | +| Derezz within domain | Unlimited, instant | + +### 9.3 For Victims + +| Requirement | Value | +|-------------|-------| +| After derezz | Can only publish spawn (kind 334) | +| Spawn validation | Check domain spawn policy | +| Protection | Enter safe zone (domain with derezz: deny) | + +--- + +## 10. Protocol Summary + +**Action Types:** + +| Kind | Action | Description | +|------|--------|-------------| +| 333 | derezz | PVP attack against stationary avatar | +| 334 | spawn | Respawn after being derezzed | + +**Policy Actions:** + +| Action | Values | Effect | +|--------|--------|--------| +| derezz | allow/deny | Enable/disable PVP in domain | + +**The Game:** + +``` +Movement → Idleness → Vulnerability + ↓ +Derezz (if PVP enabled) + ↓ +Respawn + ↓ +Movement → ... +``` + +**The Meta:** + +- Stay in safe zones to avoid PVP +- Enter domains at your own risk +- Domain owners are gods within their territory +- Movement is survival; idleness is death + +--- + +## 11. Future Extensions + +### 11.1 Derezz Cooldown + +Minimum time between derezz actions by same attacker. + +### 11.2 Derezz Defense + +Items/abilities that provide temporary immunity. + +### 11.3 Bounty System + +Rewards for derezzing specific targets. + +### 11.4 Combat Log + +Public record of derezz events for reputation systems. + +--- + +**XOR 👾** From e84a26e057284c649e3bc5327dd8f6c89416bad8 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 17:49:19 +0000 Subject: [PATCH 15/16] DECK-0002: Domain owner exempt from all policies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add section 5.3: Domain Owner Exemption - Owner can bypass all policy restrictions in their domain - Rationale: work to compute R grants absolute authority - Update enforcement logic to check owner first - Renumber subsequent sections (5.4→5.5, 5.5→5.6) --- decks/DECK-0002-stark-proofs.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index 2097984..d86b6d0 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -341,7 +341,18 @@ Domain owners can disable or restrict actions within their territory: - `derezz: "deny"` — PVP attacks are protocol-invalid within this domain - `external-shard: "deny"` — Third-party content is filtered; only domain-referenced shards visible -### 5.3 Action Enforcement +### 5.3 Domain Owner Exemption + +**The domain owner is exempt from all policies defined for their domain.** + +This means: +- If `derezz: "deny"` — Owner can still derezz within their domain +- If `external-shard: "deny"` — Owner can still publish non-referenced shards +- If `hyperjump: "deny"` — Owner can still hyperjump + +**Rationale:** The domain owner computed R through substantial work. They have absolute authority within their territory. Policies apply to visitors and citizens, not to the sovereign. + +### 5.4 Action Enforcement ``` User attempts action within domain D: @@ -349,14 +360,15 @@ User attempts action within domain D: 2. If no domain: default rules apply 3. If domain exists: a. Verify domain proof is valid - b. Check action against domain policy - c. If policy == "deny": REJECT - d. Otherwise: ALLOW + b. IF user == domain.owner: ALLOW (owner exempt from policy) + c. Check action against domain policy + d. If policy == "deny": REJECT + e. Otherwise: ALLOW ``` **Note:** `pubkey_list` policy is defined for future use but not yet specified in this version. -### 5.4 Shard Content Filtering +### 5.5 Shard Content Filtering For shards (3D objects), enforcement works as follows: @@ -387,7 +399,7 @@ Otherwise: This follows NIP-33 convention for referencing parameterized replaceable events. -### 5.5 Example: Safe Zone with Content Control +### 5.6 Example: Safe Zone with Content Control ```json { From c72a4c181f713464d343b3ed486d19776381c0d4 Mon Sep 17 00:00:00 2001 From: XOR Date: Wed, 18 Mar 2026 19:08:24 +0000 Subject: [PATCH 16/16] Remove height limit from DECK-0002: all claim heights are valid - Section 12.1: Updated prover requirements table - Section 14: Removed height limit, all heights valid - Market determines feasibility, not protocol rules - Added note about experimental testing for proof sizes at high claims (~60+) - Proof size limit marked as TBD pending testing --- decks/DECK-0002-stark-proofs.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/decks/DECK-0002-stark-proofs.md b/decks/DECK-0002-stark-proofs.md index d86b6d0..c985afe 100644 --- a/decks/DECK-0002-stark-proofs.md +++ b/decks/DECK-0002-stark-proofs.md @@ -712,11 +712,14 @@ If multiple valid domain claims exist for overlapping regions: ### 12.1 Prover Requirements -| Height | Time | Storage | -|--------|------|---------| -| Height 25 | Hours | GB | -| Height 30 | Days | TB | -| Height 35 | Years | PB (disk-based) | +| Height | Work | Notes | +|--------|------|-------| +| Height 25 | 2^25 ops | Consumer-feasible | +| Height 30 | 2^30 ops | Consumer-feasible | +| Height 35 | 2^35 ops | Consumer-feasible | +| Height 40+ | 2^40+ ops | Market determines feasibility | + +**No protocol height limit.** Higher claims require more work but are valid. The exponential growth creates natural economic limits. ### 12.2 Verifier Requirements @@ -759,15 +762,18 @@ Domain owners SHOULD disclose their privacy policy: ## 14. Protocol Limits -Verifiers SHOULD reject domains exceeding these bounds: +Verifiers SHOULD apply these bounds: | Parameter | Maximum | Rationale | |-----------|---------|-----------| -| height | 35 | Prevents infeasible claims | -| proof_size | 200 KB | Prevents DoS | +| proof_size | TBD | Requires experimental testing for high claims | | policy_size | 64 KB | Prevents DoS | | URL length | 512 chars | Prevents URL attacks | +**No height limit.** All claim heights are valid. The work required grows exponentially with height, creating natural economic limits. The market — not the protocol — determines what claims are worth mining. + +**Proof size consideration:** Implementations should verify they don't arbitrarily restrict proof validation size, excluding valid claims. Experimental testing needed for very high claims (~60+) to characterize proof sizes and set appropriate limits. + --- ## 15. Future Extensions