cryptol/examples/contrib/MISTY1.cry

246 lines
10 KiB
Plaintext

/*
* Cryptol spec of the MISTY1 cipher. Based on RFC 2994, available at
* https://tools.ietf.org/rfc/rfc2994.txt
*
* Author: Adrian Herrera
*/
module MISTY1 where
//
// Key scheduling part
//
keySchedule : [16][8] -> [32][16]
keySchedule K = EK_1 # EK_2 # EK_3 # EK_4
where EK_1 = split (join K)
EK_2 = [ FI ek_1 ek_1_shifted
| ek_1 <- EK_1
| ek_1_shifted <- EK_1 <<< 1
]
EK_3 = [extend (drop`{7} ek_2) | ek_2 <- EK_2]
EK_4 = [extend (take`{7} ek_2) | ek_2 <- EK_2]
//
// Data randomizing part
//
FO : [32] -> [8] -> [32][16] -> [32]
FO FO_IN k EK = (FO_OUT ! 0).1 # (FO_OUT ! 0).0
where FO_OUT = [(take FO_IN, drop FO_IN)] # [ f t0 t1
| f <- funcs
| (t0, t1) <- FO_OUT
]
// t0, t1 as 16-bit integers
funcs : [_]([16] -> [16] -> ([16], [16]))
funcs = [\t0 t1 -> (t0 ^ (EK @ k), t1),
\t0 t1 -> (FI t0 (EK @ ((k + 5) % 8 + 8)), t1),
\t0 t1 -> (t0 ^ t1, t1),
\t0 t1 -> (t0, t1 ^ (EK @ ((k + 2) % 8))),
\t0 t1 -> (t0, FI t1 (EK @ ((k + 1) % 8 + 8))),
\t0 t1 -> (t0, t1 ^ t0),
\t0 t1 -> (t0 ^ EK @ ((k + 7) % 8), t1),
\t0 t1 -> (FI t0 (EK @ ((k + 3) % 8 + 8)), t1),
\t0 t1 -> (t0 ^ t1, t1),
\t0 t1 -> (t0, t1 ^ EK @ ((k + 4) % 8))
]
FI : [16] -> [16] -> [16]
FI FI_IN FI_KEY = (FI_OUT ! 0).1 # (FI_OUT ! 0).0
where FI_OUT = [(take FI_IN, drop FI_IN)] # [ f d9 d7
| f <- funcs
| (d9, d7) <- FI_OUT
]
// d9 as 9-bit integer
// d7 as 7-bit integer
funcs : [_]([9] -> [7] -> ([9], [7]))
funcs = [\d9 d7 -> ((S9 @ d9) ^ (extend d7), d7),
\d9 d7 -> (d9, drop (extend (S7 @ d7) ^ d9)),
\d9 d7 -> (d9, d7 ^ drop (FI_KEY >> 9)),
\d9 d7 -> (d9 ^ drop FI_KEY, d7),
\d9 d7 -> ((S9 @ d9) ^ (extend d7), d7)
]
S7 : [_][7]
S7 = [27, 50, 51, 90, 59, 16, 23, 84, 91, 26, 114, 115, 107,
44, 102, 73, 31, 36, 19, 108, 55, 46, 63, 74, 93, 15,
64, 86, 37, 81, 28, 4, 11, 70, 32, 13, 123, 53, 68,
66, 43, 30, 65, 20, 75, 121, 21, 111, 14, 85, 9, 54,
116, 12, 103, 83, 40, 10, 126, 56, 2, 7, 96, 41, 25,
18, 101, 47, 48, 57, 8, 104, 95, 120, 42, 76, 100, 69,
117, 61, 89, 72, 3, 87, 124, 79, 98, 60, 29, 33, 94,
39, 106, 112, 77, 58, 1, 109, 110, 99, 24, 119, 35, 5,
38, 118, 0, 49, 45, 122, 127, 97, 80, 34, 17, 6, 71,
22, 82, 78, 113, 62, 105, 67, 52, 92, 88, 125]
S9 : [_][9]
S9 = [451, 203, 339, 415, 483, 233, 251, 53, 385, 185, 279, 491, 307,
9, 45, 211, 199, 330, 55, 126, 235, 356, 403, 472, 163, 286,
85, 44, 29, 418, 355, 280, 331, 338, 466, 15, 43, 48, 314,
229, 273, 312, 398, 99, 227, 200, 500, 27, 1, 157, 248, 416,
365, 499, 28, 326, 125, 209, 130, 490, 387, 301, 244, 414, 467,
221, 482, 296, 480, 236, 89, 145, 17, 303, 38, 220, 176, 396,
271, 503, 231, 364, 182, 249, 216, 337, 257, 332, 259, 184, 340,
299, 430, 23, 113, 12, 71, 88, 127, 420, 308, 297, 132, 349,
413, 434, 419, 72, 124, 81, 458, 35, 317, 423, 357, 59, 66,
218, 402, 206, 193, 107, 159, 497, 300, 388, 250, 406, 481, 361,
381, 49, 384, 266, 148, 474, 390, 318, 284, 96, 373, 463, 103,
281, 101, 104, 153, 336, 8, 7, 380, 183, 36, 25, 222, 295,
219, 228, 425, 82, 265, 144, 412, 449, 40, 435, 309, 362, 374,
223, 485, 392, 197, 366, 478, 433, 195, 479, 54, 238, 494, 240,
147, 73, 154, 438, 105, 129, 293, 11, 94, 180, 329, 455, 372,
62, 315, 439, 142, 454, 174, 16, 149, 495, 78, 242, 509, 133,
253, 246, 160, 367, 131, 138, 342, 155, 316, 263, 359, 152, 464,
489, 3, 510, 189, 290, 137, 210, 399, 18, 51, 106, 322, 237,
368, 283, 226, 335, 344, 305, 327, 93, 275, 461, 121, 353, 421,
377, 158, 436, 204, 34, 306, 26, 232, 4, 391, 493, 407, 57,
447, 471, 39, 395, 198, 156, 208, 334, 108, 52, 498, 110, 202,
37, 186, 401, 254, 19, 262, 47, 429, 370, 475, 192, 267, 470,
245, 492, 269, 118, 276, 427, 117, 268, 484, 345, 84, 287, 75,
196, 446, 247, 41, 164, 14, 496, 119, 77, 378, 134, 139, 179,
369, 191, 270, 260, 151, 347, 352, 360, 215, 187, 102, 462, 252,
146, 453, 111, 22, 74, 161, 313, 175, 241, 400, 10, 426, 323,
379, 86, 397, 358, 212, 507, 333, 404, 410, 135, 504, 291, 167,
440, 321, 60, 505, 320, 42, 341, 282, 417, 408, 213, 294, 431,
97, 302, 343, 476, 114, 394, 170, 150, 277, 239, 69, 123, 141,
325, 83, 95, 376, 178, 46, 32, 469, 63, 457, 487, 428, 68,
56, 20, 177, 363, 171, 181, 90, 386, 456, 468, 24, 375, 100,
207, 109, 256, 409, 304, 346, 5, 288, 443, 445, 224, 79, 214,
319, 452, 298, 21, 6, 255, 411, 166, 67, 136, 80, 351, 488,
289, 115, 382, 188, 194, 201, 371, 393, 501, 116, 460, 486, 424,
405, 31, 65, 13, 442, 50, 61, 465, 128, 168, 87, 441, 354,
328, 217, 261, 98, 122, 33, 511, 274, 264, 448, 169, 285, 432,
422, 205, 243, 92, 258, 91, 473, 324, 502, 173, 165, 58, 459,
310, 383, 70, 225, 30, 477, 230, 311, 506, 389, 140, 143, 64,
437, 190, 120, 0, 172, 272, 350, 292, 2, 444, 162, 234, 112,
508, 278, 348, 76, 450]
FL : [32] -> [8] -> [32][16] -> [32]
FL FL_IN k EK =
if isEven k then
d0_even # d1_even
where d1_even = d1 ^ (d0 && (EK @ (k / 2)))
d0_even = d0 ^ (d1_even || (EK @ ((k / 2 + 6) % 8 + 8)))
else
d0_odd # d1_odd
where d1_odd = d1 ^ (d0 && (EK @ (((k - 1) / 2 + 2) % 8 + 8)))
d0_odd = d0 ^ (d1_odd || (EK @ (((k - 1) / 2 + 4) % 8)))
where // d0 as 16-bit integer
d0 : [16]
d0 = take FL_IN
// d1 as 16-bit integer
d1 : [16]
d1 = drop FL_IN
FLINV : [32] -> [8] -> [32][16] -> [32]
FLINV FL_IN k EK =
if isEven k then
d0_even # d1_even
where d0_even = d0 ^ (d1 || (EK @ ((k / 2 + 6) % 8 + 8)))
d1_even = d1 ^ (d0_even && (EK @ (k / 2)))
else
d0_odd # d1_odd
where d0_odd = d0 ^ (d1 || (EK @ (((k - 1) / 2 + 4) % 8)))
d1_odd = d1 ^ (d0_odd && (EK @ (((k - 1) / 2 + 2) % 8 + 8)))
where // d0 as 16-bit integer
d0 : [16]
d0 = take FL_IN
// d1 as 16-bit integer
d1 : [16]
d1 = drop FL_IN
//
// Encrypt/decrypt
//
misty1Encrypt : [64] -> [32][16] -> [64]
misty1Encrypt P EK = (C ! 0).1 # (C ! 0).0
where
// 64-bit plaintext P is divided into the leftmost 32-bit D0 and the
// rightmost 32-bit D1
C = [(take P, drop P)] # [ f D0 D1
| f <- funcs
| (D0, D1) <- C
]
funcs : [_]([32] -> [32] -> ([32], [32]))
funcs = [// 0 round
\D0 D1 -> (FL D0 0 EK, D1),
\D0 D1 -> (D0, FL D1 1 EK),
\D0 D1 -> (D0, D1 ^ (FO D0 0 EK)),
// 1 round
\D0 D1 -> (D0 ^ (FO D1 1 EK), D1),
// 2 round
\D0 D1 -> (FL D0 2 EK, D1),
\D0 D1 -> (D0, FL D1 3 EK),
\D0 D1 -> (D0, D1 ^ (FO D0 2 EK)),
// 3 round
\D0 D1 -> (D0 ^ (FO D1 3 EK), D1),
// 4 round
\D0 D1 -> (FL D0 4 EK, D1),
\D0 D1 -> (D0, FL D1 5 EK),
\D0 D1 -> (D0, D1 ^ (FO D0 4 EK)),
// 5 round
\D0 D1 -> (D0 ^ (FO D1 5 EK), D1),
// 6 round
\D0 D1 -> (FL D0 6 EK, D1),
\D0 D1 -> (D0, FL D1 7 EK),
\D0 D1 -> (D0, D1 ^ (FO D0 6 EK)),
// 7 round
\D0 D1 -> (D0 ^ (FO D1 7 EK), D1),
// final
\D0 D1 -> (FL D0 8 EK, D1),
\D0 D1 -> (D0, FL D1 9 EK)
]
misty1Decrypt : [64] -> [32][16] -> [64]
misty1Decrypt C EK = (P ! 0).0 # (P ! 0).1
where P = [(drop C, take C)] # [ f D0 D1
| f <- funcs
| (D0, D1) <- P
]
funcs : [_]([32] -> [32] -> ([32], [32]))
funcs = [\D0 D1 -> (FLINV D0 8 EK, D1),
\D0 D1 -> (D0, FLINV D1 9 EK),
\D0 D1 -> (D0 ^ (FO D1 7 EK), D1),
\D0 D1 -> (D0, D1 ^ (FO D0 6 EK)),
\D0 D1 -> (FLINV D0 6 EK, D1),
\D0 D1 -> (D0, FLINV D1 7 EK),
\D0 D1 -> (D0 ^ (FO D1 5 EK), D1),
\D0 D1 -> (D0, D1 ^ (FO D0 4 EK)),
\D0 D1 -> (FLINV D0 4 EK, D1),
\D0 D1 -> (D0, FLINV D1 5 EK),
\D0 D1 -> (D0 ^ (FO D1 3 EK), D1),
\D0 D1 -> (D0, D1 ^ (FO D0 2 EK)),
\D0 D1 -> (FLINV D0 2 EK, D1),
\D0 D1 -> (D0, FLINV D1 3 EK),
\D0 D1 -> (D0 ^ (FO D1 1 EK), D1),
\D0 D1 -> (D0, D1 ^ (FO D0 0 EK)),
\D0 D1 -> (FLINV D0 0 EK, D1),
\D0 D1 -> (D0, FLINV D1 1 EK)
]
//
// Helper functions
//
extend : {total, n} (fin total, fin n, total >= n) => [n] -> [total]
extend n = zero # n
isEven : {a} (fin a) => [a] -> Bool
isEven n = ~(n ! zero)
//
// Examples
//
property testMisty1Encrypt = [ misty1Encrypt block EK
| block <- plaintext
] == ciphertext
where EK = keySchedule key
key = [0x00, 0x11 .. 0xff]
plaintext = [0x0123456789abcdef, 0xfedcba9876543210]
ciphertext = [0x8b1da5f56ab3d07c, 0x04b68240b13be95d]
property misty1Correct pt key = misty1Decrypt (misty1Encrypt pt EK) EK == pt
where EK = keySchedule key