cast6.bend
bend-osdev-legacy-ciphers@0.1.0.0 · 193 lines · 25 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import Base
23import bend-osdev-bytes@0.1.0.0/bytes.bend as B
24import bend-osdev-cipher-modes@0.1.0.0/cipher_modes.bend as M
25import bend-osdev-legacy-ciphers@0.1.0.0/legacy_ciphers.bend as L
26import bend-osdev-legacy-ciphers@0.1.0.0/cast5.bend as C5
27
28
29type LcCast6Ks is Data:
30 LcCast6Ks{m0: U32, m1: U32, m2: U32, m3: U32, r0: U32, r1: U32, r2: U32, r3: U32, t: C5.LcCastTabs}
31
32
33def c6.sc(k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
34 match k:
35 case LcCast6Ks{m0, m1, m2, m3, r0, r1, r2, r3, t}:
36 match s:
37 case M.CmBlock{a, b, c, +d}:
38 M.CmBlock{a, b, U32.xor(c, C5.cast.f(C5.LcCastF1{}, t, d, m0, r0)), d}
39
40def c6.sb(k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
41 match k:
42 case LcCast6Ks{m0, m1, m2, m3, r0, r1, r2, r3, t}:
43 match s:
44 case M.CmBlock{a, b, +c, d}:
45 M.CmBlock{a, U32.xor(b, C5.cast.f(C5.LcCastF2{}, t, c, m1, r1)), c, d}
46
47def c6.sa(k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
48 match k:
49 case LcCast6Ks{m0, m1, m2, m3, r0, r1, r2, r3, t}:
50 match s:
51 case M.CmBlock{a, +b, c, d}:
52 M.CmBlock{U32.xor(a, C5.cast.f(C5.LcCastF3{}, t, b, m2, r2)), b, c, d}
53
54def c6.sd(k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
55 match k:
56 case LcCast6Ks{m0, m1, m2, m3, r0, r1, r2, r3, t}:
57 match s:
58 case M.CmBlock{+a, b, c, d}:
59 M.CmBlock{a, b, c, U32.xor(d, C5.cast.f(C5.LcCastF1{}, t, a, m3, r3))}
60
61
62def c6.q(+k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
63 c6.sd(k, c6.sa(k, c6.sb(k, c6.sc(k, s))))
64
65def c6.qbar(+k: LcCast6Ks, s: M.CmBlock) -> M.CmBlock:
66 c6.sc(k, c6.sb(k, c6.sa(k, c6.sd(k, s))))
67
68
69type LcCast6Op is Data:
70 LcCast6Op{fwd: Bool, k: LcCast6Ks}
71
72def c6.op(o: LcCast6Op, s: M.CmBlock) -> M.CmBlock:
73 match o:
74 case LcCast6Op{fwd, k}:
75 match fwd:
76 case True{}:
77 c6.q(k, s)
78 case False{}:
79 c6.qbar(k, s)
80
81def c6.unop(o: LcCast6Op, s: M.CmBlock) -> M.CmBlock:
82 match o:
83 case LcCast6Op{fwd, k}:
84 match fwd:
85 case True{}:
86 c6.qbar(k, s)
87 case False{}:
88 c6.q(k, s)
89
90def c6.run(os: List<&2, LcCast6Op>, s: M.CmBlock) -> M.CmBlock:
91 match os:
92 case Nil{}:
93 s
94 case Con{o, t}:
95 c6.run(t, c6.op(o, s))
96
97def c6.unrun(os: List<&2, LcCast6Op>, s: M.CmBlock) -> M.CmBlock:
98 match os:
99 case Nil{}:
100 s
101 case Con{o, t}:
102 c6.unop(o, c6.unrun(t, s))
103
104
105
106
107def c6.set(xs: List<&2, U32>, i: Nat, v: U32) -> List<&2, U32>:
108 match xs:
109 case Nil{}:
110 Nil{}
111 case Con{x, t}:
112 match i:
113 case 0n:
114 Con{v, t}
115 case 1n+j:
116 Con{x, c6.set(t, j, v)}
117
118
119type LcCast6Kst is Data:
120 LcCast6Kst{k: List<&2, U32>, cm: U32, cr: U32}
121
122
123def c6.w(+t: C5.LcCastTabs, ty: C5.LcCastTy, +dst: Nat, src: Nat, st: LcCast6Kst) -> LcCast6Kst:
124 match st:
125 case LcCast6Kst{+k, +cm, +cr}:
126 LcCast6Kst{c6.set(k, dst, U32.xor(L.lc.at(k, dst), C5.cast.f(ty, t, L.lc.at(k, src), cm, cr))), U32.add(cm, 1859775393), U32.and(31, U32.add(cr, 17))}
127
128
129def c6.octave(+t: C5.LcCastTabs, st: LcCast6Kst) -> LcCast6Kst:
130 +s1 = c6.w(t, C5.LcCastF1{}, 6n, 7n, st)
131 +s2 = c6.w(t, C5.LcCastF2{}, 5n, 6n, s1)
132 +s3 = c6.w(t, C5.LcCastF3{}, 4n, 5n, s2)
133 +s4 = c6.w(t, C5.LcCastF1{}, 3n, 4n, s3)
134 +s5 = c6.w(t, C5.LcCastF2{}, 2n, 3n, s4)
135 +s6 = c6.w(t, C5.LcCastF3{}, 1n, 2n, s5)
136 +s7 = c6.w(t, C5.LcCastF1{}, 0n, 1n, s6)
137 c6.w(t, C5.LcCastF2{}, 7n, 0n, s7)
138
139
140def c6.ks(+t: C5.LcCastTabs, +k: List<&2, U32>) -> LcCast6Ks:
141 LcCast6Ks{L.lc.at(k, 7n), L.lc.at(k, 5n), L.lc.at(k, 3n), L.lc.at(k, 1n), U32.and(31, L.lc.at(k, 0n)), U32.and(31, L.lc.at(k, 2n)), U32.and(31, L.lc.at(k, 4n)), U32.and(31, L.lc.at(k, 6n)), t}
142
143
144def c6.ks.of(+t: C5.LcCastTabs, st: LcCast6Kst) -> LcCast6Ks:
145 match st:
146 case LcCast6Kst{+k, cm, cr}:
147 c6.ks(t, k)
148
149
150def c6.ops(n: Nat, +i: Nat, +t: C5.LcCastTabs, st: LcCast6Kst) -> List<&2, LcCast6Op>:
151 match n:
152 case 0n:
153 Nil{}
154 case 1n+p:
155 +st2 = c6.octave(t, c6.octave(t, st))
156 Con{LcCast6Op{Nat.is_lt(i, 6n), c6.ks.of(t, st2)}, c6.ops(p, Nat.add(i, 1n), t, st2)}
157
158
159type LcCast6Key is Data:
160 LcCast6Key{ops: List<&2, LcCast6Op>}
161
162
163def c6.words(xs: List<&2, U32>) -> List<&2, U32>:
164 match xs:
165 case Con{a, Con{b, Con{c, Con{d, t}}}}:
166 Con{L.lc.be(a, b, c, d), c6.words(t)}
167 case _:
168 Nil{}
169
170def c6.key.pick(ok: Bool, +n: Nat, +xs: List<&2, U32>) -> Result<&2, &2, L.LcError, LcCast6Key>:
171 match ok:
172 case True{}:
173 Done{LcCast6Key{c6.ops(12n, 0n, C5.cast.tables(), LcCast6Kst{c6.words(B.append(xs, B.zeros(Nat.sub(32n, n)))), 1518500249, 19})}}
174 case False{}:
175 Fail{L.LcBadKeyLength{n}}
176
177
178
179
180def LcCast6.key(o: B.Octets) -> Result<&2, &2, L.LcError, LcCast6Key>:
181 +xs = B.Octets.to_list(o)
182 +n = B.len(xs)
183 c6.key.pick(Bool.and(Bool.and(Nat.is_le(16n, n), Nat.is_le(n, 32n)), Nat.is_eq(Nat.mod(n, 4n), 0n)), n, xs)
184
185def LcCast6.encrypt(k: LcCast6Key, b: M.CmBlock) -> M.CmBlock:
186 match k:
187 case LcCast6Key{ops}:
188 c6.run(ops, b)
189
190def LcCast6.decrypt(k: LcCast6Key, b: M.CmBlock) -> M.CmBlock:
191 match k:
192 case LcCast6Key{ops}:
193 c6.unrun(ops, b)