Coverage report: /home/ellis/comp/ext/ironclad/src/ciphers/twofish.lisp

KindCoveredAll%
expression0895 0.0
branch02 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; twofish.lisp -- implementation of Counterpane's Twofish AES candidate
2
 (in-package :crypto)
3
 (in-ironclad-readtable)
4
 
5
 ;;; various constant data arrays used by Twofish
6
 (declaim (type (simple-octet-vector 256)
7
                +twofish-q0+ +twofish-q1+))
8
 (declaim (type (simple-octet-vector 255)
9
                +twofish-exp-to-poly+ +twofish-poly-to-exp+))
10
 (defconst +twofish-q0+
11
 #8@(#xA9 #x67 #xB3 #xE8 #x04 #xFD #xA3 #x76 #x9A #x92 #x80 #x78 #xE4
12
 #xDD #xD1 #x38 #x0D #xC6 #x35 #x98 #x18 #xF7 #xEC #x6C #x43 #x75
13
 #x37 #x26 #xFA #x13 #x94 #x48 #xF2 #xD0 #x8B #x30 #x84 #x54 #xDF
14
 #x23 #x19 #x5B #x3D #x59 #xF3 #xAE #xA2 #x82 #x63 #x01 #x83 #x2E
15
 #xD9 #x51 #x9B #x7C #xA6 #xEB #xA5 #xBE #x16 #x0C #xE3 #x61 #xC0
16
 #x8C #x3A #xF5 #x73 #x2C #x25 #x0B #xBB #x4E #x89 #x6B #x53 #x6A
17
 #xB4 #xF1 #xE1 #xE6 #xBD #x45 #xE2 #xF4 #xB6 #x66 #xCC #x95 #x03
18
 #x56 #xD4 #x1C #x1E #xD7 #xFB #xC3 #x8E #xB5 #xE9 #xCF #xBF #xBA
19
 #xEA #x77 #x39 #xAF #x33 #xC9 #x62 #x71 #x81 #x79 #x09 #xAD #x24
20
 #xCD #xF9 #xD8 #xE5 #xC5 #xB9 #x4D #x44 #x08 #x86 #xE7 #xA1 #x1D
21
 #xAA #xED #x06 #x70 #xB2 #xD2 #x41 #x7B #xA0 #x11 #x31 #xC2 #x27
22
 #x90 #x20 #xF6 #x60 #xFF #x96 #x5C #xB1 #xAB #x9E #x9C #x52 #x1B
23
 #x5F #x93 #x0A #xEF #x91 #x85 #x49 #xEE #x2D #x4F #x8F #x3B #x47
24
 #x87 #x6D #x46 #xD6 #x3E #x69 #x64 #x2A #xCE #xCB #x2F #xFC #x97
25
 #x05 #x7A #xAC #x7F #xD5 #x1A #x4B #x0E #xA7 #x5A #x28 #x14 #x3F
26
 #x29 #x88 #x3C #x4C #x02 #xB8 #xDA #xB0 #x17 #x55 #x1F #x8A #x7D
27
 #x57 #xC7 #x8D #x74 #xB7 #xC4 #x9F #x72 #x7E #x15 #x22 #x12 #x58
28
 #x07 #x99 #x34 #x6E #x50 #xDE #x68 #x65 #xBC #xDB #xF8 #xC8 #xA8
29
 #x2B #x40 #xDC #xFE #x32 #xA4 #xCA #x10 #x21 #xF0 #xD3 #x5D #x0F
30
 #x00 #x6F #x9D #x36 #x42 #x4A #x5E #xC1 #xE0))
31
 
32
 (defconst +twofish-q1+
33
 #8@(#x75 #xF3 #xC6 #xF4 #xDB #x7B #xFB #xC8 #x4A #xD3 #xE6 #x6B #x45
34
 #x7D #xE8 #x4B #xD6 #x32 #xD8 #xFD #x37 #x71 #xF1 #xE1 #x30 #x0F
35
 #xF8 #x1B #x87 #xFA #x06 #x3F #x5E #xBA #xAE #x5B #x8A #x00 #xBC
36
 #x9D #x6D #xC1 #xB1 #x0E #x80 #x5D #xD2 #xD5 #xA0 #x84 #x07 #x14
37
 #xB5 #x90 #x2C #xA3 #xB2 #x73 #x4C #x54 #x92 #x74 #x36 #x51 #x38
38
 #xB0 #xBD #x5A #xFC #x60 #x62 #x96 #x6C #x42 #xF7 #x10 #x7C #x28
39
 #x27 #x8C #x13 #x95 #x9C #xC7 #x24 #x46 #x3B #x70 #xCA #xE3 #x85
40
 #xCB #x11 #xD0 #x93 #xB8 #xA6 #x83 #x20 #xFF #x9F #x77 #xC3 #xCC
41
 #x03 #x6F #x08 #xBF #x40 #xE7 #x2B #xE2 #x79 #x0C #xAA #x82 #x41
42
 #x3A #xEA #xB9 #xE4 #x9A #xA4 #x97 #x7E #xDA #x7A #x17 #x66 #x94
43
 #xA1 #x1D #x3D #xF0 #xDE #xB3 #x0B #x72 #xA7 #x1C #xEF #xD1 #x53
44
 #x3E #x8F #x33 #x26 #x5F #xEC #x76 #x2A #x49 #x81 #x88 #xEE #x21
45
 #xC4 #x1A #xEB #xD9 #xC5 #x39 #x99 #xCD #xAD #x31 #x8B #x01 #x18
46
 #x23 #xDD #x1F #x4E #x2D #xF9 #x48 #x4F #xF2 #x65 #x8E #x78 #x5C
47
 #x58 #x19 #x8D #xE5 #x98 #x57 #x67 #x7F #x05 #x64 #xAF #x63 #xB6
48
 #xFE #xF5 #xB7 #x3C #xA5 #xCE #xE9 #x68 #x44 #xE0 #x4D #x43 #x69
49
 #x29 #x2E #xAC #x15 #x59 #xA8 #x0A #x9E #x6E #x47 #xDF #x34 #x35
50
 #x6A #xCF #xDC #x22 #xC9 #xC0 #x9B #x89 #xD4 #xED #xAB #x12 #xA2
51
 #x0D #x52 #xBB #x02 #x2F #xA9 #xD7 #x61 #x1E #xB4 #x50 #x04 #xF6
52
 #xC2 #x16 #x25 #x86 #x56 #x55 #x09 #xBE #x91))
53
 
54
 (defconst +twofish-rs+
55
 #8@(#x01 #xA4 #x02 #xA4 #xA4 #x56 #xA1 #x55
56
 #x55 #x82 #xFC #x87 #x87 #xF3 #xC1 #x5A
57
 #x5A #x1E #x47 #x58 #x58 #xC6 #xAE #xDB
58
 #xDB #x68 #x3D #x9E #x9E #xE5 #x19 #x03))
59
 
60
 (defconst +twofish-exp-to-poly+
61
 #8@(#x01 #x02 #x04 #x08 #x10 #x20 #x40 #x80 #x4D #x9A #x79 #xF2 #xA9
62
 #x1F #x3E #x7C #xF8 #xBD #x37 #x6E #xDC #xF5 #xA7 #x03 #x06 #x0C
63
 #x18 #x30 #x60 #xC0 #xCD #xD7 #xE3 #x8B #x5B #xB6 #x21 #x42 #x84
64
 #x45 #x8A #x59 #xB2 #x29 #x52 #xA4 #x05 #x0A #x14 #x28 #x50 #xA0
65
 #x0D #x1A #x34 #x68 #xD0 #xED #x97 #x63 #xC6 #xC1 #xCF #xD3 #xEB
66
 #x9B #x7B #xF6 #xA1 #x0F #x1E #x3C #x78 #xF0 #xAD #x17 #x2E #x5C
67
 #xB8 #x3D #x7A #xF4 #xA5 #x07 #x0E #x1C #x38 #x70 #xE0 #x8D #x57
68
 #xAE #x11 #x22 #x44 #x88 #x5D #xBA #x39 #x72 #xE4 #x85 #x47 #x8E
69
 #x51 #xA2 #x09 #x12 #x24 #x48 #x90 #x6D #xDA #xF9 #xBF #x33 #x66
70
 #xCC #xD5 #xE7 #x83 #x4B #x96 #x61 #xC2 #xC9 #xDF #xF3 #xAB #x1B
71
 #x36 #x6C #xD8 #xFD #xB7 #x23 #x46 #x8C #x55 #xAA #x19 #x32 #x64
72
 #xC8 #xDD #xF7 #xA3 #x0B #x16 #x2C #x58 #xB0 #x2D #x5A #xB4 #x25
73
 #x4A #x94 #x65 #xCA #xD9 #xFF #xB3 #x2B #x56 #xAC #x15 #x2A #x54
74
 #xA8 #x1D #x3A #x74 #xE8 #x9D #x77 #xEE #x91 #x6F #xDE #xF1 #xAF
75
 #x13 #x26 #x4C #x98 #x7D #xFA #xB9 #x3F #x7E #xFC #xB5 #x27 #x4E
76
 #x9C #x75 #xEA #x99 #x7F #xFE #xB1 #x2F #x5E #xBC #x35 #x6A #xD4
77
 #xE5 #x87 #x43 #x86 #x41 #x82 #x49 #x92 #x69 #xD2 #xE9 #x9F #x73
78
 #xE6 #x81 #x4F #x9E #x71 #xE2 #x89 #x5F #xBE #x31 #x62 #xC4 #xC5
79
 #xC7 #xC3 #xCB #xDB #xFB #xBB #x3B #x76 #xEC #x95 #x67 #xCE #xD1
80
 #xEF #x93 #x6B #xD6 #xE1 #x8F #x53 #xA6))
81
 
82
 (defconst +twofish-poly-to-exp+
83
 #8@(#x00 #x01 #x17 #x02 #x2E #x18 #x53 #x03 #x6A #x2F #x93 #x19 #x34
84
 #x54 #x45 #x04 #x5C #x6B #xB6 #x30 #xA6 #x94 #x4B #x1A #x8C #x35
85
 #x81 #x55 #xAA #x46 #x0D #x05 #x24 #x5D #x87 #x6C #x9B #xB7 #xC1
86
 #x31 #x2B #xA7 #xA3 #x95 #x98 #x4C #xCA #x1B #xE6 #x8D #x73 #x36
87
 #xCD #x82 #x12 #x56 #x62 #xAB #xF0 #x47 #x4F #x0E #xBD #x06 #xD4
88
 #x25 #xD2 #x5E #x27 #x88 #x66 #x6D #xD6 #x9C #x79 #xB8 #x08 #xC2
89
 #xDF #x32 #x68 #x2C #xFD #xA8 #x8A #xA4 #x5A #x96 #x29 #x99 #x22
90
 #x4D #x60 #xCB #xE4 #x1C #x7B #xE7 #x3B #x8E #x9E #x74 #xF4 #x37
91
 #xD8 #xCE #xF9 #x83 #x6F #x13 #xB2 #x57 #xE1 #x63 #xDC #xAC #xC4
92
 #xF1 #xAF #x48 #x0A #x50 #x42 #x0F #xBA #xBE #xC7 #x07 #xDE #xD5
93
 #x78 #x26 #x65 #xD3 #xD1 #x5F #xE3 #x28 #x21 #x89 #x59 #x67 #xFC
94
 #x6E #xB1 #xD7 #xF8 #x9D #xF3 #x7A #x3A #xB9 #xC6 #x09 #x41 #xC3
95
 #xAE #xE0 #xDB #x33 #x44 #x69 #x92 #x2D #x52 #xFE #x16 #xA9 #x0C
96
 #x8B #x80 #xA5 #x4A #x5B #xB5 #x97 #xC9 #x2A #xA2 #x9A #xC0 #x23
97
 #x86 #x4E #xBC #x61 #xEF #xCC #x11 #xE5 #x72 #x1D #x3D #x7C #xEB
98
 #xE8 #xE9 #x3C #xEA #x8F #x7D #x9F #xEC #x75 #x1E #xF5 #x3E #x38
99
 #xF6 #xD9 #x3F #xCF #x76 #xFA #x1F #x84 #xA0 #x70 #xED #x14 #x90
100
 #xB3 #x7E #x58 #xFB #xE2 #x20 #x64 #xD0 #xDD #x77 #xAD #xDA #xC5
101
 #x40 #xF2 #x39 #xB0 #xF7 #x49 #xB4 #x0B #x7F #x51 #x15 #x43 #x91
102
 #x10 #x71 #xBB #xEE #xBF #x85 #xC8 #xA1))
103
 
104
 (declaim (type (simple-array (unsigned-byte 32) (256))
105
                +twofish-mds0+ +twofish-mds1+ +twofish-mds2+ +twofish-mds3+))
106
 (defconst +twofish-mds0+
107
 #32@(#xBCBC3275 #xECEC21F3 #x202043C6 #xB3B3C9F4 #xDADA03DB #x02028B7B
108
 #xE2E22BFB #x9E9EFAC8 #xC9C9EC4A #xD4D409D3 #x18186BE6 #x1E1E9F6B
109
 #x98980E45 #xB2B2387D #xA6A6D2E8 #x2626B74B #x3C3C57D6 #x93938A32
110
 #x8282EED8 #x525298FD #x7B7BD437 #xBBBB3771 #x5B5B97F1 #x474783E1
111
 #x24243C30 #x5151E20F #xBABAC6F8 #x4A4AF31B #xBFBF4887 #x0D0D70FA
112
 #xB0B0B306 #x7575DE3F #xD2D2FD5E #x7D7D20BA #x666631AE #x3A3AA35B
113
 #x59591C8A #x00000000 #xCDCD93BC #x1A1AE09D #xAEAE2C6D #x7F7FABC1
114
 #x2B2BC7B1 #xBEBEB90E #xE0E0A080 #x8A8A105D #x3B3B52D2 #x6464BAD5
115
 #xD8D888A0 #xE7E7A584 #x5F5FE807 #x1B1B1114 #x2C2CC2B5 #xFCFCB490
116
 #x3131272C #x808065A3 #x73732AB2 #x0C0C8173 #x79795F4C #x6B6B4154
117
 #x4B4B0292 #x53536974 #x94948F36 #x83831F51 #x2A2A3638 #xC4C49CB0
118
 #x2222C8BD #xD5D5F85A #xBDBDC3FC #x48487860 #xFFFFCE62 #x4C4C0796
119
 #x4141776C #xC7C7E642 #xEBEB24F7 #x1C1C1410 #x5D5D637C #x36362228
120
 #x6767C027 #xE9E9AF8C #x4444F913 #x1414EA95 #xF5F5BB9C #xCFCF18C7
121
 #x3F3F2D24 #xC0C0E346 #x7272DB3B #x54546C70 #x29294CCA #xF0F035E3
122
 #x0808FE85 #xC6C617CB #xF3F34F11 #x8C8CE4D0 #xA4A45993 #xCACA96B8
123
 #x68683BA6 #xB8B84D83 #x38382820 #xE5E52EFF #xADAD569F #x0B0B8477
124
 #xC8C81DC3 #x9999FFCC #x5858ED03 #x19199A6F #x0E0E0A08 #x95957EBF
125
 #x70705040 #xF7F730E7 #x6E6ECF2B #x1F1F6EE2 #xB5B53D79 #x09090F0C
126
 #x616134AA #x57571682 #x9F9F0B41 #x9D9D803A #x111164EA #x2525CDB9
127
 #xAFAFDDE4 #x4545089A #xDFDF8DA4 #xA3A35C97 #xEAEAD57E #x353558DA
128
 #xEDEDD07A #x4343FC17 #xF8F8CB66 #xFBFBB194 #x3737D3A1 #xFAFA401D
129
 #xC2C2683D #xB4B4CCF0 #x32325DDE #x9C9C71B3 #x5656E70B #xE3E3DA72
130
 #x878760A7 #x15151B1C #xF9F93AEF #x6363BFD1 #x3434A953 #x9A9A853E
131
 #xB1B1428F #x7C7CD133 #x88889B26 #x3D3DA65F #xA1A1D7EC #xE4E4DF76
132
 #x8181942A #x91910149 #x0F0FFB81 #xEEEEAA88 #x161661EE #xD7D77321
133
 #x9797F5C4 #xA5A5A81A #xFEFE3FEB #x6D6DB5D9 #x7878AEC5 #xC5C56D39
134
 #x1D1DE599 #x7676A4CD #x3E3EDCAD #xCBCB6731 #xB6B6478B #xEFEF5B01
135
 #x12121E18 #x6060C523 #x6A6AB0DD #x4D4DF61F #xCECEE94E #xDEDE7C2D
136
 #x55559DF9 #x7E7E5A48 #x2121B24F #x03037AF2 #xA0A02665 #x5E5E198E
137
 #x5A5A6678 #x65654B5C #x62624E58 #xFDFD4519 #x0606F48D #x404086E5
138
 #xF2F2BE98 #x3333AC57 #x17179067 #x05058E7F #xE8E85E05 #x4F4F7D64
139
 #x89896AAF #x10109563 #x74742FB6 #x0A0A75FE #x5C5C92F5 #x9B9B74B7
140
 #x2D2D333C #x3030D6A5 #x2E2E49CE #x494989E9 #x46467268 #x77775544
141
 #xA8A8D8E0 #x9696044D #x2828BD43 #xA9A92969 #xD9D97929 #x8686912E
142
 #xD1D187AC #xF4F44A15 #x8D8D1559 #xD6D682A8 #xB9B9BC0A #x42420D9E
143
 #xF6F6C16E #x2F2FB847 #xDDDD06DF #x23233934 #xCCCC6235 #xF1F1C46A
144
 #xC1C112CF #x8585EBDC #x8F8F9E22 #x7171A1C9 #x9090F0C0 #xAAAA539B
145
 #x0101F189 #x8B8BE1D4 #x4E4E8CED #x8E8E6FAB #xABABA212 #x6F6F3EA2
146
 #xE6E6540D #xDBDBF252 #x92927BBB #xB7B7B602 #x6969CA2F #x3939D9A9
147
 #xD3D30CD7 #xA7A72361 #xA2A2AD1E #xC3C399B4 #x6C6C4450 #x07070504
148
 #x04047FF6 #x272746C2 #xACACA716 #xD0D07625 #x50501386 #xDCDCF756
149
 #x84841A55 #xE1E15109 #x7A7A25BE #x1313EF91))
150
 
151
 (defconst +twofish-mds1+
152
 #32@(#xA9D93939 #x67901717 #xB3719C9C #xE8D2A6A6 #x04050707 #xFD985252
153
 #xA3658080 #x76DFE4E4 #x9A084545 #x92024B4B #x80A0E0E0 #x78665A5A
154
 #xE4DDAFAF #xDDB06A6A #xD1BF6363 #x38362A2A #x0D54E6E6 #xC6432020
155
 #x3562CCCC #x98BEF2F2 #x181E1212 #xF724EBEB #xECD7A1A1 #x6C774141
156
 #x43BD2828 #x7532BCBC #x37D47B7B #x269B8888 #xFA700D0D #x13F94444
157
 #x94B1FBFB #x485A7E7E #xF27A0303 #xD0E48C8C #x8B47B6B6 #x303C2424
158
 #x84A5E7E7 #x54416B6B #xDF06DDDD #x23C56060 #x1945FDFD #x5BA33A3A
159
 #x3D68C2C2 #x59158D8D #xF321ECEC #xAE316666 #xA23E6F6F #x82165757
160
 #x63951010 #x015BEFEF #x834DB8B8 #x2E918686 #xD9B56D6D #x511F8383
161
 #x9B53AAAA #x7C635D5D #xA63B6868 #xEB3FFEFE #xA5D63030 #xBE257A7A
162
 #x16A7ACAC #x0C0F0909 #xE335F0F0 #x6123A7A7 #xC0F09090 #x8CAFE9E9
163
 #x3A809D9D #xF5925C5C #x73810C0C #x2C273131 #x2576D0D0 #x0BE75656
164
 #xBB7B9292 #x4EE9CECE #x89F10101 #x6B9F1E1E #x53A93434 #x6AC4F1F1
165
 #xB499C3C3 #xF1975B5B #xE1834747 #xE66B1818 #xBDC82222 #x450E9898
166
 #xE26E1F1F #xF4C9B3B3 #xB62F7474 #x66CBF8F8 #xCCFF9999 #x95EA1414
167
 #x03ED5858 #x56F7DCDC #xD4E18B8B #x1C1B1515 #x1EADA2A2 #xD70CD3D3
168
 #xFB2BE2E2 #xC31DC8C8 #x8E195E5E #xB5C22C2C #xE9894949 #xCF12C1C1
169
 #xBF7E9595 #xBA207D7D #xEA641111 #x77840B0B #x396DC5C5 #xAF6A8989
170
 #x33D17C7C #xC9A17171 #x62CEFFFF #x7137BBBB #x81FB0F0F #x793DB5B5
171
 #x0951E1E1 #xADDC3E3E #x242D3F3F #xCDA47676 #xF99D5555 #xD8EE8282
172
 #xE5864040 #xC5AE7878 #xB9CD2525 #x4D049696 #x44557777 #x080A0E0E
173
 #x86135050 #xE730F7F7 #xA1D33737 #x1D40FAFA #xAA346161 #xED8C4E4E
174
 #x06B3B0B0 #x706C5454 #xB22A7373 #xD2523B3B #x410B9F9F #x7B8B0202
175
 #xA088D8D8 #x114FF3F3 #x3167CBCB #xC2462727 #x27C06767 #x90B4FCFC
176
 #x20283838 #xF67F0404 #x60784848 #xFF2EE5E5 #x96074C4C #x5C4B6565
177
 #xB1C72B2B #xAB6F8E8E #x9E0D4242 #x9CBBF5F5 #x52F2DBDB #x1BF34A4A
178
 #x5FA63D3D #x9359A4A4 #x0ABCB9B9 #xEF3AF9F9 #x91EF1313 #x85FE0808
179
 #x49019191 #xEE611616 #x2D7CDEDE #x4FB22121 #x8F42B1B1 #x3BDB7272
180
 #x47B82F2F #x8748BFBF #x6D2CAEAE #x46E3C0C0 #xD6573C3C #x3E859A9A
181
 #x6929A9A9 #x647D4F4F #x2A948181 #xCE492E2E #xCB17C6C6 #x2FCA6969
182
 #xFCC3BDBD #x975CA3A3 #x055EE8E8 #x7AD0EDED #xAC87D1D1 #x7F8E0505
183
 #xD5BA6464 #x1AA8A5A5 #x4BB72626 #x0EB9BEBE #xA7608787 #x5AF8D5D5
184
 #x28223636 #x14111B1B #x3FDE7575 #x2979D9D9 #x88AAEEEE #x3C332D2D
185
 #x4C5F7979 #x02B6B7B7 #xB896CACA #xDA583535 #xB09CC4C4 #x17FC4343
186
 #x551A8484 #x1FF64D4D #x8A1C5959 #x7D38B2B2 #x57AC3333 #xC718CFCF
187
 #x8DF40606 #x74695353 #xB7749B9B #xC4F59797 #x9F56ADAD #x72DAE3E3
188
 #x7ED5EAEA #x154AF4F4 #x229E8F8F #x12A2ABAB #x584E6262 #x07E85F5F
189
 #x99E51D1D #x34392323 #x6EC1F6F6 #x50446C6C #xDE5D3232 #x68724646
190
 #x6526A0A0 #xBC93CDCD #xDB03DADA #xF8C6BABA #xC8FA9E9E #xA882D6D6
191
 #x2BCF6E6E #x40507070 #xDCEB8585 #xFE750A0A #x328A9393 #xA48DDFDF
192
 #xCA4C2929 #x10141C1C #x2173D7D7 #xF0CCB4B4 #xD309D4D4 #x5D108A8A
193
 #x0FE25151 #x00000000 #x6F9A1919 #x9DE01A1A #x368F9494 #x42E6C7C7
194
 #x4AECC9C9 #x5EFDD2D2 #xC1AB7F7F #xE0D8A8A8))
195
 
196
 (defconst +twofish-mds2+
197
 #32@(#xBC75BC32 #xECF3EC21 #x20C62043 #xB3F4B3C9 #xDADBDA03 #x027B028B
198
 #xE2FBE22B #x9EC89EFA #xC94AC9EC #xD4D3D409 #x18E6186B #x1E6B1E9F
199
 #x9845980E #xB27DB238 #xA6E8A6D2 #x264B26B7 #x3CD63C57 #x9332938A
200
 #x82D882EE #x52FD5298 #x7B377BD4 #xBB71BB37 #x5BF15B97 #x47E14783
201
 #x2430243C #x510F51E2 #xBAF8BAC6 #x4A1B4AF3 #xBF87BF48 #x0DFA0D70
202
 #xB006B0B3 #x753F75DE #xD25ED2FD #x7DBA7D20 #x66AE6631 #x3A5B3AA3
203
 #x598A591C #x00000000 #xCDBCCD93 #x1A9D1AE0 #xAE6DAE2C #x7FC17FAB
204
 #x2BB12BC7 #xBE0EBEB9 #xE080E0A0 #x8A5D8A10 #x3BD23B52 #x64D564BA
205
 #xD8A0D888 #xE784E7A5 #x5F075FE8 #x1B141B11 #x2CB52CC2 #xFC90FCB4
206
 #x312C3127 #x80A38065 #x73B2732A #x0C730C81 #x794C795F #x6B546B41
207
 #x4B924B02 #x53745369 #x9436948F #x8351831F #x2A382A36 #xC4B0C49C
208
 #x22BD22C8 #xD55AD5F8 #xBDFCBDC3 #x48604878 #xFF62FFCE #x4C964C07
209
 #x416C4177 #xC742C7E6 #xEBF7EB24 #x1C101C14 #x5D7C5D63 #x36283622
210
 #x672767C0 #xE98CE9AF #x441344F9 #x149514EA #xF59CF5BB #xCFC7CF18
211
 #x3F243F2D #xC046C0E3 #x723B72DB #x5470546C #x29CA294C #xF0E3F035
212
 #x088508FE #xC6CBC617 #xF311F34F #x8CD08CE4 #xA493A459 #xCAB8CA96
213
 #x68A6683B #xB883B84D #x38203828 #xE5FFE52E #xAD9FAD56 #x0B770B84
214
 #xC8C3C81D #x99CC99FF #x580358ED #x196F199A #x0E080E0A #x95BF957E
215
 #x70407050 #xF7E7F730 #x6E2B6ECF #x1FE21F6E #xB579B53D #x090C090F
216
 #x61AA6134 #x57825716 #x9F419F0B #x9D3A9D80 #x11EA1164 #x25B925CD
217
 #xAFE4AFDD #x459A4508 #xDFA4DF8D #xA397A35C #xEA7EEAD5 #x35DA3558
218
 #xED7AEDD0 #x431743FC #xF866F8CB #xFB94FBB1 #x37A137D3 #xFA1DFA40
219
 #xC23DC268 #xB4F0B4CC #x32DE325D #x9CB39C71 #x560B56E7 #xE372E3DA
220
 #x87A78760 #x151C151B #xF9EFF93A #x63D163BF #x345334A9 #x9A3E9A85
221
 #xB18FB142 #x7C337CD1 #x8826889B #x3D5F3DA6 #xA1ECA1D7 #xE476E4DF
222
 #x812A8194 #x91499101 #x0F810FFB #xEE88EEAA #x16EE1661 #xD721D773
223
 #x97C497F5 #xA51AA5A8 #xFEEBFE3F #x6DD96DB5 #x78C578AE #xC539C56D
224
 #x1D991DE5 #x76CD76A4 #x3EAD3EDC #xCB31CB67 #xB68BB647 #xEF01EF5B
225
 #x1218121E #x602360C5 #x6ADD6AB0 #x4D1F4DF6 #xCE4ECEE9 #xDE2DDE7C
226
 #x55F9559D #x7E487E5A #x214F21B2 #x03F2037A #xA065A026 #x5E8E5E19
227
 #x5A785A66 #x655C654B #x6258624E #xFD19FD45 #x068D06F4 #x40E54086
228
 #xF298F2BE #x335733AC #x17671790 #x057F058E #xE805E85E #x4F644F7D
229
 #x89AF896A #x10631095 #x74B6742F #x0AFE0A75 #x5CF55C92 #x9BB79B74
230
 #x2D3C2D33 #x30A530D6 #x2ECE2E49 #x49E94989 #x46684672 #x77447755
231
 #xA8E0A8D8 #x964D9604 #x284328BD #xA969A929 #xD929D979 #x862E8691
232
 #xD1ACD187 #xF415F44A #x8D598D15 #xD6A8D682 #xB90AB9BC #x429E420D
233
 #xF66EF6C1 #x2F472FB8 #xDDDFDD06 #x23342339 #xCC35CC62 #xF16AF1C4
234
 #xC1CFC112 #x85DC85EB #x8F228F9E #x71C971A1 #x90C090F0 #xAA9BAA53
235
 #x018901F1 #x8BD48BE1 #x4EED4E8C #x8EAB8E6F #xAB12ABA2 #x6FA26F3E
236
 #xE60DE654 #xDB52DBF2 #x92BB927B #xB702B7B6 #x692F69CA #x39A939D9
237
 #xD3D7D30C #xA761A723 #xA21EA2AD #xC3B4C399 #x6C506C44 #x07040705
238
 #x04F6047F #x27C22746 #xAC16ACA7 #xD025D076 #x50865013 #xDC56DCF7
239
 #x8455841A #xE109E151 #x7ABE7A25 #x139113EF))
240
 
241
 (defconst +twofish-mds3+
242
 #32@(#xD939A9D9 #x90176790 #x719CB371 #xD2A6E8D2 #x05070405 #x9852FD98
243
 #x6580A365 #xDFE476DF #x08459A08 #x024B9202 #xA0E080A0 #x665A7866
244
 #xDDAFE4DD #xB06ADDB0 #xBF63D1BF #x362A3836 #x54E60D54 #x4320C643
245
 #x62CC3562 #xBEF298BE #x1E12181E #x24EBF724 #xD7A1ECD7 #x77416C77
246
 #xBD2843BD #x32BC7532 #xD47B37D4 #x9B88269B #x700DFA70 #xF94413F9
247
 #xB1FB94B1 #x5A7E485A #x7A03F27A #xE48CD0E4 #x47B68B47 #x3C24303C
248
 #xA5E784A5 #x416B5441 #x06DDDF06 #xC56023C5 #x45FD1945 #xA33A5BA3
249
 #x68C23D68 #x158D5915 #x21ECF321 #x3166AE31 #x3E6FA23E #x16578216
250
 #x95106395 #x5BEF015B #x4DB8834D #x91862E91 #xB56DD9B5 #x1F83511F
251
 #x53AA9B53 #x635D7C63 #x3B68A63B #x3FFEEB3F #xD630A5D6 #x257ABE25
252
 #xA7AC16A7 #x0F090C0F #x35F0E335 #x23A76123 #xF090C0F0 #xAFE98CAF
253
 #x809D3A80 #x925CF592 #x810C7381 #x27312C27 #x76D02576 #xE7560BE7
254
 #x7B92BB7B #xE9CE4EE9 #xF10189F1 #x9F1E6B9F #xA93453A9 #xC4F16AC4
255
 #x99C3B499 #x975BF197 #x8347E183 #x6B18E66B #xC822BDC8 #x0E98450E
256
 #x6E1FE26E #xC9B3F4C9 #x2F74B62F #xCBF866CB #xFF99CCFF #xEA1495EA
257
 #xED5803ED #xF7DC56F7 #xE18BD4E1 #x1B151C1B #xADA21EAD #x0CD3D70C
258
 #x2BE2FB2B #x1DC8C31D #x195E8E19 #xC22CB5C2 #x8949E989 #x12C1CF12
259
 #x7E95BF7E #x207DBA20 #x6411EA64 #x840B7784 #x6DC5396D #x6A89AF6A
260
 #xD17C33D1 #xA171C9A1 #xCEFF62CE #x37BB7137 #xFB0F81FB #x3DB5793D
261
 #x51E10951 #xDC3EADDC #x2D3F242D #xA476CDA4 #x9D55F99D #xEE82D8EE
262
 #x8640E586 #xAE78C5AE #xCD25B9CD #x04964D04 #x55774455 #x0A0E080A
263
 #x13508613 #x30F7E730 #xD337A1D3 #x40FA1D40 #x3461AA34 #x8C4EED8C
264
 #xB3B006B3 #x6C54706C #x2A73B22A #x523BD252 #x0B9F410B #x8B027B8B
265
 #x88D8A088 #x4FF3114F #x67CB3167 #x4627C246 #xC06727C0 #xB4FC90B4
266
 #x28382028 #x7F04F67F #x78486078 #x2EE5FF2E #x074C9607 #x4B655C4B
267
 #xC72BB1C7 #x6F8EAB6F #x0D429E0D #xBBF59CBB #xF2DB52F2 #xF34A1BF3
268
 #xA63D5FA6 #x59A49359 #xBCB90ABC #x3AF9EF3A #xEF1391EF #xFE0885FE
269
 #x01914901 #x6116EE61 #x7CDE2D7C #xB2214FB2 #x42B18F42 #xDB723BDB
270
 #xB82F47B8 #x48BF8748 #x2CAE6D2C #xE3C046E3 #x573CD657 #x859A3E85
271
 #x29A96929 #x7D4F647D #x94812A94 #x492ECE49 #x17C6CB17 #xCA692FCA
272
 #xC3BDFCC3 #x5CA3975C #x5EE8055E #xD0ED7AD0 #x87D1AC87 #x8E057F8E
273
 #xBA64D5BA #xA8A51AA8 #xB7264BB7 #xB9BE0EB9 #x6087A760 #xF8D55AF8
274
 #x22362822 #x111B1411 #xDE753FDE #x79D92979 #xAAEE88AA #x332D3C33
275
 #x5F794C5F #xB6B702B6 #x96CAB896 #x5835DA58 #x9CC4B09C #xFC4317FC
276
 #x1A84551A #xF64D1FF6 #x1C598A1C #x38B27D38 #xAC3357AC #x18CFC718
277
 #xF4068DF4 #x69537469 #x749BB774 #xF597C4F5 #x56AD9F56 #xDAE372DA
278
 #xD5EA7ED5 #x4AF4154A #x9E8F229E #xA2AB12A2 #x4E62584E #xE85F07E8
279
 #xE51D99E5 #x39233439 #xC1F66EC1 #x446C5044 #x5D32DE5D #x72466872
280
 #x26A06526 #x93CDBC93 #x03DADB03 #xC6BAF8C6 #xFA9EC8FA #x82D6A882
281
 #xCF6E2BCF #x50704050 #xEB85DCEB #x750AFE75 #x8A93328A #x8DDFA48D
282
 #x4C29CA4C #x141C1014 #x73D72173 #xCCB4F0CC #x09D4D309 #x108A5D10
283
 #xE2510FE2 #x00000000 #x9A196F9A #xE01A9DE0 #x8F94368F #xE6C742E6
284
 #xECC94AEC #xFDD25EFD #xAB7FC1AB #xD8A8E0D8))
285
 
286
 ;;; the actual implementation of Twofish
287
 (deftype twofish-s-boxes () '(simple-array (unsigned-byte 32) (1024)))
288
 (deftype twofish-round-keys () '(simple-array (unsigned-byte 32) (40)))
289
 
290
 (defclass twofish (cipher 16-byte-block-mixin)
291
   ((round-keys :accessor round-keys :type twofish-round-keys)
292
    (s-boxes :accessor s-boxes :type twofish-s-boxes)))
293
 
294
 (defun reed-solomon-multiply (box box-offset key rs0 rs1 rs2 rs3)
295
   (declare (type (simple-octet-vector 16) box))
296
   (declare (type (integer 0 12) box-offset))
297
   (unless (zerop key)
298
     (let ((temp (aref +twofish-poly-to-exp+ (1- key))))
299
       ;; Lispworks doesn't seem to like doing this with a straight
300
       ;; MACROLET and no #., so we go ahead and build everything at
301
       ;; read-time.
302
       #.(flet ((mod-box-element (index)
303
                  (let ((rs-sym (symbolicate '#:rs index)))
304
                    `(setf (aref box (+ box-offset ,index))
305
                           (logxor (aref box (+ box-offset ,index))
306
                                   (aref +twofish-exp-to-poly+
307
                                         (mod (+ temp (aref +twofish-poly-to-exp+
308
                                                            (1- ,rs-sym)))
309
                                              255)))))))
310
           `(progn
311
              ,(mod-box-element 0)
312
              ,(mod-box-element 1)
313
              ,(mod-box-element 2)
314
              ,(mod-box-element 3)))))
315
   (values))
316
 
317
 (defun twofish-key-schedule (key)
318
   (declare (type (simple-array (unsigned-byte 8) (*)) key))
319
   (let ((rs-box (make-array 16 :element-type '(unsigned-byte 8)
320
                             :initial-element 0))
321
         (round-keys (make-array 40 :element-type '(unsigned-byte 32)))
322
         (s-boxes (make-array 1024 :element-type '(unsigned-byte 32))))
323
     (declare (type (simple-octet-vector 16) rs-box))
324
     (declare (dynamic-extent rs-box))
325
     ;; fill the rs-box
326
     (dotimes (i (length key))
327
       (reed-solomon-multiply rs-box (* 4 (truncate i 8))
328
                              (aref key i)
329
                              (aref +twofish-rs+ (mod (* 4 i) 32))
330
                              (aref +twofish-rs+ (mod (+ (* 4 i) 1) 32))
331
                              (aref +twofish-rs+ (mod (+ (* 4 i) 2) 32))
332
                              (aref +twofish-rs+ (mod (+ (* 4 i) 3) 32))))
333
     (case (length key)
334
       (16 (twofish-schedule-16-byte-key round-keys s-boxes key rs-box))
335
       (24 (twofish-schedule-24-byte-key round-keys s-boxes key rs-box))
336
       (32 (twofish-schedule-32-byte-key round-keys s-boxes key rs-box)))))
337
 
338
 (macrolet ((s-box (s-boxes which index)
339
              `(aref ,s-boxes (+ (* 256 ,which) ,index)))
340
            (s-box-0 (s-boxes index) `(s-box ,s-boxes 0 ,index))
341
            (s-box-1 (s-boxes index) `(s-box ,s-boxes 1 ,index))
342
            (s-box-2 (s-boxes index) `(s-box ,s-boxes 2 ,index))
343
            (s-box-3 (s-boxes index) `(s-box ,s-boxes 3 ,index)))
344
   (defun twofish-schedule-16-byte-key (round-keys s-boxes key box)
345
     (declare (type twofish-round-keys round-keys)
346
              (type twofish-s-boxes s-boxes)
347
              (type (simple-octet-vector 16) key box))
348
     (macrolet ((q-frob (i1 i2 d1 d2)
349
                  (let ((q0 (symbolicate '#:+twofish-q (ldb (byte 1 1) i1) '#:+))
350
                        (q1 (symbolicate '#:+twofish-q (ldb (byte 1 0) i1) '#:+)))
351
                    `(logxor (aref ,q0 (logxor (aref ,q1 ,i2) ,d1)) ,d2))))
352
       (dotimes (i 256)
353
         (setf (s-box-0 s-boxes i) (aref +twofish-mds0+
354
                                         (q-frob 0 i (aref box 0) (aref box 4)))
355
               (s-box-1 s-boxes i) (aref +twofish-mds1+
356
                                         (q-frob 1 i (aref box 1) (aref box 5)))
357
               (s-box-2 s-boxes i) (aref +twofish-mds2+
358
                                         (q-frob 2 i (aref box 2) (aref box 6)))
359
               (s-box-3 s-boxes i) (aref +twofish-mds3+
360
                                         (q-frob 3 i (aref box 3) (aref box 7)))))
361
       (loop for i from 0 below 40 by 2 do
362
             (let ((x (logxor (aref +twofish-mds0+
363
                                    (q-frob 0 i (aref key 8) (aref key 0)))
364
                              (aref +twofish-mds1+
365
                                    (q-frob 1 i (aref key 9) (aref key 1)))
366
                              (aref +twofish-mds2+
367
                                    (q-frob 2 i (aref key 10) (aref key 2)))
368
                              (aref +twofish-mds3+
369
                                    (q-frob 3 i (aref key 11) (aref key 3)))))
370
                   (y (logxor (aref +twofish-mds0+
371
                                    (q-frob 0 (1+ i) (aref key 12) (aref key 4)))
372
                              (aref +twofish-mds1+
373
                                    (q-frob 1 (1+ i) (aref key 13) (aref key 5)))
374
                              (aref +twofish-mds2+
375
                                    (q-frob 2 (1+ i) (aref key 14) (aref key 6)))
376
                              (aref +twofish-mds3+
377
                                    (q-frob 3 (1+ i) (aref key 15) (aref key 7))))))
378
               (declare (type (unsigned-byte 32) x y))
379
               (setf y (rol32 y 8))
380
               (setf x (mod32+ x y))
381
               (setf y (mod32+ y x))
382
               (setf (aref round-keys i) x
383
                     (aref round-keys (1+ i)) (rol32 y 9)))
384
             finally (return (values round-keys s-boxes)))))
385
 
386
   (defun twofish-schedule-24-byte-key (round-keys s-boxes key box)
387
     (declare (type twofish-round-keys round-keys)
388
              (type twofish-s-boxes s-boxes)
389
              (type (simple-octet-vector 24) key)
390
              (type (simple-octet-vector 16) box))
391
     (macrolet ((q-frob (i1 i2 d1 d2 d3)
392
                  (let ((q0 (symbolicate '#:+twofish-q (ldb (byte 1 2) i1) '#:+))
393
                        (q1 (symbolicate '#:+twofish-q (ldb (byte 1 1) i1) '#:+))
394
                        (q2 (symbolicate '#:+twofish-q (ldb (byte 1 0) i1) '#:+)))
395
                    `(logxor (aref ,q0 (logxor (aref ,q1 (logxor (aref ,q2 ,i2)
396
                                                                 ,d1))
397
                                               ,d2))
398
                             ,d3))))
399
       (dotimes (i 256)
400
         (setf (s-box-0 s-boxes i) (aref +twofish-mds0+
401
                                         (q-frob 1 i (aref box 0) (aref box 4) (aref box 8)))
402
               (s-box-1 s-boxes i) (aref +twofish-mds1+
403
                                         (q-frob 3 i (aref box 1) (aref box 5) (aref box 9)))
404
               (s-box-2 s-boxes i) (aref +twofish-mds2+
405
                                         (q-frob 4 i (aref box 2) (aref box 6) (aref box 10)))
406
               (s-box-3 s-boxes i) (aref +twofish-mds3+
407
                                         (q-frob 6 i (aref box 3) (aref box 7) (aref box 11)))))
408
       (loop for i from 0 below 40 by 2 do
409
             (let ((x (logxor (aref +twofish-mds0+
410
                                    (q-frob 1 i (aref key 16) (aref key 8) (aref key 0)))
411
                              (aref +twofish-mds1+
412
                                    (q-frob 3 i (aref key 17) (aref key 9) (aref key 1)))
413
                              (aref +twofish-mds2+
414
                                    (q-frob 4 i (aref key 18) (aref key 10) (aref key 2)))
415
                              (aref +twofish-mds3+
416
                                    (q-frob 6 i (aref key 19) (aref key 11) (aref key 3)))))
417
                   (y (logxor (aref +twofish-mds0+
418
                                    (q-frob 1 (1+ i) (aref key 20) (aref key 12) (aref key 4)))
419
                              (aref +twofish-mds1+
420
                                    (q-frob 3 (1+ i) (aref key 21) (aref key 13) (aref key 5)))
421
                              (aref +twofish-mds2+
422
                                    (q-frob 4 (1+ i) (aref key 22) (aref key 14) (aref key 6)))
423
                              (aref +twofish-mds3+
424
                                    (q-frob 6 (1+ i) (aref key 23) (aref key 15) (aref key 7))))))
425
               (declare (type (unsigned-byte 32) x y))
426
               (setf y (rol32 y 8))
427
               (setf x (mod32+ x y))
428
               (setf y (mod32+ y x))
429
               (setf (aref round-keys i) x
430
                     (aref round-keys (1+ i)) (rol32 y 9)))
431
             finally (return (values round-keys s-boxes)))))
432
 
433
   (defun twofish-schedule-32-byte-key (round-keys s-boxes key box)
434
     (declare (type twofish-round-keys round-keys)
435
              (type twofish-s-boxes s-boxes)
436
              (type (simple-octet-vector 32) key)
437
              (type (simple-octet-vector 16) box))
438
     (macrolet ((q-frob (i1 i2 d1 d2 d3 d4)
439
                  (let ((q0 (symbolicate '#:+twofish-q (ldb (byte 1 3) i1) '#:+))
440
                        (q1 (symbolicate '#:+twofish-q (ldb (byte 1 2) i1) '#:+))
441
                        (q2 (symbolicate '#:+twofish-q (ldb (byte 1 1) i1) '#:+))
442
                        (q3 (symbolicate '#:+twofish-q (ldb (byte 1 0) i1) '#:+)))
443
                    `(logxor (aref ,q0 (logxor (aref ,q1 (logxor (aref ,q2 (logxor (aref ,q3 ,i2) ,d1)) ,d2)) ,d3)) ,d4))))
444
       (dotimes (i 256)
445
         (setf (s-box-0 s-boxes i) (aref +twofish-mds0+
446
                                         (q-frob #b0011 i (aref box 0) (aref box 4) (aref box 8) (aref box 12)))
447
               (s-box-1 s-boxes i) (aref +twofish-mds1+
448
                                         (q-frob #b0110 i (aref box 1) (aref box 5) (aref box 9) (aref box 13)))
449
               (s-box-2 s-boxes i) (aref +twofish-mds2+
450
                                         (q-frob #b1000 i (aref box 2) (aref box 6) (aref box 10) (aref box 14)))
451
               (s-box-3 s-boxes i) (aref +twofish-mds3+
452
                                         (q-frob #b1101 i (aref box 3) (aref box 7) (aref box 11) (aref box 15)))))
453
       (loop for i from 0 below 40 by 2 do
454
             (let ((x (logxor (aref +twofish-mds0+
455
                                    (q-frob #b0011 i (aref key 24) (aref key 16) (aref key 8) (aref key 0)))
456
                              (aref +twofish-mds1+
457
                                    (q-frob #b0110 i (aref key 25) (aref key 17) (aref key 9) (aref key 1)))
458
                              (aref +twofish-mds2+
459
                                    (q-frob #b1000 i (aref key 26) (aref key 18) (aref key 10) (aref key 2)))
460
                              (aref +twofish-mds3+
461
                                    (q-frob #b1101 i (aref key 27) (aref key 19) (aref key 11) (aref key 3)))))
462
                   (y (logxor (aref +twofish-mds0+
463
                                    (q-frob #b0011 (1+ i) (aref key 28) (aref key 20) (aref key 12) (aref key 4)))
464
                              (aref +twofish-mds1+
465
                                    (q-frob #b0110 (1+ i) (aref key 29) (aref key 21) (aref key 13) (aref key 5)))
466
                              (aref +twofish-mds2+
467
                                    (q-frob #b1000 (1+ i) (aref key 30) (aref key 22) (aref key 14) (aref key 6)))
468
                              (aref +twofish-mds3+
469
                                    (q-frob #b1101 (1+ i) (aref key 31) (aref key 23) (aref key 15) (aref key 7))))))
470
               (declare (type (unsigned-byte 32) x y))
471
               (setf y (rol32 y 8))
472
               (setf x (mod32+ x y))
473
               (setf y (mod32+ y x))
474
               (setf (aref round-keys i) x
475
                     (aref round-keys (1+ i)) (rol32 y 9)))
476
             finally (return (values round-keys s-boxes)))))
477
 
478
   (define-block-encryptor twofish 16
479
     (let ((round-keys (round-keys context))
480
           (s-boxes (s-boxes context)))
481
       (declare (type twofish-round-keys round-keys))
482
       (declare (type twofish-s-boxes s-boxes))
483
       (macrolet ((encrypt-round (a b c d round)
484
                    `(let ((x (logxor (s-box-0 s-boxes (first-byte ,a))
485
                                      (s-box-1 s-boxes (second-byte ,a))
486
                                      (s-box-2 s-boxes (third-byte ,a))
487
                                      (s-box-3 s-boxes (fourth-byte ,a))))
488
                           (y (logxor (s-box-0 s-boxes (fourth-byte ,b))
489
                                      (s-box-1 s-boxes (first-byte ,b))
490
                                      (s-box-2 s-boxes (second-byte ,b))
491
                                      (s-box-3 s-boxes (third-byte ,b)))))
492
                       (declare (type (unsigned-byte 32) x y))
493
                       (setf x (mod32+ x y))
494
                       (setf y (mod32+ y (mod32+ x (aref round-keys (+ (* ,round 2) 9)))))
495
                       (setf x (mod32+ x (aref round-keys (+ (* ,round 2) 8))))
496
                       (setf ,c (rol32 (logxor ,c x) 31)
497
                             ,d (logxor (rol32 ,d 1) y)))))
498
         (with-words ((a b c d) plaintext plaintext-start :big-endian nil)
499
           (setf a (logxor a (aref round-keys 0))
500
                 b (logxor b (aref round-keys 1))
501
                 c (logxor c (aref round-keys 2))
502
                 d (logxor d (aref round-keys 3)))
503
           #.(loop for i from 0 below 16
504
                   if (evenp i)
505
                   collect `(encrypt-round a b c d ,i) into rounds
506
                   else
507
                   collect `(encrypt-round c d a b ,i) into rounds
508
                   finally (return `(progn ,@rounds)))
509
           (setf c (logxor c (aref round-keys 4))
510
                 d (logxor d (aref round-keys 5))
511
                 a (logxor a (aref round-keys 6))
512
                 b (logxor b (aref round-keys 7)))
513
           (store-words ciphertext ciphertext-start c d a b)
514
           (values)))))
515
 
516
   (define-block-decryptor twofish 16
517
     (let ((round-keys (round-keys context))
518
           (s-boxes (s-boxes context)))
519
       (declare (type twofish-round-keys round-keys))
520
       (declare (type twofish-s-boxes s-boxes))
521
       (macrolet ((decrypt-round (a b c d round)
522
                    `(let ((x (logxor (s-box-0 s-boxes (first-byte ,a))
523
                                      (s-box-1 s-boxes (second-byte ,a))
524
                                      (s-box-2 s-boxes (third-byte ,a))
525
                                      (s-box-3 s-boxes (fourth-byte ,a))))
526
                           (y (logxor (s-box-0 s-boxes (fourth-byte ,b))
527
                                      (s-box-1 s-boxes (first-byte ,b))
528
                                      (s-box-2 s-boxes (second-byte ,b))
529
                                      (s-box-3 s-boxes (third-byte ,b)))))
530
                       (declare (type (unsigned-byte 32) x y))
531
                       (setf x (mod32+ x y))
532
                       (setf y (mod32+ y (mod32+ x (aref round-keys (+ (* ,round 2) 9)))))
533
                       (setf x (mod32+ x (aref round-keys (+ (* ,round 2) 8))))
534
                       (setf ,c (logxor (rol32 ,c 1) x)
535
                             ,d (rol32 (logxor ,d y) 31)))))
536
         (with-words ((c d a b) ciphertext ciphertext-start :big-endian nil)
537
           (setf c (logxor c (aref round-keys 4))
538
                 d (logxor d (aref round-keys 5))
539
                 a (logxor a (aref round-keys 6))
540
                 b (logxor b (aref round-keys 7)))
541
           #.(loop for i from 15 downto 0
542
                   if (evenp i)
543
                   collect `(decrypt-round a b c d ,i) into rounds
544
                   else
545
                   collect `(decrypt-round c d a b ,i) into rounds
546
                   finally (return `(progn ,@rounds)))
547
           (setf a (logxor a (aref round-keys 0))
548
                 b (logxor b (aref round-keys 1))
549
                 c (logxor c (aref round-keys 2))
550
                 d (logxor d (aref round-keys 3)))
551
           (store-words plaintext plaintext-start a b c d)
552
           (values))))))
553
 
554
 (defmethod schedule-key ((cipher twofish) key)
555
   (multiple-value-bind (round-keys s-boxes) (twofish-key-schedule key)
556
     (setf (round-keys cipher) round-keys
557
           (s-boxes cipher) s-boxes)
558
     cipher))
559
 
560
 (defcipher twofish
561
   (:encrypt-function twofish-encrypt-block)
562
   (:decrypt-function twofish-decrypt-block)
563
   (:block-length 16)
564
   (:key-length (:fixed 16 24 32)))