check.bend

bend-osdev-cipher-core@0.1.0.0 · 110 lines · 15 definitions

1# cipher-core on its own: a block's hex and byte forms, XOR, tables, the
2# word helpers on bits against their native forms, Feistel rounds over a toy
3# round function, and the 64-bit modes over a toy cipher (XOR with the key
4# block: not a cipher, but enough to show the modes chain and undo
5# themselves), with their refusals. The ciphers' own packages test the
6# modes over real ciphers (des: against Python's cryptography).
7import Base
8import bend-osdev-bytes@0.1.1.0/bytes.bend as B
9import bend-osdev-cipher-core@0.1.0.0/cipher_core.bend as L
10import bend-osdev-cipher-core@0.1.0.0/modes64.bend as X
11
12def err(e: L.LcError) -> String:
13  match e:
14    case L.LcBadKeyLength{n}:
15      "bad key " ++ Nat.show(n)
16    case L.LcBadIvLength{n}:
17      "bad iv " ++ Nat.show(n)
18    case L.LcNotBlockMultiple{n}:
19      "not whole blocks " ++ Nat.show(n)
20
21def show(r: Result<&2, &2, L.LcError, B.Octets>) -> String:
22  match r:
23    case Fail{e}:
24      err(e)
25    case Done{o}:
26      B.Octets.hex(o)
27
28def show_blocks(r: Result<&2, &2, L.LcError, List<&2, L.LcBlock64>>) -> String:
29  match r:
30    case Fail{e}:
31      err(e)
32    case Done{bs}:
33      B.Octets.hex(X.Lc64.octets_of(bs))
34
35def show_some(m: Maybe<&2, L.LcBlock64>) -> String:
36  match m:
37    case None{}:
38      "none"
39    case Some{b}:
40      L.LcBlock64.hex(b)
41
42# a word as hex, through the block's hex form
43def word(x: U32) -> String:
44  L.LcBlock64.hex(L.LcBlock64{0, x})
45
46# the toy cipher: XOR with the key block, its own inverse
47def toy(k: L.LcBlock64, b: L.LcBlock64) -> L.LcBlock64:
48  L.LcBlock64.xor(k, b)
49
50def toy_key() -> L.LcBlock64:
51  L.LcBlock64{19088743, 2309737967}
52
53# a toy round function for the Feistel rounds: x + k, then rotated by 7
54def toy_f(k: U32, x: U32) -> U32:
55  L.lc.rotl(U32.add(x, k), 7n)
56
57def msg() -> B.Octets:
58  B.Octets.of_list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
59
60def iv() -> B.Octets:
61  B.Octets.of_list([240, 241, 242, 243, 244, 245, 246, 247])
62
63def ecb(m: B.Octets) -> String:
64  +c = X.Lc64.ecb_encrypt(~L.LcBlock64, ~toy, toy_key(), m)
65  show(c) ++ " " ++ show(Result.bind(&2, &2, L.LcError, B.Octets, B.Octets, c, x => X.Lc64.ecb_decrypt(~L.LcBlock64, ~toy, toy_key(), x)))
66
67def cbc(+v: B.Octets, m: B.Octets) -> String:
68  +c = X.Lc64.cbc_encrypt(~L.LcBlock64, ~toy, toy_key(), v, m)
69  show(c) ++ " " ++ show(Result.bind(&2, &2, L.LcError, B.Octets, B.Octets, c, x => X.Lc64.cbc_decrypt(~L.LcBlock64, ~toy, toy_key(), v, x)))
70
71def feistel(+b: L.LcBlock64) -> String:
72  +ks = {[1, 2, 3, 4, 5, 6, 7, 8] : List<&2, U32>}
73  +c = L.lc.fe.run(~U32, ~toy_f, ks, b)
74  L.LcBlock64.hex(c) ++ " " ++ L.LcBlock64.hex(L.lc.fe.unrun(~U32, ~toy_f, ks, c))
75
76def tab() -> String:
77  +t = L.lc.tab(2n, [10, 20, 30, 40])
78  word(L.lc.tab.get(2n, t, 2)) ++ " " ++ word(L.lc.tab.get(2n, L.lc.tab.set(2n, t, 1, 99), 1)) ++ " " ++ word(L.lc.tab.get(2n, t, 1))
79
80def main() -> IO(Unit):
81  do IO<Unit>:
82    IO.print(L.LcBlock64.hex(toy_key()))
83    IO.print(B.Octets.hex(L.LcBlock64.to_octets(toy_key())))
84    IO.print(show_some(L.LcBlock64.of_octets(L.LcBlock64.to_octets(toy_key()))))
85    IO.print(show_some(L.LcBlock64.of_octets(B.Octets.zeros(7n))))
86    IO.print(L.LcBlock64.hex(L.LcBlock64.xor(toy_key(), L.LcBlock64{4294967295, 0})))
87    IO.print(word(L.lc.bswap.bits(16909060)) ++ " " ++ word(L.lc.rotl1.bits(2147483649)) ++ " " ++ word(L.lc.rotl(2147483649, 1n)) ++ " " ++ word(L.lc.rotl31.bits(3)))
88    IO.print(word(L.lc.be(1, 2, 3, 4)) ++ " " ++ word(L.lc.le(1, 2, 3, 4)) ++ " " ++ word(L.lc.byte(16909060, 3n)))
89    IO.print(tab())
90    IO.print(feistel(L.LcBlock64{305419896, 2596069104}))
91    IO.print(show_blocks(X.Lc64.blocks_of(msg())))
92    IO.print(ecb(msg()))
93    IO.print(cbc(iv(), msg()))
94    IO.print(cbc(B.Octets.zeros(7n), msg()))
95    IO.print(ecb(B.Octets.zeros(9n)))
96
97#|0123456789abcdef
98#|0123456789abcdef
99#|0123456789abcdef
100#|none
101#|fedcba9889abcdef
102#|0000000004030201 0000000000000003 0000000000000003 0000000080000001
103#|0000000001020304 0000000004030201 0000000000000001
104#|000000000000001e 0000000000000063 0000000000000014
105#|3eefc45f6fc66333 123456789abcdef0
106#|000102030405060708090a0b0c0d0e0f1011121314151617
107#|012247648daecbe8092a4f6c85a6c3e0113257749dbedbf8 000102030405060708090a0b0c0d0e0f1011121314151617
108#|f1d3b597795b3d1ff8f9fafbfcfdfeffe9cbad8f61432507 000102030405060708090a0b0c0d0e0f1011121314151617
109#|bad iv 7 bad iv 7
110#|not whole blocks 9 not whole blocks 9