crypto/
blowfish.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use cryptoutil::{read_u32v_be, write_u32_be};
8use symmetriccipher::{BlockEncryptor, BlockDecryptor};
9use step_by::RangeExt;
10
11#[derive(Clone,Copy)]
12pub struct Blowfish {
13    s: [[u32; 256]; 4],
14    p: [u32; 18]
15}
16
17fn next_u32_wrap(buf: &[u8], offset: &mut usize) -> u32 {
18    let mut v = 0;
19    for _ in 0..4 {
20        if *offset >= buf.len() {
21            *offset = 0;
22        }
23        v = (v << 8) | buf[*offset] as u32;
24        *offset += 1;
25    }
26    v
27}
28
29impl Blowfish {
30    pub fn new(key: &[u8]) -> Blowfish {
31        assert!(4 <= key.len() && key.len() <= 56);
32        let mut blowfish = Blowfish::init_state();
33        blowfish.expand_key(key);
34        blowfish
35    }
36
37    // For bcrypt. Use Blowfish::new instead.
38    pub fn init_state() -> Blowfish {
39        Blowfish {
40            p: [0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
41                0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
42                0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b],
43            s: [[0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
44                 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
45                 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
46                 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
47                 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
48                 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
49                 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
50                 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
51                 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
52                 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
53                 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
54                 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
55                 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
56                 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
57                 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
58                 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
59                 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
60                 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
61                 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
62                 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
63                 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
64                 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
65                 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
66                 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
67                 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
68                 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
69                 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
70                 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
71                 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
72                 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
73                 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
74                 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
75                 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
76                 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
77                 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
78                 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
79                 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
80                 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
81                 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
82                 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
83                 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
84                 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
85                 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a],
86                [0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
87                 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
88                 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
89                 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
90                 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
91                 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
92                 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
93                 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
94                 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
95                 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
96                 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
97                 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
98                 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
99                 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
100                 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
101                 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
102                 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
103                 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
104                 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
105                 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
106                 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
107                 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
108                 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
109                 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
110                 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
111                 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
112                 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
113                 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
114                 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
115                 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
116                 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
117                 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
118                 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
119                 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
120                 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
121                 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
122                 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
123                 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
124                 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
125                 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
126                 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
127                 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
128                 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7],
129                [0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
130                 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
131                 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
132                 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
133                 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
134                 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
135                 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
136                 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
137                 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
138                 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
139                 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
140                 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
141                 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
142                 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
143                 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
144                 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
145                 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
146                 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
147                 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
148                 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
149                 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
150                 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
151                 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
152                 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
153                 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
154                 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
155                 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
156                 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
157                 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
158                 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
159                 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
160                 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
161                 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
162                 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
163                 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
164                 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
165                 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
166                 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
167                 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
168                 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
169                 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
170                 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
171                 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0],
172                [0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
173                 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
174                 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
175                 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
176                 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
177                 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
178                 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
179                 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
180                 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
181                 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
182                 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
183                 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
184                 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
185                 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
186                 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
187                 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
188                 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
189                 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
190                 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
191                 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
192                 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
193                 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
194                 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
195                 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
196                 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
197                 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
198                 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
199                 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
200                 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
201                 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
202                 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
203                 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
204                 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
205                 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
206                 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
207                 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
208                 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
209                 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
210                 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
211                 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
212                 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
213                 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
214                 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]]
215        }
216    }
217
218    // For bcrypt. Use Blowfish::new instead.
219    pub fn expand_key(&mut self, key: &[u8]) {
220        let mut key_pos = 0;
221        for i in 0..18 {
222            self.p[i] ^= next_u32_wrap(key, &mut key_pos);
223        }
224        let mut l = 0u32;
225        let mut r = 0u32;
226        for i in (0..18).step_up(2) {
227            let (new_l, new_r) = self.encrypt(l, r);
228            l = new_l;
229            r = new_r;
230            self.p[i] = l;
231            self.p[i+1] = r;
232        }
233        for i in 0..4 {
234            for j in (0..256).step_up(2) {
235                let (new_l, new_r) = self.encrypt(l, r);
236                l = new_l;
237                r = new_r;
238                self.s[i][j] = l;
239                self.s[i][j+1] = r;
240            }
241        }
242    }
243
244    // Bcrypt key schedule.
245    pub fn salted_expand_key(&mut self, salt: &[u8], key: &[u8]) {
246        let mut key_pos = 0;
247        for i in 0..18 {
248            self.p[i] ^= next_u32_wrap(key, &mut key_pos);
249        }
250        let mut l = 0u32;
251        let mut r = 0u32;
252        let mut salt_pos = 0;
253        for i in (0..18).step_up(2) {
254            let (new_l, new_r) = self.encrypt(l ^ next_u32_wrap(salt, &mut salt_pos), r ^ next_u32_wrap(salt, &mut salt_pos));
255            l = new_l;
256            r = new_r;
257            self.p[i] = l;
258            self.p[i+1] = r;
259        }
260        for i in 0..4 {
261            for j in (0..256).step_up(4) {
262                let (new_l, new_r) = self.encrypt(l ^ next_u32_wrap(salt, &mut salt_pos), r ^ next_u32_wrap(salt, &mut salt_pos));
263                l = new_l;
264                r = new_r;
265                self.s[i][j] = l;
266                self.s[i][j+1] = r;
267
268                let (new_l, new_r) = self.encrypt(l ^ next_u32_wrap(salt, &mut salt_pos), r ^ next_u32_wrap(salt, &mut salt_pos));
269                l = new_l;
270                r = new_r;
271                self.s[i][j+2] = l;
272                self.s[i][j+3] = r;
273            }
274        }
275    }
276
277    fn round_function(&self, x: u32) -> u32 {
278        ((self.s[0][(x >> 24) as usize].wrapping_add(self.s[1][((x >> 16) & 0xff) as usize])) ^ self.s[2][((x >> 8) & 0xff) as usize]).wrapping_add(self.s[3][(x & 0xff) as usize])
279    }
280
281    // Public for bcrypt.
282    pub fn encrypt(&self, mut l: u32, mut r: u32) -> (u32, u32) {
283        for i in (0..16).step_up(2) {
284            l ^= self.p[i];
285            r ^= self.round_function(l);
286            r ^= self.p[i+1];
287            l ^= self.round_function(r);
288        }
289        l ^= self.p[16];
290        r ^= self.p[17];
291        (r, l)
292    }
293
294    fn decrypt(&self, mut l: u32, mut r: u32) -> (u32, u32) {
295        let mut i = 16;
296        while i > 0 {
297            l ^= self.p[i+1];
298            r ^= self.round_function(l);
299            r ^= self.p[i];
300            l ^= self.round_function(r);
301            i -= 2;
302        }
303        l ^= self.p[1];
304        r ^= self.p[0];
305        (r, l)
306    }
307}
308
309impl BlockEncryptor for Blowfish {
310    fn block_size(&self) -> usize {
311        8
312    }
313
314    fn encrypt_block(&self, input: &[u8], output: &mut [u8]) {
315        assert!(input.len() == 8);
316        assert!(output.len() == 8);
317        let mut block = [0u32, 0u32];
318        read_u32v_be(&mut block, input);
319        let (l, r) = self.encrypt(block[0], block[1]);
320        write_u32_be(&mut output[0..4], l);
321        write_u32_be(&mut output[4..8], r);
322    }
323}
324
325impl BlockDecryptor for Blowfish {
326    fn block_size(&self) -> usize {
327        8
328    }
329
330    fn decrypt_block(&self, input: &[u8], output: &mut [u8]) {
331        assert!(input.len() == 8);
332        assert!(output.len() == 8);
333        let mut block = [0u32, 0u32];
334        read_u32v_be(&mut block, input);
335        let (l, r) = self.decrypt(block[0], block[1]);
336        write_u32_be(&mut output[0..4], l);
337        write_u32_be(&mut output[4..8], r);
338    }
339}
340
341#[cfg(test)]
342mod test {
343    use blowfish::Blowfish;
344    use symmetriccipher::{BlockEncryptor, BlockDecryptor};
345    struct Test {
346        key: Vec<u8>,
347        plaintext: Vec<u8>,
348        ciphertext: Vec<u8>
349    }
350
351    fn eay_test_vectors() -> Vec<Test> {
352        vec![
353            Test {
354                    key: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
355                    plaintext: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
356                    ciphertext: vec![0x4Eu8, 0xF9u8, 0x97u8, 0x45u8, 0x61u8, 0x98u8, 0xDDu8, 0x78u8]
357            },
358            Test {
359                    key: vec![0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8],
360                    plaintext: vec![0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8],
361                    ciphertext: vec![0x51u8, 0x86u8, 0x6Fu8, 0xD5u8, 0xB8u8, 0x5Eu8, 0xCBu8, 0x8Au8]
362            },
363            Test {
364                    key: vec![0x30u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
365                    plaintext: vec![0x10u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x01u8],
366                    ciphertext: vec![0x7Du8, 0x85u8, 0x6Fu8, 0x9Au8, 0x61u8, 0x30u8, 0x63u8, 0xF2u8]
367            },
368            Test {
369                    key: vec![0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8],
370                    plaintext: vec![0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8],
371                    ciphertext: vec![0x24u8, 0x66u8, 0xDDu8, 0x87u8, 0x8Bu8, 0x96u8, 0x3Cu8, 0x9Du8]
372            },
373            Test {
374                    key: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
375                    plaintext: vec![0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8],
376                    ciphertext: vec![0x61u8, 0xF9u8, 0xC3u8, 0x80u8, 0x22u8, 0x81u8, 0xB0u8, 0x96u8]
377            },
378            Test {
379                    key: vec![0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8, 0x11u8],
380                    plaintext: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
381                    ciphertext: vec![0x7Du8, 0x0Cu8, 0xC6u8, 0x30u8, 0xAFu8, 0xDAu8, 0x1Eu8, 0xC7u8]
382            },
383            Test {
384                    key: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
385                    plaintext: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
386                    ciphertext: vec![0x4Eu8, 0xF9u8, 0x97u8, 0x45u8, 0x61u8, 0x98u8, 0xDDu8, 0x78u8]
387            },
388            Test {
389                    key: vec![0xFEu8, 0xDCu8, 0xBAu8, 0x98u8, 0x76u8, 0x54u8, 0x32u8, 0x10u8],
390                    plaintext: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
391                    ciphertext: vec![0x0Au8, 0xCEu8, 0xABu8, 0x0Fu8, 0xC6u8, 0xA0u8, 0xA2u8, 0x8Du8]
392            },
393            Test {
394                    key: vec![0x7Cu8, 0xA1u8, 0x10u8, 0x45u8, 0x4Au8, 0x1Au8, 0x6Eu8, 0x57u8],
395                    plaintext: vec![0x01u8, 0xA1u8, 0xD6u8, 0xD0u8, 0x39u8, 0x77u8, 0x67u8, 0x42u8],
396                    ciphertext: vec![0x59u8, 0xC6u8, 0x82u8, 0x45u8, 0xEBu8, 0x05u8, 0x28u8, 0x2Bu8]
397            },
398            Test {
399                    key: vec![0x01u8, 0x31u8, 0xD9u8, 0x61u8, 0x9Du8, 0xC1u8, 0x37u8, 0x6Eu8],
400                    plaintext: vec![0x5Cu8, 0xD5u8, 0x4Cu8, 0xA8u8, 0x3Du8, 0xEFu8, 0x57u8, 0xDAu8],
401                    ciphertext: vec![0xB1u8, 0xB8u8, 0xCCu8, 0x0Bu8, 0x25u8, 0x0Fu8, 0x09u8, 0xA0u8]
402            },
403            Test {
404                    key: vec![0x07u8, 0xA1u8, 0x13u8, 0x3Eu8, 0x4Au8, 0x0Bu8, 0x26u8, 0x86u8],
405                    plaintext: vec![0x02u8, 0x48u8, 0xD4u8, 0x38u8, 0x06u8, 0xF6u8, 0x71u8, 0x72u8],
406                    ciphertext: vec![0x17u8, 0x30u8, 0xE5u8, 0x77u8, 0x8Bu8, 0xEAu8, 0x1Du8, 0xA4u8]
407            },
408            Test {
409                    key: vec![0x38u8, 0x49u8, 0x67u8, 0x4Cu8, 0x26u8, 0x02u8, 0x31u8, 0x9Eu8],
410                    plaintext: vec![0x51u8, 0x45u8, 0x4Bu8, 0x58u8, 0x2Du8, 0xDFu8, 0x44u8, 0x0Au8],
411                    ciphertext: vec![0xA2u8, 0x5Eu8, 0x78u8, 0x56u8, 0xCFu8, 0x26u8, 0x51u8, 0xEBu8]
412            },
413            Test {
414                    key: vec![0x04u8, 0xB9u8, 0x15u8, 0xBAu8, 0x43u8, 0xFEu8, 0xB5u8, 0xB6u8],
415                    plaintext: vec![0x42u8, 0xFDu8, 0x44u8, 0x30u8, 0x59u8, 0x57u8, 0x7Fu8, 0xA2u8],
416                    ciphertext: vec![0x35u8, 0x38u8, 0x82u8, 0xB1u8, 0x09u8, 0xCEu8, 0x8Fu8, 0x1Au8]
417            },
418            Test {
419                    key: vec![0x01u8, 0x13u8, 0xB9u8, 0x70u8, 0xFDu8, 0x34u8, 0xF2u8, 0xCEu8],
420                    plaintext: vec![0x05u8, 0x9Bu8, 0x5Eu8, 0x08u8, 0x51u8, 0xCFu8, 0x14u8, 0x3Au8],
421                    ciphertext: vec![0x48u8, 0xF4u8, 0xD0u8, 0x88u8, 0x4Cu8, 0x37u8, 0x99u8, 0x18u8]
422            },
423            Test {
424                    key: vec![0x01u8, 0x70u8, 0xF1u8, 0x75u8, 0x46u8, 0x8Fu8, 0xB5u8, 0xE6u8],
425                    plaintext: vec![0x07u8, 0x56u8, 0xD8u8, 0xE0u8, 0x77u8, 0x47u8, 0x61u8, 0xD2u8],
426                    ciphertext: vec![0x43u8, 0x21u8, 0x93u8, 0xB7u8, 0x89u8, 0x51u8, 0xFCu8, 0x98u8]
427            },
428            Test {
429                    key: vec![0x43u8, 0x29u8, 0x7Fu8, 0xADu8, 0x38u8, 0xE3u8, 0x73u8, 0xFEu8],
430                    plaintext: vec![0x76u8, 0x25u8, 0x14u8, 0xB8u8, 0x29u8, 0xBFu8, 0x48u8, 0x6Au8],
431                    ciphertext: vec![0x13u8, 0xF0u8, 0x41u8, 0x54u8, 0xD6u8, 0x9Du8, 0x1Au8, 0xE5u8]
432            },
433            Test {
434                    key: vec![0x07u8, 0xA7u8, 0x13u8, 0x70u8, 0x45u8, 0xDAu8, 0x2Au8, 0x16u8],
435                    plaintext: vec![0x3Bu8, 0xDDu8, 0x11u8, 0x90u8, 0x49u8, 0x37u8, 0x28u8, 0x02u8],
436                    ciphertext: vec![0x2Eu8, 0xEDu8, 0xDAu8, 0x93u8, 0xFFu8, 0xD3u8, 0x9Cu8, 0x79u8]
437            },
438            Test {
439                    key: vec![0x04u8, 0x68u8, 0x91u8, 0x04u8, 0xC2u8, 0xFDu8, 0x3Bu8, 0x2Fu8],
440                    plaintext: vec![0x26u8, 0x95u8, 0x5Fu8, 0x68u8, 0x35u8, 0xAFu8, 0x60u8, 0x9Au8],
441                    ciphertext: vec![0xD8u8, 0x87u8, 0xE0u8, 0x39u8, 0x3Cu8, 0x2Du8, 0xA6u8, 0xE3u8]
442            },
443            Test {
444                    key: vec![0x37u8, 0xD0u8, 0x6Bu8, 0xB5u8, 0x16u8, 0xCBu8, 0x75u8, 0x46u8],
445                    plaintext: vec![0x16u8, 0x4Du8, 0x5Eu8, 0x40u8, 0x4Fu8, 0x27u8, 0x52u8, 0x32u8],
446                    ciphertext: vec![0x5Fu8, 0x99u8, 0xD0u8, 0x4Fu8, 0x5Bu8, 0x16u8, 0x39u8, 0x69u8]
447            },
448            Test {
449                    key: vec![0x1Fu8, 0x08u8, 0x26u8, 0x0Du8, 0x1Au8, 0xC2u8, 0x46u8, 0x5Eu8],
450                    plaintext: vec![0x6Bu8, 0x05u8, 0x6Eu8, 0x18u8, 0x75u8, 0x9Fu8, 0x5Cu8, 0xCAu8],
451                    ciphertext: vec![0x4Au8, 0x05u8, 0x7Au8, 0x3Bu8, 0x24u8, 0xD3u8, 0x97u8, 0x7Bu8]
452            },
453            Test {
454                    key: vec![0x58u8, 0x40u8, 0x23u8, 0x64u8, 0x1Au8, 0xBAu8, 0x61u8, 0x76u8],
455                    plaintext: vec![0x00u8, 0x4Bu8, 0xD6u8, 0xEFu8, 0x09u8, 0x17u8, 0x60u8, 0x62u8],
456                    ciphertext: vec![0x45u8, 0x20u8, 0x31u8, 0xC1u8, 0xE4u8, 0xFAu8, 0xDAu8, 0x8Eu8]
457            },
458            Test {
459                    key: vec![0x02u8, 0x58u8, 0x16u8, 0x16u8, 0x46u8, 0x29u8, 0xB0u8, 0x07u8],
460                    plaintext: vec![0x48u8, 0x0Du8, 0x39u8, 0x00u8, 0x6Eu8, 0xE7u8, 0x62u8, 0xF2u8],
461                    ciphertext: vec![0x75u8, 0x55u8, 0xAEu8, 0x39u8, 0xF5u8, 0x9Bu8, 0x87u8, 0xBDu8]
462            },
463            Test {
464                    key: vec![0x49u8, 0x79u8, 0x3Eu8, 0xBCu8, 0x79u8, 0xB3u8, 0x25u8, 0x8Fu8],
465                    plaintext: vec![0x43u8, 0x75u8, 0x40u8, 0xC8u8, 0x69u8, 0x8Fu8, 0x3Cu8, 0xFAu8],
466                    ciphertext: vec![0x53u8, 0xC5u8, 0x5Fu8, 0x9Cu8, 0xB4u8, 0x9Fu8, 0xC0u8, 0x19u8]
467            },
468            Test {
469                    key: vec![0x4Fu8, 0xB0u8, 0x5Eu8, 0x15u8, 0x15u8, 0xABu8, 0x73u8, 0xA7u8],
470                    plaintext: vec![0x07u8, 0x2Du8, 0x43u8, 0xA0u8, 0x77u8, 0x07u8, 0x52u8, 0x92u8],
471                    ciphertext: vec![0x7Au8, 0x8Eu8, 0x7Bu8, 0xFAu8, 0x93u8, 0x7Eu8, 0x89u8, 0xA3u8]
472            },
473            Test {
474                    key: vec![0x49u8, 0xE9u8, 0x5Du8, 0x6Du8, 0x4Cu8, 0xA2u8, 0x29u8, 0xBFu8],
475                    plaintext: vec![0x02u8, 0xFEu8, 0x55u8, 0x77u8, 0x81u8, 0x17u8, 0xF1u8, 0x2Au8],
476                    ciphertext: vec![0xCFu8, 0x9Cu8, 0x5Du8, 0x7Au8, 0x49u8, 0x86u8, 0xADu8, 0xB5u8]
477            },
478            Test {
479                    key: vec![0x01u8, 0x83u8, 0x10u8, 0xDCu8, 0x40u8, 0x9Bu8, 0x26u8, 0xD6u8],
480                    plaintext: vec![0x1Du8, 0x9Du8, 0x5Cu8, 0x50u8, 0x18u8, 0xF7u8, 0x28u8, 0xC2u8],
481                    ciphertext: vec![0xD1u8, 0xABu8, 0xB2u8, 0x90u8, 0x65u8, 0x8Bu8, 0xC7u8, 0x78u8]
482            },
483            Test {
484                    key: vec![0x1Cu8, 0x58u8, 0x7Fu8, 0x1Cu8, 0x13u8, 0x92u8, 0x4Fu8, 0xEFu8],
485                    plaintext: vec![0x30u8, 0x55u8, 0x32u8, 0x28u8, 0x6Du8, 0x6Fu8, 0x29u8, 0x5Au8],
486                    ciphertext: vec![0x55u8, 0xCBu8, 0x37u8, 0x74u8, 0xD1u8, 0x3Eu8, 0xF2u8, 0x01u8]
487            },
488            Test {
489                    key: vec![0x01u8, 0x01u8, 0x01u8, 0x01u8, 0x01u8, 0x01u8, 0x01u8, 0x01u8],
490                    plaintext: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
491                    ciphertext: vec![0xFAu8, 0x34u8, 0xECu8, 0x48u8, 0x47u8, 0xB2u8, 0x68u8, 0xB2u8]
492            },
493            Test {
494                    key: vec![0x1Fu8, 0x1Fu8, 0x1Fu8, 0x1Fu8, 0x0Eu8, 0x0Eu8, 0x0Eu8, 0x0Eu8],
495                    plaintext: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
496                    ciphertext: vec![0xA7u8, 0x90u8, 0x79u8, 0x51u8, 0x08u8, 0xEAu8, 0x3Cu8, 0xAEu8]
497            },
498            Test {
499                    key: vec![0xE0u8, 0xFEu8, 0xE0u8, 0xFEu8, 0xF1u8, 0xFEu8, 0xF1u8, 0xFEu8],
500                    plaintext: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
501                    ciphertext: vec![0xC3u8, 0x9Eu8, 0x07u8, 0x2Du8, 0x9Fu8, 0xACu8, 0x63u8, 0x1Du8]
502            },
503            Test {
504                    key: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
505                    plaintext: vec![0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8],
506                    ciphertext: vec![0x01u8, 0x49u8, 0x33u8, 0xE0u8, 0xCDu8, 0xAFu8, 0xF6u8, 0xE4u8]
507            },
508            Test {
509                    key: vec![0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8],
510                    plaintext: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
511                    ciphertext: vec![0xF2u8, 0x1Eu8, 0x9Au8, 0x77u8, 0xB7u8, 0x1Cu8, 0x49u8, 0xBCu8]
512            },
513            Test {
514                    key: vec![0x01u8, 0x23u8, 0x45u8, 0x67u8, 0x89u8, 0xABu8, 0xCDu8, 0xEFu8],
515                    plaintext: vec![0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8, 0x00u8],
516                    ciphertext: vec![0x24u8, 0x59u8, 0x46u8, 0x88u8, 0x57u8, 0x54u8, 0x36u8, 0x9Au8]
517            },
518            Test {
519                    key: vec![0xFEu8, 0xDCu8, 0xBAu8, 0x98u8, 0x76u8, 0x54u8, 0x32u8, 0x10u8],
520                    plaintext: vec![0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8],
521                    ciphertext: vec![0x6Bu8, 0x5Cu8, 0x5Au8, 0x9Cu8, 0x5Du8, 0x9Eu8, 0x0Au8, 0x5Au8]
522            }
523        ]
524    }
525
526    #[test]
527    fn encrypt_eay_test_vectors() {
528        let tests = eay_test_vectors();
529        let mut output = [0u8; 8];
530        for test in tests.iter() {
531            let state = Blowfish::new(&test.key[..]);
532            state.encrypt_block(&test.plaintext[..], &mut output[..]);
533            assert!(test.ciphertext[..] == output[..]);
534        }
535    }
536
537    #[test]
538    fn decrypt_eay_test_vectors() {
539        let tests = eay_test_vectors();
540        let mut output = [0u8; 8];
541        for test in tests.iter() {
542            let state = Blowfish::new(&test.key[..]);
543            state.decrypt_block(&test.ciphertext[..], &mut output[..]);
544            assert!(test.plaintext[..] == output[..]);
545        }
546    }
547}
548
549#[cfg(all(test, feature = "with-bench"))]
550mod bench {
551    use blowfish::Blowfish;
552    use symmetriccipher::BlockEncryptor;
553    use test::Bencher;
554
555    #[bench]
556    fn blowfish(bh: &mut Bencher) {
557        let key = [0u8; 16];
558        let plaintext = [1u8; 8];
559        let state = Blowfish::new(&key);
560        let mut ciphertext = [0u8; 8];
561
562        bh.iter(|| {
563            state.encrypt_block(&plaintext, &mut ciphertext);
564        });
565        bh.bytes = 8u64;
566    }
567}