check.bend
bend-osdev-camellia@0.1.0.0 · 90 lines · 0 definitions
1# Camellia: RFC 3713's three vectors, both ways (the ciphertext, then the
2# plaintext decrypted back), and Camellia-128 through cbc's CBC over
3# 32 KB both ways.
4import Base
5import bend-osdev-bytes@0.1.1.0/bytes.bend as B
6import bend-osdev-mode-core@0.1.0.0/mode_core.bend as M
7import bend-osdev-cbc@0.1.0.0/cbc.bend as CB
8import bend-osdev-cipher-core@0.1.0.0/cipher_core.bend as L
9import bend-osdev-camellia@0.1.0.0/camellia.bend as C
10
11def b128.of(m: Maybe<&2, M.CmBlock>) -> M.CmBlock:
12 match m:
13 case None{}:
14 M.CmBlock.zero()
15 case Some{b}:
16 b
17
18def b128(o: B.Octets) -> M.CmBlock:
19 b128.of(M.CmBlock.of_octets(o))
20
21def key(~K: Data, r: Result<&2, &2, L.LcError, K>, d: K) -> K:
22 match r:
23 case Fail{e}:
24 d
25 case Done{k}:
26 k
27
28def both(~K: Data, ~enc: K -> M.CmBlock -> M.CmBlock, ~dec: K -> M.CmBlock -> M.CmBlock, +k: K, b: M.CmBlock) -> String:
29 +c = enc(k, b)
30 M.CmBlock.hex(c) ++ " " ++ M.CmBlock.hex(dec(k, c))
31
32def camellia(k: B.Octets, b: B.Octets) -> String:
33 both(~C.LcCamelliaKey, ~C.LcCamellia.encrypt, ~C.LcCamellia.decrypt, key(~C.LcCamelliaKey, C.LcCamellia.key(k), C.LcCamelliaKey{Nil{}}), b128(b))
34
35# n bytes, byte i = 7i + 3 (mod 256)
36def big.go(n: Nat, +i: U32, acc: List<&2, U32>) -> List<&2, U32>:
37 match n:
38 case 0n:
39 B.rev(acc)
40 case 1n+p:
41 big.go(p, U32.add(i, 1), Con{U32.and(255, U32.add(U32.mul(i, 7), 3)), acc})
42
43def big(n: Nat) -> B.Octets:
44 B.Octets.of_list(big.go(n, 0, Nil{}))
45
46def iv16() -> B.Octets:
47 B.Octets.of_list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
48
49def last16(r: Result<&2, &2, M.CmError, B.Octets>) -> String:
50 match r:
51 case Fail{e}:
52 "fail"
53 case Done{+o}:
54 B.Octets.hex(B.Octets.drop(Nat.sub(B.Octets.len(o), 16n), o))
55
56def verdict(b: Bool) -> String:
57 match b:
58 case True{}:
59 "ok"
60 case False{}:
61 "differs"
62
63def same(r: Result<&2, &2, M.CmError, B.Octets>, +m: B.Octets) -> String:
64 match r:
65 case Fail{e}:
66 "fail"
67 case Done{o}:
68 verdict(B.Octets.is_eq(o, m))
69
70def cbc128(~K: Data, ~enc: K -> M.CmBlock -> M.CmBlock, ~dec: K -> M.CmBlock -> M.CmBlock, +k: K, n: Nat) -> String:
71 +m = big(n)
72 +c = CB.Cbc.encrypt(~K, ~enc, k, iv16(), m)
73 last16(c) ++ " " ++ same(Result.bind(&2, &2, M.CmError, B.Octets, B.Octets, c, x => CB.Cbc.decrypt(~K, ~dec, k, iv16(), x)), m)
74
75def camellia_cbc(k: B.Octets, n: Nat) -> String:
76 cbc128(~C.LcCamelliaKey, ~C.LcCamellia.encrypt, ~C.LcCamellia.decrypt, key(~C.LcCamelliaKey, C.LcCamellia.key(k), C.LcCamelliaKey{Nil{}}), n)
77
78# BEGIN GENERATED by gen/vectors.py: check
79def main() -> IO(Unit):
80 do IO<Unit>:
81 IO.print(camellia(B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16]), B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16])))
82 IO.print(camellia(B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16, 0, 17, 34, 51, 68, 85, 102, 119]), B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16])))
83 IO.print(camellia(B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16, 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255]), B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16])))
84 IO.print(camellia_cbc(B.Octets.of_list([1, 35, 69, 103, 137, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16]), 32768n))
85
86#|67673138549669730857065648eabe43 0123456789abcdeffedcba9876543210
87#|b4993401b3e996f84ee5cee7d79b09b9 0123456789abcdeffedcba9876543210
88#|9acc237dff16d76c20ef7c919e3a7509 0123456789abcdeffedcba9876543210
89#|01fbbba61e8bb08562d59ae3b7e70881 ok
90# END GENERATED: check