sm4.bend
bend-osdev-legacy-ciphers@0.1.0.0 · 143 lines · 20 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14import Base
15import bend-osdev-bytes@0.1.0.0/bytes.bend as B
16import bend-osdev-cipher-modes@0.1.0.0/cipher_modes.bend as M
17import bend-osdev-legacy-ciphers@0.1.0.0/legacy_ciphers.bend as L
18
19
20def sm4.sbox.list() -> List<&2, U32>:
21 [214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5,
22 43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153,
23 156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98,
24 228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166,
25 71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168,
26 104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53,
27 30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135,
28 212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158,
29 234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161,
30 224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227,
31 29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111,
32 213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81,
33 141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216,
34 10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176,
35 137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132,
36 24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72]
37
38def sm4.sbox() -> L.LcTab:
39 L.lc.tab(8n, sm4.sbox.list())
40
41def sm4.s(+tab: L.LcTab, +a: U32, n: Nat) -> U32:
42 L.lc.tab.get(8n, tab, L.lc.byte(a, n))
43
44
45def sm4.tau(+tab: L.LcTab, +a: U32) -> U32:
46 L.lc.be(sm4.s(tab, a, 3n), sm4.s(tab, a, 2n), sm4.s(tab, a, 1n), sm4.s(tab, a, 0n))
47
48
49def sm4.t(+tab: L.LcTab, x: U32) -> U32:
50 +b = sm4.tau(tab, x)
51 U32.xor(U32.xor(U32.xor(b, L.lc.rotl(b, 2n)), U32.xor(L.lc.rotl(b, 10n), L.lc.rotl(b, 18n))), L.lc.rotl(b, 24n))
52
53
54def sm4.t2(+tab: L.LcTab, x: U32) -> U32:
55 +b = sm4.tau(tab, x)
56 U32.xor(U32.xor(b, L.lc.rotl(b, 13n)), L.lc.rotl(b, 23n))
57
58
59
60def sm4.step(+tab: L.LcTab, rk: U32, s: M.CmBlock) -> M.CmBlock:
61 match s:
62 case M.CmBlock{x0, +x1, +x2, +x3}:
63 M.CmBlock{x1, x2, x3, U32.xor(x0, sm4.t(tab, U32.xor(U32.xor(U32.xor(x1, x2), x3), rk)))}
64
65
66def sm4.unstep(+tab: L.LcTab, rk: U32, s: M.CmBlock) -> M.CmBlock:
67 match s:
68 case M.CmBlock{+y0, +y1, +y2, y3}:
69 M.CmBlock{U32.xor(y3, sm4.t(tab, U32.xor(U32.xor(U32.xor(y0, y1), y2), rk))), y0, y1, y2}
70
71def sm4.rounds(+tab: L.LcTab, rks: List<&2, U32>, s: M.CmBlock) -> M.CmBlock:
72 match rks:
73 case Nil{}:
74 s
75 case Con{k, t}:
76 sm4.rounds(tab, t, sm4.step(tab, k, s))
77
78def sm4.unrounds(+tab: L.LcTab, rks: List<&2, U32>, s: M.CmBlock) -> M.CmBlock:
79 match rks:
80 case Nil{}:
81 s
82 case Con{k, t}:
83 sm4.unstep(tab, k, sm4.unrounds(tab, t, s))
84
85
86def sm4.rev(s: M.CmBlock) -> M.CmBlock:
87 match s:
88 case M.CmBlock{a, b, c, d}:
89 M.CmBlock{d, c, b, a}
90
91
92
93
94def sm4.fk(n: Nat) -> U32:
95 L.lc.at([2746333894, 1453994832, 1736282519, 2993693404], n)
96
97def sm4.ck(+i: U32) -> U32:
98 +b = U32.mul(i, 28)
99 L.lc.be(b, U32.add(b, 7), U32.add(b, 14), U32.add(b, 21))
100
101
102
103def sm4.schedule(n: Nat, +tab: L.LcTab, +i: U32, k0: U32, +k1: U32, +k2: U32, +k3: U32) -> List<&2, U32>:
104 match n:
105 case 0n:
106 Nil{}
107 case 1n+p:
108 +k4 = U32.xor(k0, sm4.t2(tab, U32.xor(U32.xor(U32.xor(k1, k2), k3), sm4.ck(i))))
109 Con{k4, sm4.schedule(p, tab, U32.add(i, 1), k1, k2, k3, k4)}
110
111
112
113type LcSm4Key is Data:
114 LcSm4Key{tab: L.LcTab, rks: List<&2, U32>}
115
116def sm4.mk(+xs: List<&2, U32>, +i: Nat) -> U32:
117 +j = Nat.mul(4n, i)
118 U32.xor(L.lc.be(L.lc.at(xs, j), L.lc.at(xs, Nat.add(j, 1n)), L.lc.at(xs, Nat.add(j, 2n)), L.lc.at(xs, Nat.add(j, 3n))), sm4.fk(i))
119
120def sm4.key.pick(ok: Bool, +xs: List<&2, U32>) -> Result<&2, &2, L.LcError, LcSm4Key>:
121 match ok:
122 case True{}:
123 +tab = sm4.sbox()
124 Done{LcSm4Key{tab, sm4.schedule(32n, tab, 0, sm4.mk(xs, 0n), sm4.mk(xs, 1n), sm4.mk(xs, 2n), sm4.mk(xs, 3n))}}
125 case False{}:
126 Fail{L.LcBadKeyLength{B.len(xs)}}
127
128
129
130
131def LcSm4.key(o: B.Octets) -> Result<&2, &2, L.LcError, LcSm4Key>:
132 +xs = B.Octets.to_list(o)
133 sm4.key.pick(Nat.is_eq(B.len(xs), 16n), xs)
134
135def LcSm4.encrypt(k: LcSm4Key, b: M.CmBlock) -> M.CmBlock:
136 match k:
137 case LcSm4Key{+tab, rks}:
138 sm4.rev(sm4.rounds(tab, rks, b))
139
140def LcSm4.decrypt(k: LcSm4Key, b: M.CmBlock) -> M.CmBlock:
141 match k:
142 case LcSm4Key{+tab, rks}:
143 sm4.unrounds(tab, rks, sm4.rev(b))