synor/formal/tla/GHOSTDAGOrdering.tla
Gulshan Yadav 1606776394 feat: Phase 7 critical tasks - security, formal verification, WASM crypto
## Formal Verification
- Add TLA+ specs for UTXO conservation (formal/tla/UTXOConservation.tla)
- Add TLA+ specs for GHOSTDAG ordering (formal/tla/GHOSTDAGOrdering.tla)
- Add mathematical proof of DAA convergence (formal/proofs/)
- Document Kani verification approach (formal/kani/)

## Bug Bounty Program
- Add SECURITY.md with vulnerability disclosure process
- Add docs/BUG_BOUNTY.md with $500-$100,000 reward tiers
- Define scope, rules, and response SLA

## Web Wallet Dilithium3 WASM Integration
- Build WASM module via Docker (498KB optimized)
- Add wasm-crypto.ts lazy loader for Dilithium3
- Add createHybridSignatureLocal() for full client-side signing
- Add createHybridSignatureSmart() for auto-mode selection
- Add Dockerfile.wasm and build scripts

## Security Review ($0 Approach)
- Add .github/workflows/security.yml CI workflow
- Add deny.toml for cargo-deny license/security checks
- Add Dockerfile.security for audit container
- Add scripts/security-audit.sh for local audits
- Configure cargo-audit, cargo-deny, cargo-geiger, gitleaks
2026-01-10 01:40:03 +05:30

146 lines
5.4 KiB
Text

-------------------------------- MODULE GHOSTDAGOrdering --------------------------------
\* TLA+ Specification for GHOSTDAG Ordering Determinism
\*
\* This specification formally verifies that the GHOSTDAG algorithm produces
\* a deterministic total ordering of blocks given the same DAG structure,
\* regardless of the order in which blocks are received.
\*
\* Key Property: Two honest nodes with the same DAG view will compute
\* the same blue set, selected parent chain, and block ordering.
\*
\* Author: Synor Team
\* Date: January 2026
EXTENDS Integers, Sequences, FiniteSets, TLC
CONSTANTS
K, \* K parameter (anticone size bound for blue blocks)
MAX_BLOCKS, \* Maximum blocks in simulation
GENESIS \* Genesis block hash
VARIABLES
dag, \* DAG structure: block -> {parent blocks}
blue_set, \* Set of blue blocks
blue_score, \* Mapping: block -> blue score
selected_parent,\* Mapping: block -> selected parent
chain \* Selected parent chain (sequence)
\* Type invariant
TypeOK ==
/\ dag \in [SUBSET Nat -> SUBSET Nat]
/\ blue_set \subseteq DOMAIN dag
/\ blue_score \in [DOMAIN dag -> Nat]
/\ selected_parent \in [DOMAIN dag \ {GENESIS} -> DOMAIN dag]
/\ chain \in Seq(DOMAIN dag)
\* Helper: Get all ancestors of a block
RECURSIVE Ancestors(_, _)
Ancestors(block, d) ==
IF block = GENESIS THEN {GENESIS}
ELSE LET parents == d[block]
IN parents \cup UNION {Ancestors(p, d) : p \in parents}
\* Helper: Get past (ancestors including self)
Past(block, d) == {block} \cup Ancestors(block, d)
\* Helper: Get anticone of block B relative to block A
\* Anticone(A, B) = blocks in Past(B) that are not in Past(A) and A is not in their past
Anticone(blockA, blockB, d) ==
LET pastA == Past(blockA, d)
pastB == Past(blockB, d)
IN {b \in pastB : b \notin pastA /\ blockA \notin Past(b, d)}
\* GHOSTDAG: Compute blue set for a new block
\* A block is blue if its anticone (relative to virtual) contains at most K blue blocks
ComputeBlueSet(new_block, d, current_blue) ==
LET anticone == Anticone(new_block, new_block, d) \cap current_blue
IN IF Cardinality(anticone) <= K
THEN current_blue \cup {new_block}
ELSE current_blue
\* Compute blue score (number of blue blocks in past)
ComputeBlueScore(block, d, bs) ==
Cardinality(Past(block, d) \cap bs)
\* Select parent with highest blue score
SelectParent(block, d, scores) ==
LET parents == d[block]
IN CHOOSE p \in parents : \A q \in parents : scores[p] >= scores[q]
\* CRITICAL INVARIANT: Ordering is deterministic
\* Given the same DAG, all nodes compute the same ordering
OrderingDeterminism ==
\* For any two blocks A and B, their relative order is determined solely by:
\* 1. Blue scores (higher = earlier in virtual order)
\* 2. If tied, by hash (deterministic tiebreaker)
\A a, b \in DOMAIN dag :
a # b =>
(blue_score[a] > blue_score[b] => \* a comes before b in ordering
\A i, j \in 1..Len(chain) :
chain[i] = a /\ chain[j] = b => i < j)
\* Initial state: Only genesis block
Init ==
/\ dag = [b \in {GENESIS} |-> {}]
/\ blue_set = {GENESIS}
/\ blue_score = [b \in {GENESIS} |-> 0]
/\ selected_parent = [b \in {} |-> GENESIS] \* Empty function
/\ chain = <<GENESIS>>
\* Add a new block to the DAG
AddBlock(new_block, parents) ==
/\ new_block \notin DOMAIN dag
/\ parents \subseteq DOMAIN dag
/\ parents # {}
/\ LET new_dag == [b \in DOMAIN dag \cup {new_block} |->
IF b = new_block THEN parents ELSE dag[b]]
new_blue == ComputeBlueSet(new_block, new_dag, blue_set)
new_scores == [b \in DOMAIN new_dag |->
ComputeBlueScore(b, new_dag, new_blue)]
new_sel_parent == SelectParent(new_block, new_dag, new_scores)
IN /\ dag' = new_dag
/\ blue_set' = new_blue
/\ blue_score' = new_scores
/\ selected_parent' = [b \in DOMAIN selected_parent \cup {new_block} |->
IF b = new_block THEN new_sel_parent
ELSE selected_parent[b]]
/\ chain' = \* Rebuild chain to tip
LET RECURSIVE BuildChain(_, _)
BuildChain(blk, acc) ==
IF blk = GENESIS THEN Append(acc, GENESIS)
ELSE BuildChain(selected_parent'[blk], Append(acc, blk))
IN BuildChain(new_block, <<>>)
\* Next state relation
Next ==
\E new_block \in Nat, parents \in SUBSET (DOMAIN dag) :
/\ Cardinality(DOMAIN dag) < MAX_BLOCKS
/\ AddBlock(new_block, parents)
\* Specification
Spec == Init /\ [][Next]_<<dag, blue_set, blue_score, selected_parent, chain>>
\* Safety properties
\* Blue set is monotonic (blocks stay blue once blue)
BlueMonotonic ==
[][blue_set \subseteq blue_set']_blue_set
\* Chain extends (never shrinks except on reorg)
ChainGrows ==
[][Len(chain') >= Len(chain) \/ \E i \in 1..Len(chain) : chain[i] # chain'[i]]_chain
\* Selected parent chain is connected
ChainConnected ==
\A i \in 1..(Len(chain)-1) :
chain[i] \in dag[chain[i+1]]
\* All properties
AllInvariants ==
/\ TypeOK
/\ OrderingDeterminism
/\ ChainConnected
THEOREM Spec => []AllInvariants
================================================================================