Skip to content

Commit d3fffd6

Browse files
committed
Squashed commit of the following:
commit 35ebc97 Author: Jan Mas Rovira <[email protected]> Date: Mon Sep 22 17:28:56 2025 +0200 destructors commit 18fcdd3 Author: Jan Mas Rovira <[email protected]> Date: Mon Sep 22 13:39:48 2025 +0200 syntax commit 6df404c Author: Jan Mas Rovira <[email protected]> Date: Mon Sep 22 13:13:24 2025 +0200 constrs and destr commit 2165afe Author: Jan Mas Rovira <[email protected]> Date: Mon Sep 22 10:17:33 2025 +0200 sigs commit 82e19b9 Author: Jan Mas Rovira <[email protected]> Date: Sun Sep 21 23:39:58 2025 +0200 proofs commit 2e06fac Author: Jan Mas Rovira <[email protected]> Date: Fri Sep 19 16:33:54 2025 +0200 wip commit 72faad1 Author: Jan Mas Rovira <[email protected]> Date: Fri Sep 19 08:25:44 2025 +0200 noSignatures commit fb64072 Author: Jan Mas Rovira <[email protected]> Date: Thu Sep 18 15:23:58 2025 +0200 signatures wip commit 4a5495e Author: Jan Mas Rovira <[email protected]> Date: Wed Sep 17 17:29:26 2025 +0200 store owner commit dc14617 Author: Jan Mas Rovira <[email protected]> Date: Wed Sep 17 15:42:56 2025 +0200 basic authorization for class members
1 parent 03cd53d commit d3fffd6

File tree

22 files changed

+500
-228
lines changed

22 files changed

+500
-228
lines changed

AVM/Authorization.lean

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Mathlib.Data.Fintype.Basic
2+
import Prelude
3+
4+
structure PublicKey where
5+
key : Nat
6+
deriving Repr, BEq, Hashable, DecidableEq, Inhabited
7+
8+
def PublicKey.universal : PublicKey where
9+
key := 0
10+
11+
instance PublicKey.hasTypeRep : TypeRep PublicKey where
12+
rep := Rep.atomic "PublicKey"
13+
14+
structure PrivateKey where
15+
key : Nat
16+
deriving Repr, BEq, Hashable, DecidableEq
17+
18+
def PrivateKey.universal : PrivateKey where
19+
key := 0
20+
21+
-- mock function
22+
def checkKey (pub : PublicKey) (priv : PrivateKey) : Bool := pub.key == priv.key
23+
24+
structure Signature {A : Type u} (msg : A) : Type where
25+
signature : PrivateKey
26+
27+
def Signature.sign {A : Type u} (msg : A) (key : PrivateKey) : Signature msg where
28+
signature := key
29+
30+
-- mock function
31+
def checkSignature {A : Type u} {msg : A} (sig : Signature msg) (pub : PublicKey) : Bool := checkKey pub sig.signature

AVM/Class/Label.lean

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Anoma.Resource
22
import Prelude
33
import Mathlib.Data.Fintype.Basic
44
import Mathlib.Data.FinEnum
5+
import AVM.Authorization
56

67
abbrev AVM.ObjectId := Anoma.ObjectId
78

@@ -36,18 +37,23 @@ structure Label : Type 1 where
3637
[constructorsFinite : Fintype ConstructorId]
3738
[constructorsRepr : Repr ConstructorId]
3839
[constructorsBEq : BEq ConstructorId]
40+
[constructorsLawfulBEq : LawfulBEq ConstructorId]
3941

4042
DestructorId : Type := Empty
4143
DestructorArgs : DestructorId -> SomeType := fun _ => ⟨PUnit⟩
44+
DestructorSignatureId : DestructorId → Type := fun _ => Empty
4245
[destructorsFinite : Fintype DestructorId]
4346
[destructorsRepr : Repr DestructorId]
4447
[destructorsBEq : BEq DestructorId]
48+
[destructorsLawfulBEq : LawfulBEq DestructorId]
4549

4650
MethodId : Type
4751
MethodArgs : MethodId -> SomeType
52+
MethodSignatureId : MethodId → Type := fun _ => Empty
4853
[methodsFinite : Fintype MethodId]
4954
[methodsRepr : Repr MethodId]
5055
[methodsBEq : BEq MethodId]
56+
[methodsLawfulBEq : LawfulBEq MethodId]
5157

5258
def Label.dummy : Label where
5359
name := "Dummy"
@@ -59,22 +65,21 @@ def Label.dummy : Label where
5965
constructorsRepr := inferInstanceAs (Repr PUnit)
6066
constructorsBEq := inferInstanceAs (BEq PUnit)
6167
DestructorId := Empty
62-
DestructorArgs := fun _ => ⟨PUnit⟩
63-
destructorsFinite := inferInstanceAs (Fintype Empty)
64-
destructorsRepr := inferInstanceAs (Repr Empty)
65-
destructorsBEq := inferInstanceAs (BEq Empty)
66-
MethodId := PUnit
67-
MethodArgs := fun _ => ⟨PUnit⟩
68-
methodsFinite := inferInstanceAs (Fintype PUnit)
69-
methodsRepr := inferInstanceAs (Repr PUnit)
70-
methodsBEq := inferInstanceAs (BEq PUnit)
71-
72-
inductive Label.MemberId (lab : Class.Label) where
68+
MethodId := Empty
69+
MethodArgs f := nomatch f
70+
71+
inductive Label.MemberId (lab : Class.Label) : Type where
7372
| constructorId (constrId : lab.ConstructorId) : MemberId lab
7473
| destructorId (destructorId : lab.DestructorId) : MemberId lab
7574
| methodId (methodId : lab.MethodId) : MemberId lab
7675
| upgradeId : MemberId lab
7776

77+
abbrev Label.MemberId.SignatureId {lab : Class.Label} : Label.MemberId lab → Type
78+
| .methodId m => lab.MethodSignatureId m
79+
| .destructorId m => lab.DestructorSignatureId m
80+
| .constructorId _ => Empty
81+
| .upgradeId => Empty
82+
7883
instance Label.MemberId.hasBEq {lab : Class.Label} : BEq (Class.Label.MemberId lab) where
7984
beq a b :=
8085
match a, b with
@@ -89,6 +94,27 @@ instance Label.MemberId.hasBEq {lab : Class.Label} : BEq (Class.Label.MemberId l
8994
| _, methodId _ => false
9095
| upgradeId, upgradeId => true
9196

97+
instance Label.MemberId.instReflBEq {lab : Class.Label} : ReflBEq lab.MemberId where
98+
rfl := by
99+
intro a
100+
have := lab.constructorsLawfulBEq
101+
have := lab.destructorsLawfulBEq
102+
have := lab.methodsLawfulBEq
103+
cases a
104+
iterate 4 {
105+
unfold BEq.beq Label.MemberId.hasBEq
106+
simp
107+
}
108+
109+
instance Label.MemberId.instLawfulBEq {lab : Class.Label} : LawfulBEq (Class.Label.MemberId lab) where
110+
eq_of_beq := by
111+
intro a b
112+
have := lab.constructorsLawfulBEq
113+
have := lab.destructorsLawfulBEq
114+
have := lab.methodsLawfulBEq
115+
unfold BEq.beq Label.MemberId.hasBEq
116+
cases a <;> cases b <;> simp
117+
92118
instance Label.MemberId.hasTypeRep (lab : Class.Label) : TypeRep (Class.Label.MemberId lab) where
93119
rep := Rep.composite "AVM.Class.Label.MemberId" [Rep.atomic lab.name]
94120

@@ -108,6 +134,34 @@ def Label.MemberId.Args {lab : Class.Label} (memberId : MemberId lab) : SomeType
108134
| methodId c => lab.MethodArgs c
109135
| upgradeId => ⟨PUnit⟩
110136

137+
abbrev Label.MemberId.Signatures
138+
{lab : Class.Label}
139+
(f : MemberId lab)
140+
(args : f.Args.type)
141+
: Type :=
142+
f.SignatureId → Signature (f, args)
143+
144+
abbrev Label.MethodId.Signatures
145+
{lab : Class.Label}
146+
(f : lab.MethodId)
147+
(args : f.Args.type)
148+
: Type :=
149+
(MemberId.methodId f) |>.Signatures args
150+
151+
abbrev Label.ConstructorId.Signatures
152+
{lab : Class.Label}
153+
(f : lab.ConstructorId)
154+
(args : f.Args.type)
155+
: Type :=
156+
(MemberId.constructorId f) |>.Signatures args
157+
158+
abbrev Label.DestructorId.Signatures
159+
{lab : Class.Label}
160+
(f : lab.DestructorId)
161+
(args : f.Args.type)
162+
: Type :=
163+
(MemberId.destructorId f) |>.Signatures args
164+
111165
instance Label.hasTypeRep : TypeRep Label where
112166
rep := Rep.atomic "AVM.Class.Label"
113167

AVM/Class/Member.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ structure Destructor {lab : Ecosystem.Label} (cid : lab.ClassId) (destructorId :
1313
/-- Destructor call body. -/
1414
body : (self : Object cid) → destructorId.Args.type → Program.{0} lab PUnit
1515
/-- Extra destructor logic. -/
16-
invariant : (self : Object cid) → destructorId.Args.type → Bool
16+
invariant : (self : Object cid) → (args : destructorId.Args.type) → destructorId.Signatures args → Bool
1717

1818
structure Method {lab : Ecosystem.Label} (cid : lab.ClassId) (methodId : cid.label.MethodId) : Type 1 where
1919
/-- Method call body. -/
2020
body : (self : Object cid) → methodId.Args.type → Program lab (Object cid)
2121
/-- Extra method logic. The method invariant is combined with auto-generated
2222
method body constraints to create the method logic. -/
23-
invariant : (self : Object cid) → methodId.Args.type → Bool
23+
invariant : (self : Object cid) → (args : methodId.Args.type) → methodId.Signatures args → Bool
2424

2525
/-- A class member is a constructor, a destructor or a method. -/
2626
inductive Member {lab : Ecosystem.Label} (cid : lab.ClassId) where

AVM/Class/Translation/Logics.lean

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ private def Constructor.Message.logicFun
1414
(args : Logic.Args)
1515
: Bool :=
1616
let try msg : Message lab := Message.fromResource args.self
17-
let try argsData := SomeType.cast msg.args
18-
let try vals : (constr.body argsData).params.Product := tryCast msg.vals
17+
let try argsData := SomeType.cast msg.contents.args
18+
let try vals : (constr.body argsData).params.Product := tryCast msg.contents.vals
1919
let newObjData := constr.body argsData |>.value vals
2020
let consumedResObjs := Logic.selectObjectResources args.consumed
2121
let createdResObjs := Logic.selectObjectResources args.created
@@ -36,17 +36,24 @@ private def Destructor.Message.logicFun
3636
(args : Logic.Args)
3737
: Bool :=
3838
let try msg : Message lab := Message.fromResource args.self
39-
let try argsData := SomeType.cast msg.args
40-
let consumedResObjs := Logic.selectObjectResources args.consumed
41-
let createdResObjs := Logic.selectObjectResources args.created
42-
let! [selfRes] := consumedResObjs
43-
let try selfObj : Object classId := Object.fromResource selfRes
44-
Logic.checkResourceValues [selfObj.toObjectValue] createdResObjs
45-
&& Logic.checkResourcesPersistent consumedResObjs
46-
&& Logic.checkResourcesEphemeral createdResObjs
47-
&& destructor.invariant selfObj argsData
39+
match msg with
40+
| {id := id, contents := contents} =>
41+
-- TODO check syntax
42+
if h : id == .classMember (Label.MemberId.destructorId destructorId)
43+
then
44+
let contents : MessageContents lab (.classMember (Label.MemberId.destructorId destructorId)) := eq_of_beq h ▸ contents
45+
let argsData := contents.args
46+
let signatures : destructorId.Signatures argsData := contents.signatures
47+
let consumedResObjs := Logic.selectObjectResources args.consumed
48+
let createdResObjs := Logic.selectObjectResources args.created
49+
let! [selfRes] := consumedResObjs
50+
let try selfObj : Object classId := Object.fromResource selfRes
51+
Logic.checkResourceValues [selfObj.toObjectValue] createdResObjs
52+
&& Logic.checkResourcesPersistent consumedResObjs
53+
&& Logic.checkResourcesEphemeral createdResObjs
54+
&& destructor.invariant selfObj argsData signatures
55+
else false
4856

49-
/-- Creates a message logic function for a given method. -/
5057
private def Method.Message.logicFun
5158
{lab : Ecosystem.Label}
5259
{classId : lab.ClassId}
@@ -55,18 +62,25 @@ private def Method.Message.logicFun
5562
(args : Logic.Args)
5663
: Bool :=
5764
let try msg : Message lab := Message.fromResource args.self
58-
let try argsData := SomeType.cast msg.args
59-
let consumedResObjs := Logic.selectObjectResources args.consumed
60-
let createdResObjs := Logic.selectObjectResources args.created
61-
let! [selfRes] := consumedResObjs
62-
let try selfObj : Object classId := Object.fromResource selfRes
63-
check method.invariant selfObj argsData
64-
let body := method.body selfObj argsData
65-
let try vals : body.params.Product := tryCast msg.vals
66-
let createdObject : Object classId := body |>.value vals
67-
Logic.checkResourceValues [createdObject.toObjectValue] createdResObjs
68-
&& Logic.checkResourcesPersistent consumedResObjs
69-
&& Logic.checkResourcesPersistent createdResObjs
65+
match msg with
66+
| {id := id, contents := contents} =>
67+
if h : id == .classMember (Label.MemberId.methodId methodId)
68+
then
69+
let contents : MessageContents lab (.classMember (Label.MemberId.methodId methodId)) := eq_of_beq h ▸ contents
70+
let argsData : methodId.Args.type := contents.args
71+
let consumedResObjs := Logic.selectObjectResources args.consumed
72+
let createdResObjs := Logic.selectObjectResources args.created
73+
let! [selfRes] := consumedResObjs
74+
let try selfObj : Object classId := Object.fromResource selfRes
75+
let body := method.body selfObj argsData
76+
let try vals : body.params.Product := tryCast contents.vals
77+
let signatures : methodId.Signatures argsData := contents.signatures
78+
check method.invariant selfObj argsData signatures
79+
let createdObject : Object classId := body |>.value vals
80+
Logic.checkResourceValues [createdObject.toObjectValue] createdResObjs
81+
&& Logic.checkResourcesPersistent consumedResObjs
82+
&& Logic.checkResourcesPersistent createdResObjs
83+
else false
7084

7185
private def Upgrade.Message.logicFun
7286
{lab : Ecosystem.Label}
@@ -108,7 +122,7 @@ private def logicFun
108122
nMessages + 1 == (Logic.filterOutDummy args.consumed).length
109123
&& consumedMessageResources.all fun res =>
110124
let try msg : Message lab := Message.fromResource res
111-
let! [recipient] := msg.recipients.toList
125+
let! [recipient] := msg.contents.recipients.toList
112126
consumedObject.uid == recipient
113127

114128
def Constructor.Message.logic
@@ -157,7 +171,7 @@ def MultiMethod.Message.logicFun
157171
(data : MultiMethodData)
158172
: Bool :=
159173
let try msg : Message lab := Message.fromResource args.self
160-
let try fargs : multiId.Args.type := SomeType.cast msg.args
174+
let try fargs : multiId.Args.type := SomeType.cast msg.contents.args
161175
let consumedResObjs := Logic.selectObjectResources args.consumed
162176
let createdResObjs := Logic.selectObjectResources args.created
163177
let try (argsConsumedSelves, argsConstructedEph, argsDestroyed, .unit) :=
@@ -167,7 +181,7 @@ def MultiMethod.Message.logicFun
167181
let try argsConsumedObjects : multiId.Selves := Label.MultiMethodId.ConsumedToSelves argsConsumedSelves.toList
168182
let prog := method.body argsConsumedObjects fargs
169183
method.invariant argsConsumedObjects fargs
170-
&& let try vals : prog.params.Product := tryCast msg.vals
184+
&& let try vals : prog.params.Product := tryCast msg.contents.vals
171185
let res : MultiMethodResult multiId := prog |>.value vals
172186
let consumedUid (arg : multiId.ObjectArgNames) : Anoma.ObjectId := argsConsumedObjects arg |>.uid
173187
let mkObjectValue {classId : lab.ClassId} (arg : multiId.ObjectArgNames) (d : ObjectData classId) : ObjectValue := ⟨consumedUid arg, d⟩
@@ -228,7 +242,7 @@ private def logicFun
228242
| .multiMethodId multiId =>
229243
let try selves : multiId.Selves := multiId.ConsumedToSelves consumedObjectResources
230244
nMessages + multiId.numObjectArgs == (Logic.filterOutDummy args.consumed).length
231-
&& Label.MultiMethodId.SelvesToVector selves (fun o => o.uid) ≍? msg.recipients
245+
&& Label.MultiMethodId.SelvesToVector selves (fun o => o.uid) ≍? msg.contents.recipients
232246

233247
def logic
234248
{lab : Ecosystem.Label}

0 commit comments

Comments
 (0)