Skip to content

Commit 377e998

Browse files
authored
Trace verifier (#3)
1 parent ee654a4 commit 377e998

File tree

16 files changed

+775
-108
lines changed

16 files changed

+775
-108
lines changed

.github/workflows/formal-spec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
uses: actions/checkout@v4
3636

3737
- name: 💾 Cache Nix store
38-
uses: actions/cache@v3.0.8
38+
uses: actions/cache@v4
3939
id: nix-cache
4040
with:
4141
path: /tmp/nixcache

formal-spec/Everything.agda

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
module Everything where
22

3-
open import Leios.Simplified
4-
open import Leios.Simplified.Deterministic
3+
open import CategoricalCrypto
4+
open import Class.Computational22
5+
open import Leios.Abstract
6+
open import Leios.Base
7+
open import Leios.Blocks
8+
open import Leios.Defaults
9+
open import Leios.FFD
10+
open import Leios.Foreign.BaseTypes
11+
open import Leios.Foreign.HsTypes
12+
open import Leios.Foreign.Types
13+
open import Leios.Foreign.Util
14+
open import Leios.KeyRegistration
15+
open import Leios.Network
16+
open import Leios.Prelude
17+
open import Leios.Protocol
518
open import Leios.Short
619
open import Leios.Short.Deterministic
7-
open import Leios.Network
8-
open import Leios.Foreign.Types
20+
open import Leios.Simplified
21+
open import Leios.Simplified.Deterministic
22+
open import Leios.Simplified.Deterministic.Test
23+
open import Leios.SpecStructure
24+
open import Leios.Traces
25+
open import Leios.Trace.Decidable
26+
open import Leios.Trace.Verifier
27+
open import Leios.Trace.Verifier.Test
28+
open import Leios.UniformShort
29+
open import Leios.Voting
30+
open import Leios.VRF
31+
open import StateMachine

formal-spec/Leios/Abstract.agda

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ open import Leios.Prelude
66

77
record LeiosAbstract : Type₁ where
88
field Tx : Type
9+
⦃ DecEq-Tx ⦄ : DecEq Tx
910
PoolID : Type
1011
⦃ DecEq-PoolID ⦄ : DecEq PoolID
1112
BodyHash VrfPf PrivKey Sig Hash : Type -- these could have been byte strings, but this is safer
1213
⦃ DecEq-Hash ⦄ : DecEq Hash
14+
⦃ DecEq-VrfPf ⦄ : DecEq VrfPf
15+
⦃ DecEq-Sig ⦄ : DecEq Sig
1316
Vote : Type
17+
⦃ DecEq-Vote ⦄ : DecEq Vote
1418
vote : PrivKey Hash Vote
1519
sign : PrivKey Hash Sig
1620
⦃ Hashable-Txs ⦄ : Hashable (List Tx) Hash

formal-spec/Leios/Base.agda

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ record BaseAbstract : Type₁ where
3434
record Functionality : Type₁ where
3535
field State : Type
3636
_-⟦_/_⟧⇀_ : State Input Output State Type
37+
⦃ Dec-_-⟦_/_⟧⇀_ ⦄ : {s : State} {i : Input} {o : Output} {s' : State} (s -⟦ i / o ⟧⇀ s') ⁇
3738
SUBMIT-total : {s b} ∃[ s' ] s -⟦ SUBMIT b / EMPTY ⟧⇀ s'
3839

3940
open Input public

formal-spec/Leios/Blocks.agda

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
open import Leios.Prelude
44
open import Leios.Abstract
55
open import Leios.FFD
6+
open import Tactic.Defaults
7+
open import Tactic.Derive.DecEq
68

79
module Leios.Blocks (a : LeiosAbstract) (let open LeiosAbstract a) where
810

@@ -20,26 +22,22 @@ record IsBlock (B : Type) : Type where
2022

2123
open IsBlock ⦃...⦄ public
2224

23-
OSig : Bool Type
24-
OSig true = Sig
25-
OSig false =
26-
2725
IBRef = Hash
2826
EBRef = Hash
2927

3028
--------------------------------------------------------------------------------
3129
-- Input Blocks
3230
--------------------------------------------------------------------------------
3331

34-
record IBHeaderOSig (b : Bool) : Type where
32+
record IBHeaderOSig (sig : Type) : Type where
3533
field slotNumber :
3634
producerID : PoolID
3735
lotteryPf : VrfPf
3836
bodyHash : Hash
39-
signature : OSig b
37+
signature : sig
4038

41-
IBHeader = IBHeaderOSig true
42-
PreIBHeader = IBHeaderOSig false
39+
IBHeader = IBHeaderOSig Sig
40+
PreIBHeader = IBHeaderOSig
4341

4442
record IBBody : Type where
4543
field txs : List Tx
@@ -50,28 +48,38 @@ record InputBlock : Type where
5048

5149
open IBHeaderOSig header public
5250

51+
unquoteDecl DecEq-IBBody DecEq-IBHeaderOSig DecEq-InputBlock =
52+
derive-DecEq (
53+
(quote IBBody , DecEq-IBBody)
54+
∷ (quote IBHeaderOSig , DecEq-IBHeaderOSig)
55+
∷ (quote InputBlock , DecEq-InputBlock) ∷ [])
56+
5357
instance
54-
IsBlock-IBHeaderOSig : {b} IsBlock (IBHeaderOSig b)
55-
IsBlock-IBHeaderOSig = record { IBHeaderOSig }
58+
IsBlock-IBHeader : IsBlock IBHeader
59+
IsBlock-IBHeader = record { IBHeaderOSig }
5660

5761
Hashable-IBBody : Hashable IBBody Hash
5862
Hashable-IBBody .hash b = hash (b .IBBody.txs)
5963

64+
Hashable-IBHeader : ⦃ Hashable PreIBHeader Hash ⦄ Hashable IBHeader Hash
65+
Hashable-IBHeader .hash b = hash {T = PreIBHeader}
66+
record { IBHeaderOSig b hiding (signature) ; signature = _ }
67+
6068
IsBlock-InputBlock : IsBlock InputBlock
6169
IsBlock-InputBlock = record { InputBlock }
6270

6371
mkIBHeader : ⦃ Hashable PreIBHeader Hash ⦄ PoolID VrfPf PrivKey List Tx IBHeader
6472
mkIBHeader slot id π pKey txs = record { signature = sign pKey (hash h) ; IBHeaderOSig h }
6573
where
66-
h : IBHeaderOSig false
74+
h : IBHeaderOSig
6775
h = record { slotNumber = slot
6876
; producerID = id
6977
; lotteryPf = π
7078
; bodyHash = hash txs
7179
; signature = _
7280
}
7381

74-
getIBRef : ⦃ Hashable IBHeader Hash ⦄ InputBlock IBRef
82+
getIBRef : ⦃ Hashable PreIBHeader Hash ⦄ InputBlock IBRef
7583
getIBRef = hash ∘ InputBlock.header
7684

7785
-- TODO
@@ -94,24 +102,26 @@ ibValid? record { header = h ; body = b } = ibHeaderValid? h ×-dec ibBodyValid?
94102
-- Endorser Blocks
95103
--------------------------------------------------------------------------------
96104

97-
record EndorserBlockOSig (b : Bool) : Type where
105+
record EndorserBlockOSig (sig : Type) : Type where
98106
field slotNumber :
99107
producerID : PoolID
100108
lotteryPf : VrfPf
101109
ibRefs : List IBRef
102110
ebRefs : List EBRef
103-
signature : OSig b
111+
signature : sig
104112

105-
EndorserBlock = EndorserBlockOSig true
106-
PreEndorserBlock = EndorserBlockOSig false
113+
EndorserBlock = EndorserBlockOSig Sig
114+
PreEndorserBlock = EndorserBlockOSig
107115

108116
instance
109117
Hashable-EndorserBlock : ⦃ Hashable PreEndorserBlock Hash ⦄ Hashable EndorserBlock Hash
110118
Hashable-EndorserBlock .hash b = hash {T = PreEndorserBlock}
111119
record { EndorserBlockOSig b hiding (signature) ; signature = _ }
112120

113-
IsBlock-EndorserBlockOSig : {b} IsBlock (EndorserBlockOSig b)
114-
IsBlock-EndorserBlockOSig {b} = record { EndorserBlockOSig }
121+
IsBlock-EndorserBlock : IsBlock EndorserBlock
122+
IsBlock-EndorserBlock = record { EndorserBlockOSig }
123+
124+
unquoteDecl DecEq-EndorserBlockOSig = derive-DecEq ((quote EndorserBlockOSig , DecEq-EndorserBlockOSig) ∷ [])
115125

116126
mkEB : ⦃ Hashable PreEndorserBlock Hash ⦄ PoolID VrfPf PrivKey List IBRef List EBRef EndorserBlock
117127
mkEB slot id π pKey LI LE = record { signature = sign pKey (hash b) ; EndorserBlockOSig b }
@@ -161,6 +171,9 @@ module GenFFD ⦃ _ : IsBlock (List Vote) ⦄ where
161171
data Body : Type where
162172
ibBody : IBBody Body
163173

174+
unquoteDecl DecEq-Header DecEq-Body =
175+
derive-DecEq ((quote Header , DecEq-Header) ∷ (quote Body , DecEq-Body) ∷ [])
176+
164177
ID : Type
165178
ID = ℕ × PoolID
166179

formal-spec/Leios/Foreign/Defaults.agda renamed to formal-spec/Leios/Defaults.agda

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
{-# OPTIONS --safe #-}
1+
{-# OPTIONS --allow-unsolved-metas #-}
22

33
open import Leios.Prelude
44
open import Leios.Abstract
55
open import Leios.SpecStructure
66
open import Axiom.Set.Properties th
77

88
open import Data.Nat.Show as N
9-
open import Data.Integer
9+
open import Data.Integer hiding (_≟_)
1010
open import Data.String as S using (intersperse)
1111
open import Function.Related.TypeIsomorphisms
1212
open import Relation.Binary.Structures
1313

14-
import Data.Sum
14+
open import Tactic.Defaults
15+
open import Tactic.Derive.DecEq
1516

1617
open Equivalence
1718

@@ -21,7 +22,7 @@ open Equivalence
2122
-- As parameters the module expects
2223
-- * numberOfParties: the total number of participants
2324
-- * SUT-id: the number of the SUT (system under test)
24-
module Leios.Foreign.Defaults (numberOfParties : ℕ) (SUT-id : Fin numberOfParties) where
25+
module Leios.Defaults (numberOfParties : ℕ) (SUT-id : Fin numberOfParties) where
2526

2627
instance
2728
htx : Hashable (List ℕ) String
@@ -90,6 +91,7 @@ d-BaseFunctionality =
9091
record
9192
{ State =
9293
; _-⟦_/_⟧⇀_ = λ _ _ _ _
94+
; Dec-_-⟦_/_⟧⇀_ = ⁇ (yes tt)
9395
; SUBMIT-total = tt , tt
9496
}
9597

@@ -104,7 +106,7 @@ instance
104106
; lotteryPf = λ _ tt
105107
}
106108

107-
hhs : {b} Hashable (IBHeaderOSig b) String
109+
hhs : Hashable PreIBHeader String
108110
hhs = record { hash = IBHeaderOSig.bodyHash }
109111

110112
hpe : Hashable PreEndorserBlock String
@@ -119,6 +121,8 @@ record FFDState : Type where
119121
outEBs : List EndorserBlock
120122
outVTs : List (List Vote)
121123

124+
unquoteDecl DecEq-FFDState = derive-DecEq ((quote FFDState , DecEq-FFDState) ∷ [])
125+
122126
open GenFFD.Header
123127
open GenFFD.Body
124128
open FFDState
@@ -142,22 +146,54 @@ data SimpleFFD : FFDState → FFDAbstract.Input ffdAbstract → FFDAbstract.Outp
142146

143147
Fetch : {s} SimpleFFD s FFDAbstract.Fetch (FFDAbstract.FetchRes (flushIns s)) (record s { inIBs = [] ; inEBs = [] ; inVTs = [] })
144148

145-
simple-total : {s h b} ∃[ s' ] (SimpleFFD s (FFDAbstract.Send h b) FFDAbstract.SendRes s')
146-
simple-total {s} {ibHeader h} {just (ibBody b)} = record s { outIBs = record {header = h; body = b} ∷ outIBs s} , SendIB
147-
simple-total {s} {ebHeader eb} {nothing} = record s { outEBs = eb ∷ outEBs s} , SendEB
148-
simple-total {s} {vHeader vs} {nothing} = record s { outVTs = vs ∷ outVTs s} , SendVS
149+
send-total : {s h b} ∃[ s' ] (SimpleFFD s (FFDAbstract.Send h b) FFDAbstract.SendRes s')
150+
send-total {s} {ibHeader h} {just (ibBody b)} = record s { outIBs = record {header = h; body = b} ∷ outIBs s} , SendIB
151+
send-total {s} {ebHeader eb} {nothing} = record s { outEBs = eb ∷ outEBs s} , SendEB
152+
send-total {s} {vHeader vs} {nothing} = record s { outVTs = vs ∷ outVTs s} , SendVS
153+
154+
send-total {s} {ibHeader h} {nothing} = s , BadSendIB
155+
send-total {s} {ebHeader eb} {just _} = s , BadSendEB
156+
send-total {s} {vHeader vs} {just _} = s , BadSendVS
157+
158+
fetch-total : {s} ∃[ x ] (∃[ s' ] (SimpleFFD s FFDAbstract.Fetch (FFDAbstract.FetchRes x) s'))
159+
fetch-total {s} = flushIns s , (record s { inIBs = [] ; inEBs = [] ; inVTs = [] } , Fetch)
160+
161+
send-complete : {s h b s'} SimpleFFD s (FFDAbstract.Send h b) FFDAbstract.SendRes s' s' ≡ proj₁ (send-total {s} {h} {b})
162+
send-complete SendIB = refl
163+
send-complete SendEB = refl
164+
send-complete SendVS = refl
165+
send-complete BadSendIB = refl
166+
send-complete BadSendEB = refl
167+
send-complete BadSendVS = refl
149168

150-
simple-total {s} {ibHeader h} {nothing} = s , BadSendIB
151-
simple-total {s} {ebHeader eb} {just _} = s , BadSendEB
152-
simple-total {s} {vHeader vs} {just _} = s , BadSendVS
169+
fetch-complete₁ : {s r s'} SimpleFFD s FFDAbstract.Fetch (FFDAbstract.FetchRes r) s' s' ≡ proj₁ (proj₂ (fetch-total {s}))
170+
fetch-complete₁ Fetch = refl
171+
172+
fetch-complete₂ : {s r s'} SimpleFFD s FFDAbstract.Fetch (FFDAbstract.FetchRes r) s' r ≡ proj₁ (fetch-total {s})
173+
fetch-complete₂ Fetch = refl
174+
175+
instance
176+
Dec-SimpleFFD : {s i o s'} SimpleFFD s i o s' ⁇
177+
Dec-SimpleFFD {s} {FFDAbstract.Send h b} {FFDAbstract.SendRes} {s'} with s' ≟ proj₁ (send-total {s} {h} {b})
178+
... | yes p rewrite p = ⁇ yes (proj₂ send-total)
179+
... | no ¬p = ⁇ no λ x ⊥-elim (¬p (send-complete x))
180+
Dec-SimpleFFD {_} {FFDAbstract.Send _ _} {FFDAbstract.FetchRes _} {_} = ⁇ no λ ()
181+
Dec-SimpleFFD {s} {FFDAbstract.Fetch} {FFDAbstract.FetchRes r} {s'}
182+
with s' ≟ proj₁ (proj₂ (fetch-total {s}))
183+
| r ≟ proj₁ (fetch-total {s})
184+
... | yes p | yes q rewrite p rewrite q = ⁇ yes (proj₂ (proj₂ (fetch-total {s})))
185+
... | yes p | no ¬q = ⁇ no λ x ⊥-elim (¬q (fetch-complete₂ x))
186+
... | no ¬p | _ = ⁇ no λ x ⊥-elim (¬p (fetch-complete₁ x))
187+
Dec-SimpleFFD {_} {FFDAbstract.Fetch} {FFDAbstract.SendRes} {_} = ⁇ no λ ()
153188

154189
d-FFDFunctionality : FFDAbstract.Functionality ffdAbstract
155190
d-FFDFunctionality =
156191
record
157192
{ State = FFDState
158193
; initFFDState = record { inIBs = []; inEBs = []; inVTs = []; outIBs = []; outEBs = []; outVTs = [] }
159194
; _-⟦_/_⟧⇀_ = SimpleFFD
160-
; FFD-Send-total = simple-total
195+
; Dec-_-⟦_/_⟧⇀_ = Dec-SimpleFFD
196+
; FFD-Send-total = send-total
161197
}
162198

163199
open import Leios.Voting public
@@ -181,6 +217,8 @@ d-VotingAbstract-2 =
181217
st : SpecStructure 1
182218
st = record
183219
{ a = d-Abstract
220+
; Hashable-PreIBHeader = hhs
221+
; Hashable-PreEndorserBlock = hpe
184222
; id = SUT-id
185223
; FFD' = d-FFDFunctionality
186224
; vrf' = d-VRF
@@ -201,6 +239,8 @@ st = record
201239
st-2 : SpecStructure 2
202240
st-2 = record
203241
{ a = d-Abstract
242+
; Hashable-PreIBHeader = hhs
243+
; Hashable-PreEndorserBlock = hpe
204244
; id = SUT-id
205245
; FFD' = d-FFDFunctionality
206246
; vrf' = d-VRF
@@ -249,4 +289,31 @@ maximalFin (ℕ.suc n) {a} with toℕ a N.<? n
249289
open FunTot (completeFin numberOfParties) (maximalFin numberOfParties)
250290

251291
sd : TotalMap (Fin numberOfParties) ℕ
252-
sd = Fun⇒TotalMap toℕ
292+
sd = Fun⇒TotalMap (const 100000000)
293+
294+
open import Class.Computational
295+
open import Class.Computational22
296+
297+
open Computational22
298+
open BaseAbstract
299+
open FFDAbstract
300+
301+
open GenFFD.Header using (ibHeader; ebHeader; vHeader)
302+
open GenFFD.Body using (ibBody)
303+
open FFDState
304+
305+
instance
306+
Computational-B : Computational22 (BaseAbstract.Functionality._-⟦_/_⟧⇀_ d-BaseFunctionality) String
307+
Computational-B .computeProof s (INIT x) = success ((STAKE sd , tt) , tt)
308+
Computational-B .computeProof s (SUBMIT x) = success ((EMPTY , tt) , tt)
309+
Computational-B .computeProof s FTCH-LDG = success (((BASE-LDG []) , tt) , tt)
310+
Computational-B .completeness _ _ _ _ _ = {!!} -- TODO: Completeness proof
311+
312+
Computational-FFD : Computational22 (FFDAbstract.Functionality._-⟦_/_⟧⇀_ d-FFDFunctionality) String
313+
Computational-FFD .computeProof s (Send (ibHeader h) (just (ibBody b))) = success ((SendRes , record s {outIBs = record {header = h; body = b} ∷ outIBs s}) , SendIB)
314+
Computational-FFD .computeProof s (Send (ebHeader h) nothing) = success ((SendRes , record s {outEBs = h ∷ outEBs s}) , SendEB)
315+
Computational-FFD .computeProof s (Send (vHeader h) nothing) = success ((SendRes , record s {outVTs = h ∷ outVTs s}) , SendVS)
316+
Computational-FFD .computeProof s Fetch = success ((FetchRes (flushIns s) , record s {inIBs = []; inEBs = []; inVTs = []}) , Fetch)
317+
318+
Computational-FFD .computeProof _ _ = failure "FFD error"
319+
Computational-FFD .completeness _ _ _ _ _ = {!!} -- TODO:Completeness proof

formal-spec/Leios/FFD.agda

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ open import Leios.Prelude
66

77
record FFDAbstract : Type₁ where
88
field Header Body ID : Type
9+
⦃ DecEq-Header ⦄ : DecEq Header
10+
⦃ DecEq-Body ⦄ : DecEq Body
911
match : Header Body Type
1012
msgID : Header ID
1113

@@ -21,6 +23,7 @@ record FFDAbstract : Type₁ where
2123
field State : Type
2224
initFFDState : State
2325
_-⟦_/_⟧⇀_ : State Input Output State Type
26+
⦃ Dec-_-⟦_/_⟧⇀_ ⦄ : {s : State} {i : Input} {o : Output} {s' : State} (s -⟦ i / o ⟧⇀ s') ⁇
2427
FFD-Send-total : {ffds h b} ∃[ ffds' ] ffds -⟦ Send h b / SendRes ⟧⇀ ffds'
2528

2629
open Input public

0 commit comments

Comments
 (0)