proofs/crypto/aes/proof.bend
bend-collections-laws-crypto@1.0.0.0 · 231 lines · 7 definitions
1import Base
2import bend-collections-laws-crypto@1.0.0.0/proofs/lib/logic.bend as L
3import bend-collections-laws-crypto@1.0.0.0/src/crypto/aes/types.bend as T
4import bend-collections-laws-crypto@1.0.0.0/src/crypto/aes/aes.bend as A
5import bend-collections-laws-crypto@1.0.0.0/src/crypto/aes/gcm.bend as GI
6import bend-collections-laws-crypto@1.0.0.0/src/crypto/aesgcm.bend as GCM
7import bend-collections-laws-crypto@1.0.0.0/spec/crypto/aes/aes.bend as S
8import bend-collections-laws-crypto@1.0.0.0/spec/crypto/aes/gcm.bend as G
9import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/laws.bend as Laws
10import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/sbox.bend as SB
11import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/inverse.bend as INV
12import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/cipher.bend as C
13import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/gcm.bend as GP
14import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/aead.bend as AD
15import bend-collections-laws-crypto@1.0.0.0/proofs/crypto/aes/api.bend as API
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31def seal_nonce_bad(+sched: A.Schedule, +nonce: List<&2, U32>, +h: {Nat.is_eq(List.length(&2, U32, nonce), 12n) == False{} : Bool}, +aad: List<&2, U32>, +pt: List<&2, U32>) -> {GI.seal_nonce(sched, nonce, aad, pt) == None{} : Maybe<&2, List<&2, U32>>}:
32 match nonce:
33 case Nil{}:
34 {==}
35 case n0 <> Nil{}:
36 {==}
37 case n0 <> n1 <> Nil{}:
38 {==}
39 case n0 <> n1 <> n2 <> Nil{}:
40 {==}
41 case n0 <> n1 <> n2 <> n3 <> Nil{}:
42 {==}
43 case n0 <> n1 <> n2 <> n3 <> n4 <> Nil{}:
44 {==}
45 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> Nil{}:
46 {==}
47 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> Nil{}:
48 {==}
49 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> Nil{}:
50 {==}
51 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> Nil{}:
52 {==}
53 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> Nil{}:
54 {==}
55 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> Nil{}:
56 {==}
57 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> n11 <> Nil{}:
58 Empty.absurd({GI.seal_nonce(sched, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, pt) == None{} : Maybe<&2, List<&2, U32>>}, L.true_false(h))
59 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> n11 <> n12 <> rest:
60 {==}
61
62def open_nonce_bad(+sched: A.Schedule, +nonce: List<&2, U32>, +h: {Nat.is_eq(List.length(&2, U32, nonce), 12n) == False{} : Bool}, +aad: List<&2, U32>, +ct: List<&2, U32>) -> {GI.open_nonce(sched, nonce, aad, ct) == None{} : Maybe<&2, List<&2, U32>>}:
63 match nonce:
64 case Nil{}:
65 {==}
66 case n0 <> Nil{}:
67 {==}
68 case n0 <> n1 <> Nil{}:
69 {==}
70 case n0 <> n1 <> n2 <> Nil{}:
71 {==}
72 case n0 <> n1 <> n2 <> n3 <> Nil{}:
73 {==}
74 case n0 <> n1 <> n2 <> n3 <> n4 <> Nil{}:
75 {==}
76 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> Nil{}:
77 {==}
78 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> Nil{}:
79 {==}
80 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> Nil{}:
81 {==}
82 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> Nil{}:
83 {==}
84 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> Nil{}:
85 {==}
86 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> Nil{}:
87 {==}
88 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> n11 <> Nil{}:
89 Empty.absurd({GI.open_nonce(sched, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, ct) == None{} : Maybe<&2, List<&2, U32>>}, L.true_false(h))
90 case n0 <> n1 <> n2 <> n3 <> n4 <> n5 <> n6 <> n7 <> n8 <> n9 <> n10 <> n11 <> n12 <> rest:
91 {==}
92
93def seal_key_bad(+m: Maybe<&2, A.Schedule>, +nonce: List<&2, U32>, +h: {Nat.is_eq(List.length(&2, U32, nonce), 12n) == False{} : Bool}, +aad: List<&2, U32>, +pt: List<&2, U32>) -> {GI.seal_key(m, nonce, aad, pt) == None{} : Maybe<&2, List<&2, U32>>}:
94 match m:
95 case None{}:
96 {==}
97 case Some{s}:
98 seal_nonce_bad(s, nonce, h, aad, pt)
99
100def open_key_bad(+m: Maybe<&2, A.Schedule>, +nonce: List<&2, U32>, +h: {Nat.is_eq(List.length(&2, U32, nonce), 12n) == False{} : Bool}, +aad: List<&2, U32>, +ct: List<&2, U32>) -> {GI.open_key(m, nonce, aad, ct) == None{} : Maybe<&2, List<&2, U32>>}:
101 match m:
102 case None{}:
103 {==}
104 case Some{s}:
105 open_nonce_bad(s, nonce, h, aad, ct)
106
107
108def valid_of(+key: List<&2, U32>, +w: Nat, +h: {List.length(&2, U32, key) == w : Nat}, +v: {A.valid_length(w) == True{} : Bool}) -> {A.valid_length(List.length(&2, U32, key)) == True{} : Bool}:
109 %Equal.sym(Nat, List.length(&2, U32, key), w, h) : {A.valid_length(_) == True{} : Bool}
110 v
111
112def Laws.Sbox.value(x):
113 SB.sbox_ok(x)
114
115def Laws.Inverse.unit(x, h):
116 INV.inverse_unit(x, h)
117
118def Laws.Inverse.zero():
119 INV.inverse_zero()
120
121def Laws.Cipher.value(nk, nr, key, s):
122 C.encrypt_ok(nk, nr, key, s)
123
124def Laws.Block.value(key, h, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15):
125 %Equal.sym(Bool, A.valid_length(List.length(&2, U32, key)), True{}, h) : {Laws.block_with(A.schedule_if(_, Nat.div(List.length(&2, U32, key), 4n), key), [b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15]) == Some{S.bytes_of(S.aes(key, S.state_of([b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15])))} : Maybe<&2, List<&2, U32>>}
126 %C.encrypt_ok(S.nk(key), S.nr(key), key, T.S{T.W{b0, b1, b2, b3}, T.W{b4, b5, b6, b7}, T.W{b8, b9, b10, b11}, T.W{b12, b13, b14, b15}}) : {Laws.block_with(A.schedule_if(True{}, Nat.div(List.length(&2, U32, key), 4n), key), [b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15]) == Some{S.bytes_of(_)} : Maybe<&2, List<&2, U32>>}
127 %GP.bytes_of_ok(A.encrypt(S.nk(key), S.nr(key), key, T.S{T.W{b0, b1, b2, b3}, T.W{b4, b5, b6, b7}, T.W{b8, b9, b10, b11}, T.W{b12, b13, b14, b15}})) : {Laws.block_with(A.schedule_if(True{}, Nat.div(List.length(&2, U32, key), 4n), key), [b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15]) == Some{_} : Maybe<&2, List<&2, U32>>}
128 {==}
129
130def Laws.Block.aes128(key, h):
131 %Equal.sym(Nat, List.length(&2, U32, key), 16n, h) : {Nat.div(_, 4n) == 4n : Nat}
132 {==}
133
134def Laws.Block.aes192(key, h):
135 %Equal.sym(Nat, List.length(&2, U32, key), 24n, h) : {Nat.div(_, 4n) == 6n : Nat}
136 {==}
137
138def Laws.Block.aes256(key, h):
139 %Equal.sym(Nat, List.length(&2, U32, key), 32n, h) : {Nat.div(_, 4n) == 8n : Nat}
140 {==}
141
142def Laws.Gcm.seal(nk, nr, key, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt):
143 GP.seal_ok(nk, nr, key, T.W{n0, n1, n2, n3}, T.W{n4, n5, n6, n7}, T.W{n8, n9, n10, n11}, aad, pt)
144
145def Laws.Gcm.open(nk, nr, key, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, input):
146 GP.open_ok(nk, nr, key, T.W{n0, n1, n2, n3}, T.W{n4, n5, n6, n7}, T.W{n8, n9, n10, n11}, aad, input)
147
148def Laws.Aead.roundtrip(nk, nr, key, iv, aad, pt):
149 AD.roundtrip(nk, nr, key, iv, aad, pt)
150
151def Laws.Aead.forgery(nk, nr, key, iv, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne):
152 AD.forgery(nk, nr, key, iv, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne)
153
154def Laws.Api128.encrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt):
155 API.aes128_encrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt)
156
157def Laws.Api128.decrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, ct):
158 API.aes128_decrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, ct)
159
160law open128_same:
161 for +key: List<&2, U32>
162 for +nonce: List<&2, U32>
163 for +aad: List<&2, U32>
164 for +m: Maybe<&2, List<&2, U32>>
165 {Laws.open128(key, nonce, aad, m) == API.open128(key, nonce, aad, m) : Maybe<&2, List<&2, U32>>}
166
167def open128_same(key, nonce, aad, m):
168 match m:
169 case None{}: {==}
170 case Some{c}: {==}
171
172def Laws.Api128.roundtrip(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt):
173 +m = GCM.aes128_gcm_encrypt(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, pt)
174 Equal.trans(Maybe<&2, List<&2, U32>>, Laws.open128(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), API.open128(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), Some{pt}, open128_same(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), API.aes128_roundtrip(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt))
175
176def Laws.Api128.forgery(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne):
177 API.aes128_forgery(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne)
178
179def Laws.Api128.bad_key(key, h, nonce, aad, pt):
180 %Equal.sym(Bool, Nat.is_eq(List.length(&2, U32, key), 16n), False{}, h) : {GI.seal_key(GI.schedule_if(_, key), nonce, aad, pt) == None{} : Maybe<&2, List<&2, U32>>}
181 {==}
182
183def Laws.Api128.bad_key_open(key, h, nonce, aad, ct):
184 %Equal.sym(Bool, Nat.is_eq(List.length(&2, U32, key), 16n), False{}, h) : {GI.open_key(GI.schedule_if(_, key), nonce, aad, ct) == None{} : Maybe<&2, List<&2, U32>>}
185 {==}
186
187def Laws.Api128.bad_nonce(key, nonce, h, aad, pt):
188 seal_key_bad(GI.schedule_of(16n, key), nonce, h, aad, pt)
189
190def Laws.Api128.bad_nonce_open(key, nonce, h, aad, ct):
191 open_key_bad(GI.schedule_of(16n, key), nonce, h, aad, ct)
192
193def Laws.Api256.encrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt):
194 API.aes256_encrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt)
195
196def Laws.Api256.decrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, ct):
197 API.aes256_decrypt(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, ct)
198
199law open256_same:
200 for +key: List<&2, U32>
201 for +nonce: List<&2, U32>
202 for +aad: List<&2, U32>
203 for +m: Maybe<&2, List<&2, U32>>
204 {Laws.open256(key, nonce, aad, m) == API.open256(key, nonce, aad, m) : Maybe<&2, List<&2, U32>>}
205
206def open256_same(key, nonce, aad, m):
207 match m:
208 case None{}: {==}
209 case Some{c}: {==}
210
211def Laws.Api256.roundtrip(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt):
212 +m = GCM.aes256_gcm_encrypt(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, pt)
213 Equal.trans(Maybe<&2, List<&2, U32>>, Laws.open256(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), API.open256(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), Some{pt}, open256_same(key, [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11], aad, m), API.aes256_roundtrip(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, pt))
214
215def Laws.Api256.forgery(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne):
216 API.aes256_forgery(key, h, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, aad, c, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, ne)
217
218def Laws.Api256.bad_key(key, h, nonce, aad, pt):
219 %Equal.sym(Bool, Nat.is_eq(List.length(&2, U32, key), 32n), False{}, h) : {GI.seal_key(GI.schedule_if(_, key), nonce, aad, pt) == None{} : Maybe<&2, List<&2, U32>>}
220 {==}
221
222def Laws.Api256.bad_key_open(key, h, nonce, aad, ct):
223 %Equal.sym(Bool, Nat.is_eq(List.length(&2, U32, key), 32n), False{}, h) : {GI.open_key(GI.schedule_if(_, key), nonce, aad, ct) == None{} : Maybe<&2, List<&2, U32>>}
224 {==}
225
226def Laws.Api256.bad_nonce(key, nonce, h, aad, pt):
227 seal_key_bad(GI.schedule_of(32n, key), nonce, h, aad, pt)
228
229def Laws.Api256.bad_nonce_open(key, nonce, h, aad, ct):
230 open_key_bad(GI.schedule_of(32n, key), nonce, h, aad, ct)
231