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