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

KindCoveredAll%
expression0454 0.0
branch06 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; blowfish.lisp -- implementation of Bruce Schneier's Blowfish block cipher
2
 (in-package :crypto)
3
 (in-ironclad-readtable)
4
 
5
 (defconst +blowfish-n-rounds+ 16)
6
 
7
 (declaim (type (simple-array (unsigned-byte 32) (18)) +p-array+))
8
 (defconst +p-array+
9
 #32@(#x243f6a88 #x85a308d3 #x13198a2e #x03707344 #xa4093822 #x299f31d0
10
      #x082efa98 #xec4e6c89 #x452821e6 #x38d01377 #xbe5466cf #x34e90c6c
11
      #xc0ac29b7 #xc97c50dd #x3f84d5b5 #xb5470917 #x9216d5d9 #x8979fb1b))
12
 
13
 (declaim (type (simple-array (unsigned-byte 32) (256))
14
                +s-box-0+ +s-box-1+ +s-box-2+ +s-box-3+))
15
 (defconst +s-box-0+
16
 #32@(#xd1310ba6 #x98dfb5ac #x2ffd72db #xd01adfb7 #xb8e1afed #x6a267e96
17
      #xba7c9045 #xf12c7f99 #x24a19947 #xb3916cf7 #x0801f2e2 #x858efc16
18
      #x636920d8 #x71574e69 #xa458fea3 #xf4933d7e #x0d95748f #x728eb658
19
      #x718bcd58 #x82154aee #x7b54a41d #xc25a59b5 #x9c30d539 #x2af26013
20
      #xc5d1b023 #x286085f0 #xca417918 #xb8db38ef #x8e79dcb0 #x603a180e
21
      #x6c9e0e8b #xb01e8a3e #xd71577c1 #xbd314b27 #x78af2fda #x55605c60
22
      #xe65525f3 #xaa55ab94 #x57489862 #x63e81440 #x55ca396a #x2aab10b6
23
      #xb4cc5c34 #x1141e8ce #xa15486af #x7c72e993 #xb3ee1411 #x636fbc2a
24
      #x2ba9c55d #x741831f6 #xce5c3e16 #x9b87931e #xafd6ba33 #x6c24cf5c
25
      #x7a325381 #x28958677 #x3b8f4898 #x6b4bb9af #xc4bfe81b #x66282193
26
      #x61d809cc #xfb21a991 #x487cac60 #x5dec8032 #xef845d5d #xe98575b1
27
      #xdc262302 #xeb651b88 #x23893e81 #xd396acc5 #x0f6d6ff3 #x83f44239
28
      #x2e0b4482 #xa4842004 #x69c8f04a #x9e1f9b5e #x21c66842 #xf6e96c9a
29
      #x670c9c61 #xabd388f0 #x6a51a0d2 #xd8542f68 #x960fa728 #xab5133a3
30
      #x6eef0b6c #x137a3be4 #xba3bf050 #x7efb2a98 #xa1f1651d #x39af0176
31
      #x66ca593e #x82430e88 #x8cee8619 #x456f9fb4 #x7d84a5c3 #x3b8b5ebe
32
      #xe06f75d8 #x85c12073 #x401a449f #x56c16aa6 #x4ed3aa62 #x363f7706
33
      #x1bfedf72 #x429b023d #x37d0d724 #xd00a1248 #xdb0fead3 #x49f1c09b
34
      #x075372c9 #x80991b7b #x25d479d8 #xf6e8def7 #xe3fe501a #xb6794c3b
35
      #x976ce0bd #x04c006ba #xc1a94fb6 #x409f60c4 #x5e5c9ec2 #x196a2463
36
      #x68fb6faf #x3e6c53b5 #x1339b2eb #x3b52ec6f #x6dfc511f #x9b30952c
37
      #xcc814544 #xaf5ebd09 #xbee3d004 #xde334afd #x660f2807 #x192e4bb3
38
      #xc0cba857 #x45c8740f #xd20b5f39 #xb9d3fbdb #x5579c0bd #x1a60320a
39
      #xd6a100c6 #x402c7279 #x679f25fe #xfb1fa3cc #x8ea5e9f8 #xdb3222f8
40
      #x3c7516df #xfd616b15 #x2f501ec8 #xad0552ab #x323db5fa #xfd238760
41
      #x53317b48 #x3e00df82 #x9e5c57bb #xca6f8ca0 #x1a87562e #xdf1769db
42
      #xd542a8f6 #x287effc3 #xac6732c6 #x8c4f5573 #x695b27b0 #xbbca58c8
43
      #xe1ffa35d #xb8f011a0 #x10fa3d98 #xfd2183b8 #x4afcb56c #x2dd1d35b
44
      #x9a53e479 #xb6f84565 #xd28e49bc #x4bfb9790 #xe1ddf2da #xa4cb7e33
45
      #x62fb1341 #xcee4c6e8 #xef20cada #x36774c01 #xd07e9efe #x2bf11fb4
46
      #x95dbda4d #xae909198 #xeaad8e71 #x6b93d5a0 #xd08ed1d0 #xafc725e0
47
      #x8e3c5b2f #x8e7594b7 #x8ff6e2fb #xf2122b64 #x8888b812 #x900df01c
48
      #x4fad5ea0 #x688fc31c #xd1cff191 #xb3a8c1ad #x2f2f2218 #xbe0e1777
49
      #xea752dfe #x8b021fa1 #xe5a0cc0f #xb56f74e8 #x18acf3d6 #xce89e299
50
      #xb4a84fe0 #xfd13e0b7 #x7cc43b81 #xd2ada8d9 #x165fa266 #x80957705
51
      #x93cc7314 #x211a1477 #xe6ad2065 #x77b5fa86 #xc75442f5 #xfb9d35cf
52
      #xebcdaf0c #x7b3e89a0 #xd6411bd3 #xae1e7e49 #x00250e2d #x2071b35e
53
      #x226800bb #x57b8e0af #x2464369b #xf009b91e #x5563911d #x59dfa6aa
54
      #x78c14389 #xd95a537f #x207d5ba2 #x02e5b9c5 #x83260376 #x6295cfa9
55
      #x11c81968 #x4e734a41 #xb3472dca #x7b14a94a #x1b510052 #x9a532915
56
      #xd60f573f #xbc9bc6e4 #x2b60a476 #x81e67400 #x08ba6fb5 #x571be91f
57
      #xf296ec6b #x2a0dd915 #xb6636521 #xe7b9f9b6 #xff34052e #xc5855664
58
      #x53b02d5d #xa99f8fa1 #x08ba4799 #x6e85076a))
59
 
60
 (defconst +s-box-1+
61
 #32@(#x4b7a70e9 #xb5b32944 #xdb75092e #xc4192623 #xad6ea6b0 #x49a7df7d
62
      #x9cee60b8 #x8fedb266 #xecaa8c71 #x699a17ff #x5664526c #xc2b19ee1
63
      #x193602a5 #x75094c29 #xa0591340 #xe4183a3e #x3f54989a #x5b429d65
64
      #x6b8fe4d6 #x99f73fd6 #xa1d29c07 #xefe830f5 #x4d2d38e6 #xf0255dc1
65
      #x4cdd2086 #x8470eb26 #x6382e9c6 #x021ecc5e #x09686b3f #x3ebaefc9
66
      #x3c971814 #x6b6a70a1 #x687f3584 #x52a0e286 #xb79c5305 #xaa500737
67
      #x3e07841c #x7fdeae5c #x8e7d44ec #x5716f2b8 #xb03ada37 #xf0500c0d
68
      #xf01c1f04 #x0200b3ff #xae0cf51a #x3cb574b2 #x25837a58 #xdc0921bd
69
      #xd19113f9 #x7ca92ff6 #x94324773 #x22f54701 #x3ae5e581 #x37c2dadc
70
      #xc8b57634 #x9af3dda7 #xa9446146 #x0fd0030e #xecc8c73e #xa4751e41
71
      #xe238cd99 #x3bea0e2f #x3280bba1 #x183eb331 #x4e548b38 #x4f6db908
72
      #x6f420d03 #xf60a04bf #x2cb81290 #x24977c79 #x5679b072 #xbcaf89af
73
      #xde9a771f #xd9930810 #xb38bae12 #xdccf3f2e #x5512721f #x2e6b7124
74
      #x501adde6 #x9f84cd87 #x7a584718 #x7408da17 #xbc9f9abc #xe94b7d8c
75
      #xec7aec3a #xdb851dfa #x63094366 #xc464c3d2 #xef1c1847 #x3215d908
76
      #xdd433b37 #x24c2ba16 #x12a14d43 #x2a65c451 #x50940002 #x133ae4dd
77
      #x71dff89e #x10314e55 #x81ac77d6 #x5f11199b #x043556f1 #xd7a3c76b
78
      #x3c11183b #x5924a509 #xf28fe6ed #x97f1fbfa #x9ebabf2c #x1e153c6e
79
      #x86e34570 #xeae96fb1 #x860e5e0a #x5a3e2ab3 #x771fe71c #x4e3d06fa
80
      #x2965dcb9 #x99e71d0f #x803e89d6 #x5266c825 #x2e4cc978 #x9c10b36a
81
      #xc6150eba #x94e2ea78 #xa5fc3c53 #x1e0a2df4 #xf2f74ea7 #x361d2b3d
82
      #x1939260f #x19c27960 #x5223a708 #xf71312b6 #xebadfe6e #xeac31f66
83
      #xe3bc4595 #xa67bc883 #xb17f37d1 #x018cff28 #xc332ddef #xbe6c5aa5
84
      #x65582185 #x68ab9802 #xeecea50f #xdb2f953b #x2aef7dad #x5b6e2f84
85
      #x1521b628 #x29076170 #xecdd4775 #x619f1510 #x13cca830 #xeb61bd96
86
      #x0334fe1e #xaa0363cf #xb5735c90 #x4c70a239 #xd59e9e0b #xcbaade14
87
      #xeecc86bc #x60622ca7 #x9cab5cab #xb2f3846e #x648b1eaf #x19bdf0ca
88
      #xa02369b9 #x655abb50 #x40685a32 #x3c2ab4b3 #x319ee9d5 #xc021b8f7
89
      #x9b540b19 #x875fa099 #x95f7997e #x623d7da8 #xf837889a #x97e32d77
90
      #x11ed935f #x16681281 #x0e358829 #xc7e61fd6 #x96dedfa1 #x7858ba99
91
      #x57f584a5 #x1b227263 #x9b83c3ff #x1ac24696 #xcdb30aeb #x532e3054
92
      #x8fd948e4 #x6dbc3128 #x58ebf2ef #x34c6ffea #xfe28ed61 #xee7c3c73
93
      #x5d4a14d9 #xe864b7e3 #x42105d14 #x203e13e0 #x45eee2b6 #xa3aaabea
94
      #xdb6c4f15 #xfacb4fd0 #xc742f442 #xef6abbb5 #x654f3b1d #x41cd2105
95
      #xd81e799e #x86854dc7 #xe44b476a #x3d816250 #xcf62a1f2 #x5b8d2646
96
      #xfc8883a0 #xc1c7b6a3 #x7f1524c3 #x69cb7492 #x47848a0b #x5692b285
97
      #x095bbf00 #xad19489d #x1462b174 #x23820e00 #x58428d2a #x0c55f5ea
98
      #x1dadf43e #x233f7061 #x3372f092 #x8d937e41 #xd65fecf1 #x6c223bdb
99
      #x7cde3759 #xcbee7460 #x4085f2a7 #xce77326e #xa6078084 #x19f8509e
100
      #xe8efd855 #x61d99735 #xa969a7aa #xc50c06c2 #x5a04abfc #x800bcadc
101
      #x9e447a2e #xc3453484 #xfdd56705 #x0e1e9ec9 #xdb73dbd3 #x105588cd
102
      #x675fda79 #xe3674340 #xc5c43465 #x713e38d8 #x3d28f89e #xf16dff20
103
      #x153e21e7 #x8fb03d4a #xe6e39f2b #xdb83adf7))
104
 
105
 (defconst +s-box-2+
106
 #32@(#xe93d5a68 #x948140f7 #xf64c261c #x94692934 #x411520f7 #x7602d4f7
107
      #xbcf46b2e #xd4a20068 #xd4082471 #x3320f46a #x43b7d4b7 #x500061af
108
      #x1e39f62e #x97244546 #x14214f74 #xbf8b8840 #x4d95fc1d #x96b591af
109
      #x70f4ddd3 #x66a02f45 #xbfbc09ec #x03bd9785 #x7fac6dd0 #x31cb8504
110
      #x96eb27b3 #x55fd3941 #xda2547e6 #xabca0a9a #x28507825 #x530429f4
111
      #x0a2c86da #xe9b66dfb #x68dc1462 #xd7486900 #x680ec0a4 #x27a18dee
112
      #x4f3ffea2 #xe887ad8c #xb58ce006 #x7af4d6b6 #xaace1e7c #xd3375fec
113
      #xce78a399 #x406b2a42 #x20fe9e35 #xd9f385b9 #xee39d7ab #x3b124e8b
114
      #x1dc9faf7 #x4b6d1856 #x26a36631 #xeae397b2 #x3a6efa74 #xdd5b4332
115
      #x6841e7f7 #xca7820fb #xfb0af54e #xd8feb397 #x454056ac #xba489527
116
      #x55533a3a #x20838d87 #xfe6ba9b7 #xd096954b #x55a867bc #xa1159a58
117
      #xcca92963 #x99e1db33 #xa62a4a56 #x3f3125f9 #x5ef47e1c #x9029317c
118
      #xfdf8e802 #x04272f70 #x80bb155c #x05282ce3 #x95c11548 #xe4c66d22
119
      #x48c1133f #xc70f86dc #x07f9c9ee #x41041f0f #x404779a4 #x5d886e17
120
      #x325f51eb #xd59bc0d1 #xf2bcc18f #x41113564 #x257b7834 #x602a9c60
121
      #xdff8e8a3 #x1f636c1b #x0e12b4c2 #x02e1329e #xaf664fd1 #xcad18115
122
      #x6b2395e0 #x333e92e1 #x3b240b62 #xeebeb922 #x85b2a20e #xe6ba0d99
123
      #xde720c8c #x2da2f728 #xd0127845 #x95b794fd #x647d0862 #xe7ccf5f0
124
      #x5449a36f #x877d48fa #xc39dfd27 #xf33e8d1e #x0a476341 #x992eff74
125
      #x3a6f6eab #xf4f8fd37 #xa812dc60 #xa1ebddf8 #x991be14c #xdb6e6b0d
126
      #xc67b5510 #x6d672c37 #x2765d43b #xdcd0e804 #xf1290dc7 #xcc00ffa3
127
      #xb5390f92 #x690fed0b #x667b9ffb #xcedb7d9c #xa091cf0b #xd9155ea3
128
      #xbb132f88 #x515bad24 #x7b9479bf #x763bd6eb #x37392eb3 #xcc115979
129
      #x8026e297 #xf42e312d #x6842ada7 #xc66a2b3b #x12754ccc #x782ef11c
130
      #x6a124237 #xb79251e7 #x06a1bbe6 #x4bfb6350 #x1a6b1018 #x11caedfa
131
      #x3d25bdd8 #xe2e1c3c9 #x44421659 #x0a121386 #xd90cec6e #xd5abea2a
132
      #x64af674e #xda86a85f #xbebfe988 #x64e4c3fe #x9dbc8057 #xf0f7c086
133
      #x60787bf8 #x6003604d #xd1fd8346 #xf6381fb0 #x7745ae04 #xd736fccc
134
      #x83426b33 #xf01eab71 #xb0804187 #x3c005e5f #x77a057be #xbde8ae24
135
      #x55464299 #xbf582e61 #x4e58f48f #xf2ddfda2 #xf474ef38 #x8789bdc2
136
      #x5366f9c3 #xc8b38e74 #xb475f255 #x46fcd9b9 #x7aeb2661 #x8b1ddf84
137
      #x846a0e79 #x915f95e2 #x466e598e #x20b45770 #x8cd55591 #xc902de4c
138
      #xb90bace1 #xbb8205d0 #x11a86248 #x7574a99e #xb77f19b6 #xe0a9dc09
139
      #x662d09a1 #xc4324633 #xe85a1f02 #x09f0be8c #x4a99a025 #x1d6efe10
140
      #x1ab93d1d #x0ba5a4df #xa186f20f #x2868f169 #xdcb7da83 #x573906fe
141
      #xa1e2ce9b #x4fcd7f52 #x50115e01 #xa70683fa #xa002b5c4 #x0de6d027
142
      #x9af88c27 #x773f8641 #xc3604c06 #x61a806b5 #xf0177a28 #xc0f586e0
143
      #x006058aa #x30dc7d62 #x11e69ed7 #x2338ea63 #x53c2dd94 #xc2c21634
144
      #xbbcbee56 #x90bcb6de #xebfc7da1 #xce591d76 #x6f05e409 #x4b7c0188
145
      #x39720a3d #x7c927c24 #x86e3725f #x724d9db9 #x1ac15bb4 #xd39eb8fc
146
      #xed545578 #x08fca5b5 #xd83d7cd3 #x4dad0fc4 #x1e50ef5e #xb161e6f8
147
      #xa28514d9 #x6c51133c #x6fd5c7e7 #x56e14ec4 #x362abfce #xddc6c837
148
      #xd79a3234 #x92638212 #x670efa8e #x406000e0))
149
 
150
 (defconst +s-box-3+
151
 #32@(#x3a39ce37 #xd3faf5cf #xabc27737 #x5ac52d1b #x5cb0679e #x4fa33742
152
      #xd3822740 #x99bc9bbe #xd5118e9d #xbf0f7315 #xd62d1c7e #xc700c47b
153
      #xb78c1b6b #x21a19045 #xb26eb1be #x6a366eb4 #x5748ab2f #xbc946e79
154
      #xc6a376d2 #x6549c2c8 #x530ff8ee #x468dde7d #xd5730a1d #x4cd04dc6
155
      #x2939bbdb #xa9ba4650 #xac9526e8 #xbe5ee304 #xa1fad5f0 #x6a2d519a
156
      #x63ef8ce2 #x9a86ee22 #xc089c2b8 #x43242ef6 #xa51e03aa #x9cf2d0a4
157
      #x83c061ba #x9be96a4d #x8fe51550 #xba645bd6 #x2826a2f9 #xa73a3ae1
158
      #x4ba99586 #xef5562e9 #xc72fefd3 #xf752f7da #x3f046f69 #x77fa0a59
159
      #x80e4a915 #x87b08601 #x9b09e6ad #x3b3ee593 #xe990fd5a #x9e34d797
160
      #x2cf0b7d9 #x022b8b51 #x96d5ac3a #x017da67d #xd1cf3ed6 #x7c7d2d28
161
      #x1f9f25cf #xadf2b89b #x5ad6b472 #x5a88f54c #xe029ac71 #xe019a5e6
162
      #x47b0acfd #xed93fa9b #xe8d3c48d #x283b57cc #xf8d56629 #x79132e28
163
      #x785f0191 #xed756055 #xf7960e44 #xe3d35e8c #x15056dd4 #x88f46dba
164
      #x03a16125 #x0564f0bd #xc3eb9e15 #x3c9057a2 #x97271aec #xa93a072a
165
      #x1b3f6d9b #x1e6321f5 #xf59c66fb #x26dcf319 #x7533d928 #xb155fdf5
166
      #x03563482 #x8aba3cbb #x28517711 #xc20ad9f8 #xabcc5167 #xccad925f
167
      #x4de81751 #x3830dc8e #x379d5862 #x9320f991 #xea7a90c2 #xfb3e7bce
168
      #x5121ce64 #x774fbe32 #xa8b6e37e #xc3293d46 #x48de5369 #x6413e680
169
      #xa2ae0810 #xdd6db224 #x69852dfd #x09072166 #xb39a460a #x6445c0dd
170
      #x586cdecf #x1c20c8ae #x5bbef7dd #x1b588d40 #xccd2017f #x6bb4e3bb
171
      #xdda26a7e #x3a59ff45 #x3e350a44 #xbcb4cdd5 #x72eacea8 #xfa6484bb
172
      #x8d6612ae #xbf3c6f47 #xd29be463 #x542f5d9e #xaec2771b #xf64e6370
173
      #x740e0d8d #xe75b1357 #xf8721671 #xaf537d5d #x4040cb08 #x4eb4e2cc
174
      #x34d2466a #x0115af84 #xe1b00428 #x95983a1d #x06b89fb4 #xce6ea048
175
      #x6f3f3b82 #x3520ab82 #x011a1d4b #x277227f8 #x611560b1 #xe7933fdc
176
      #xbb3a792b #x344525bd #xa08839e1 #x51ce794b #x2f32c9b7 #xa01fbac9
177
      #xe01cc87e #xbcc7d1f6 #xcf0111c3 #xa1e8aac7 #x1a908749 #xd44fbd9a
178
      #xd0dadecb #xd50ada38 #x0339c32a #xc6913667 #x8df9317c #xe0b12b4f
179
      #xf79e59b7 #x43f5bb3a #xf2d519ff #x27d9459c #xbf97222c #x15e6fc2a
180
      #x0f91fc71 #x9b941525 #xfae59361 #xceb69ceb #xc2a86459 #x12baa8d1
181
      #xb6c1075e #xe3056a0c #x10d25065 #xcb03a442 #xe0ec6e0e #x1698db3b
182
      #x4c98a0be #x3278e964 #x9f1f9532 #xe0d392df #xd3a0342b #x8971f21e
183
      #x1b0a7441 #x4ba3348c #xc5be7120 #xc37632d8 #xdf359f8d #x9b992f2e
184
      #xe60b6f47 #x0fe3f11d #xe54cda54 #x1edad891 #xce6279cf #xcd3e7e6f
185
      #x1618b166 #xfd2c1d05 #x848fd2c5 #xf6fb2299 #xf523f357 #xa6327623
186
      #x93a83531 #x56cccd02 #xacf08162 #x5a75ebb5 #x6e163697 #x88d273cc
187
      #xde966292 #x81b949d0 #x4c50901b #x71c65614 #xe6c6c7bd #x327a140a
188
      #x45e1d006 #xc3f27b9a #xc9aa53fd #x62a80f00 #xbb25bfe2 #x35bdd2f6
189
      #x71126905 #xb2040222 #xb6cbcf7c #xcd769c2b #x53113ec0 #x1640e3d3
190
      #x38abbd60 #x2547adf0 #xba38209c #xf746ce76 #x77afa1c5 #x20756060
191
      #x85cbfe4e #x8ae88dd8 #x7aaaf9b0 #x4cf9aa7e #x1948c25c #x02fb8a8c
192
      #x01c36ae4 #xd6ebe1f9 #x90d4f869 #xa65cdea0 #x3f09252d #xc208e69f
193
      #xb74e6132 #xce77e25b #x578fdfe3 #x3ac372e6))
194
 
195
 ;;; the actual Blowfish implementation
196
 (eval-when (:compile-toplevel :load-toplevel)
197
   (deftype blowfish-p-array () '(simple-array (unsigned-byte 32) (18)))
198
   (deftype blowfish-s-boxes () '(simple-array (unsigned-byte 32) (1024))))
199
 
200
 (defclass blowfish (cipher 8-byte-block-mixin)
201
   ((p-array :accessor p-array :type blowfish-p-array)
202
    (s-boxes :accessor s-boxes :type blowfish-s-boxes)))
203
 
204
 (macrolet ((s-box (s-boxes which index)
205
              `(aref ,s-boxes (+ (* 256 ,which) ,index)))
206
            (s-box-0 (s-boxes index) `(s-box ,s-boxes 0 ,index))
207
            (s-box-1 (s-boxes index) `(s-box ,s-boxes 1 ,index))
208
            (s-box-2 (s-boxes index) `(s-box ,s-boxes 2 ,index))
209
            (s-box-3 (s-boxes index) `(s-box ,s-boxes 3 ,index)))
210
 
211
 (declaim (inline blowfish-f))
212
 (defun blowfish-f (block s-boxes)
213
   (declare (type (unsigned-byte 32) block))
214
   (declare (type blowfish-s-boxes s-boxes))
215
   (mod32+ (s-box-3 s-boxes (first-byte block))
216
           (logxor (s-box-2 s-boxes (second-byte block))
217
                   (mod32+ (s-box-1 s-boxes (third-byte block))
218
                           (s-box-0 s-boxes (fourth-byte block))))))
219
 
220
 (declaim (inline blowfish-encrypt-block*))
221
 (defun blowfish-encrypt-block* (p-array s-boxes plaintext plaintext-start
222
                                         ciphertext ciphertext-start)
223
   (declare (type (simple-array (unsigned-byte 8) (*)) plaintext ciphertext))
224
   (declare (type (integer 0 #.(- array-dimension-limit 8))
225
                  plaintext-start ciphertext-start))
226
   (declare (type blowfish-p-array p-array))
227
   (declare (type blowfish-s-boxes s-boxes))
228
   (with-words ((left right) plaintext plaintext-start)
229
     #.(loop for i from 0 below 16
230
             if (evenp i)
231
               collect `(setf left (logxor left (aref p-array ,i))
232
                         right (logxor right (blowfish-f left s-boxes))) into forms
233
             else
234
               collect `(setf right (logxor right (aref p-array ,i))
235
                         left (logxor left (blowfish-f right s-boxes))) into forms
236
             finally (return `(progn ,@forms)))
237
     (setf left (logxor left (aref p-array 16))
238
           right (logxor right (aref p-array 17)))
239
     (store-words ciphertext ciphertext-start right left)))
240
 
241
 (defun initialize-blowfish-vectors (key p-array s-boxes)
242
   (declare (type (simple-array (unsigned-byte 8) (*)) key))
243
   (declare (type blowfish-p-array p-array))
244
   (declare (type blowfish-s-boxes s-boxes))
245
   (mix-p-array key p-array)
246
   (let ((data (make-array 8 :element-type '(unsigned-byte 8) :initial-element 0)))
247
     (declare (type (simple-array (unsigned-byte 8) (8)) data))
248
     (do ((i 0 (+ i 2)))
249
         ((= i (+ +blowfish-n-rounds+ 2)))
250
       (blowfish-encrypt-block* p-array s-boxes data 0 data 0)
251
       (setf (aref p-array i) (ub32ref/be data 0)
252
             (aref p-array (1+ i)) (ub32ref/be data 4)))
253
     (dotimes (i 4)
254
       (do ((j 0 (+ j 2)))
255
           ((= j 256))
256
         (blowfish-encrypt-block* p-array s-boxes data 0 data 0)
257
         (setf (s-box s-boxes i j) (ub32ref/be data 0)
258
               (s-box s-boxes i (1+ j)) (ub32ref/be data 4))))))
259
 
260
 (declaim (notinline blowfish-encrypt-block*))
261
 
262
 (define-block-encryptor blowfish 8
263
   (declare (inline blowfish-encrypt-block*))
264
   (blowfish-encrypt-block* (p-array context) (s-boxes context)
265
                            plaintext plaintext-start
266
                            ciphertext ciphertext-start))
267
 
268
 (declaim (inline blowfish-decrypt-block*))
269
 (defun blowfish-decrypt-block* (p-array s-boxes ciphertext ciphertext-start
270
                                         plaintext plaintext-start)
271
   (declare (type (simple-array (unsigned-byte 8) (*)) plaintext ciphertext))
272
   (declare (type (integer 0 #.(- array-dimension-limit 8))
273
                  ciphertext-start plaintext-start))
274
   (declare (type blowfish-p-array p-array))
275
   (declare (type blowfish-s-boxes s-boxes))
276
   (with-words ((left right) ciphertext ciphertext-start)
277
     #.(loop for i from 17 above 1
278
             if (oddp i)
279
               collect `(setf left (logxor left (aref p-array ,i))
280
                         right (logxor right (blowfish-f left s-boxes))) into forms
281
             else
282
               collect `(setf right (logxor right (aref p-array ,i))
283
                         left (logxor left (blowfish-f right s-boxes))) into forms
284
             finally (return `(progn ,@forms)))
285
     (setf left (logxor left (aref p-array 1))
286
           right (logxor right (aref p-array 0)))
287
     (store-words plaintext plaintext-start right left)))
288
 (declaim (notinline blowfish-decrypt-block*))
289
 
290
 (define-block-decryptor blowfish 8
291
   (declare (inline blowfish-decrypt-block*))
292
   (blowfish-decrypt-block* (p-array context) (s-boxes context)
293
                            ciphertext ciphertext-start
294
                            plaintext plaintext-start))
295
 
296
 (defun mix-p-array (key p-array)
297
   (declare (type (simple-array (unsigned-byte 8) (*)) key))
298
   (declare (type blowfish-p-array p-array))
299
   (let ((n-key-bytes (length key))
300
         (j 0))
301
     (dotimes (i (+ +blowfish-n-rounds+ 2))
302
       (let ((data 0))
303
         (declare (type (unsigned-byte 32) data))
304
         (dotimes (k 4)
305
           (setf data (logior (mod32ash data 8) (aref key j)))
306
           (incf j)
307
           (when (>= j n-key-bytes)
308
             (setf j 0)))
309
         (setf (aref p-array i) (logxor (aref p-array i) data))))))
310
 
311
 (defmethod schedule-key ((cipher blowfish) key)
312
   (let ((p-array (copy-seq +p-array+))
313
         (s-boxes (make-array 1024 :element-type '(unsigned-byte 32))))
314
     (declare (type (simple-array (unsigned-byte 8) (*)) key))
315
     (declare (type blowfish-p-array p-array))
316
     (declare (type blowfish-s-boxes s-boxes))
317
     (dotimes (i 256)
318
       (setf (aref s-boxes i) (aref +s-box-0+ i)
319
             (aref s-boxes (+ 256 i)) (aref +s-box-1+ i)
320
             (aref s-boxes (+ 512 i)) (aref +s-box-2+ i)
321
             (aref s-boxes (+ 768 i)) (aref +s-box-3+ i)))
322
     (initialize-blowfish-vectors key p-array s-boxes)
323
     (setf (p-array cipher) p-array
324
           (s-boxes cipher) s-boxes)
325
     cipher)))
326
 
327
 (defcipher blowfish
328
   (:encrypt-function blowfish-encrypt-block)
329
   (:decrypt-function blowfish-decrypt-block)
330
   (:block-length 8)
331
   (:key-length (:variable 1 56 1)))