Mercurial > dropbear
comparison libtomcrypt/src/ciphers/multi2.c @ 1471:6dba84798cd5
Update to libtomcrypt 1.18.1, merged with Dropbear changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 21:44:05 +0800 |
parents | f849a5ca2efc |
children |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
3 * LibTomCrypt is a library that provides various cryptographic | 3 * LibTomCrypt is a library that provides various cryptographic |
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | |
9 * Tom St Denis, [email protected], http://libtom.org | |
10 */ | 8 */ |
11 | 9 |
12 /** | 10 /** |
13 @file multi2.c | 11 @file multi2.c |
14 Multi-2 implementation (not public domain, hence the default disable) | 12 Multi-2 implementation (not public domain, hence the default disable) |
56 int n, t; | 54 int n, t; |
57 ulong32 p[2]; | 55 ulong32 p[2]; |
58 | 56 |
59 p[0] = dk[0]; p[1] = dk[1]; | 57 p[0] = dk[0]; p[1] = dk[1]; |
60 | 58 |
61 t = 4; | 59 t = 4; |
62 n = 0; | 60 n = 0; |
63 pi1(p); | 61 pi1(p); |
64 pi2(p, k); | 62 pi2(p, k); |
65 uk[n++] = p[0]; | 63 uk[n++] = p[0]; |
66 pi3(p, k); | 64 pi3(p, k); |
81 | 79 |
82 static void encrypt(ulong32 *p, int N, ulong32 *uk) | 80 static void encrypt(ulong32 *p, int N, ulong32 *uk) |
83 { | 81 { |
84 int n, t; | 82 int n, t; |
85 for (t = n = 0; ; ) { | 83 for (t = n = 0; ; ) { |
86 pi1(p); if (++n == N) break; | 84 pi1(p); if (++n == N) break; |
87 pi2(p, uk+t); if (++n == N) break; | 85 pi2(p, uk+t); if (++n == N) break; |
88 pi3(p, uk+t); if (++n == N) break; | 86 pi3(p, uk+t); if (++n == N) break; |
89 pi4(p, uk+t); if (++n == N) break; | 87 pi4(p, uk+t); if (++n == N) break; |
90 t ^= 4; | 88 t ^= 4; |
91 } | 89 } |
92 } | 90 } |
93 | 91 |
94 static void decrypt(ulong32 *p, int N, ulong32 *uk) | 92 static void decrypt(ulong32 *p, int N, ulong32 *uk) |
95 { | 93 { |
96 int n, t; | 94 int n, t; |
97 for (t = 4*((N&1)^1), n = N; ; ) { | 95 for (t = 4*(((N-1)>>2)&1), n = N; ; ) { |
98 switch (n >= 4 ? 4 : 0) { | 96 switch (n<=4 ? n : ((n-1)%4)+1) { |
99 case 4: pi4(p, uk+t); --n; | 97 case 4: pi4(p, uk+t); --n; /* FALLTHROUGH */ |
100 case 3: pi3(p, uk+t); --n; | 98 case 3: pi3(p, uk+t); --n; /* FALLTHROUGH */ |
101 case 2: pi2(p, uk+t); --n; | 99 case 2: pi2(p, uk+t); --n; /* FALLTHROUGH */ |
102 case 1: pi1(p); --n; break; | 100 case 1: pi1(p); --n; break; |
103 case 0: return; | 101 case 0: return; |
104 } | 102 } |
105 t ^= 4; | 103 t ^= 4; |
106 } | 104 } |
107 } | 105 } |
108 | 106 |
109 const struct ltc_cipher_descriptor multi2_desc = { | 107 const struct ltc_cipher_descriptor multi2_desc = { |
110 "multi2", | 108 "multi2", |
111 22, | 109 22, |
112 40, 40, 8, 128, | 110 40, 40, 8, 128, |
114 &multi2_ecb_encrypt, | 112 &multi2_ecb_encrypt, |
115 &multi2_ecb_decrypt, | 113 &multi2_ecb_decrypt, |
116 &multi2_test, | 114 &multi2_test, |
117 &multi2_done, | 115 &multi2_done, |
118 &multi2_keysize, | 116 &multi2_keysize, |
119 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | 117 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL |
120 }; | 118 }; |
121 | 119 |
122 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | 120 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) |
123 { | 121 { |
124 ulong32 sk[8], dk[2]; | 122 ulong32 sk[8], dk[2]; |
127 LTC_ARGCHK(key != NULL); | 125 LTC_ARGCHK(key != NULL); |
128 LTC_ARGCHK(skey != NULL); | 126 LTC_ARGCHK(skey != NULL); |
129 | 127 |
130 if (keylen != 40) return CRYPT_INVALID_KEYSIZE; | 128 if (keylen != 40) return CRYPT_INVALID_KEYSIZE; |
131 if (num_rounds == 0) num_rounds = 128; | 129 if (num_rounds == 0) num_rounds = 128; |
132 | 130 |
133 skey->multi2.N = num_rounds; | 131 skey->multi2.N = num_rounds; |
134 for (x = 0; x < 8; x++) { | 132 for (x = 0; x < 8; x++) { |
135 LOAD32H(sk[x], key + x*4); | 133 LOAD32H(sk[x], key + x*4); |
136 } | 134 } |
137 LOAD32H(dk[0], key + 32); | 135 LOAD32H(dk[0], key + 32); |
157 LTC_ARGCHK(ct != NULL); | 155 LTC_ARGCHK(ct != NULL); |
158 LTC_ARGCHK(skey != NULL); | 156 LTC_ARGCHK(skey != NULL); |
159 LOAD32H(p[0], pt); | 157 LOAD32H(p[0], pt); |
160 LOAD32H(p[1], pt+4); | 158 LOAD32H(p[1], pt+4); |
161 encrypt(p, skey->multi2.N, skey->multi2.uk); | 159 encrypt(p, skey->multi2.N, skey->multi2.uk); |
162 STORE32H(p[0], ct); | 160 STORE32H(p[0], ct); |
163 STORE32H(p[1], ct+4); | 161 STORE32H(p[1], ct+4); |
164 return CRYPT_OK; | 162 return CRYPT_OK; |
165 } | 163 } |
166 | 164 |
167 /** | 165 /** |
178 LTC_ARGCHK(ct != NULL); | 176 LTC_ARGCHK(ct != NULL); |
179 LTC_ARGCHK(skey != NULL); | 177 LTC_ARGCHK(skey != NULL); |
180 LOAD32H(p[0], ct); | 178 LOAD32H(p[0], ct); |
181 LOAD32H(p[1], ct+4); | 179 LOAD32H(p[1], ct+4); |
182 decrypt(p, skey->multi2.N, skey->multi2.uk); | 180 decrypt(p, skey->multi2.N, skey->multi2.uk); |
183 STORE32H(p[0], pt); | 181 STORE32H(p[0], pt); |
184 STORE32H(p[1], pt+4); | 182 STORE32H(p[1], pt+4); |
185 return CRYPT_OK; | 183 return CRYPT_OK; |
186 } | 184 } |
187 | 185 |
188 /** | 186 /** |
205 | 203 |
206 0x00, 0x00, 0x00, 0x00, | 204 0x00, 0x00, 0x00, 0x00, |
207 0x00, 0x00, 0x00, 0x00, | 205 0x00, 0x00, 0x00, 0x00, |
208 0x00, 0x00, 0x00, 0x00, | 206 0x00, 0x00, 0x00, 0x00, |
209 0x00, 0x00, 0x00, 0x00, | 207 0x00, 0x00, 0x00, 0x00, |
210 | 208 |
211 0x01, 0x23, 0x45, 0x67, | 209 0x01, 0x23, 0x45, 0x67, |
212 0x89, 0xAB, 0xCD, 0xEF | 210 0x89, 0xAB, 0xCD, 0xEF |
213 }, | 211 }, |
214 { | 212 { |
215 0x00, 0x00, 0x00, 0x00, | 213 0x00, 0x00, 0x00, 0x00, |
233 0x36, 0x35, 0xd0, 0x67, | 231 0x36, 0x35, 0xd0, 0x67, |
234 | 232 |
235 0xb1, 0x27, 0xb9, 0x06, | 233 0xb1, 0x27, 0xb9, 0x06, |
236 0xe7, 0x56, 0x22, 0x38, | 234 0xe7, 0x56, 0x22, 0x38, |
237 }, | 235 }, |
238 { | 236 { |
239 0x1f, 0xb4, 0x60, 0x60, | 237 0x1f, 0xb4, 0x60, 0x60, |
240 0xd0, 0xb3, 0x4f, 0xa5 | 238 0xd0, 0xb3, 0x4f, 0xa5 |
241 }, | 239 }, |
242 { | 240 { |
243 0xca, 0x84, 0xa9, 0x34, | 241 0xca, 0x84, 0xa9, 0x34, |
256 } | 254 } |
257 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { | 255 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { |
258 return err; | 256 return err; |
259 } | 257 } |
260 | 258 |
261 if (XMEMCMP(buf, tests[x].ct, 8)) { | 259 if (compare_testvector(buf, 8, tests[x].ct, 8, "Multi2 Encrypt", x)) { |
262 return CRYPT_FAIL_TESTVECTOR; | 260 return CRYPT_FAIL_TESTVECTOR; |
263 } | 261 } |
264 | 262 |
265 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { | 263 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { |
266 return err; | 264 return err; |
267 } | 265 } |
268 if (XMEMCMP(buf, tests[x].pt, 8)) { | 266 if (compare_testvector(buf, 8, tests[x].pt, 8, "Multi2 Decrypt", x)) { |
269 return CRYPT_FAIL_TESTVECTOR; | 267 return CRYPT_FAIL_TESTVECTOR; |
270 } | 268 } |
271 } | 269 } |
272 | 270 |
273 return CRYPT_OK; | 271 for (x = 128; x < 256; ++x) { |
274 } | 272 unsigned char ct[8]; |
275 | 273 |
276 /** Terminate the context | 274 if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) { |
275 return err; | |
276 } | |
277 if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) { | |
278 return err; | |
279 } | |
280 if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) { | |
281 return err; | |
282 } | |
283 if (compare_testvector(buf, 8, tests[0].pt, 8, "Multi2 Rounds", x)) { | |
284 return CRYPT_FAIL_TESTVECTOR; | |
285 } | |
286 } | |
287 | |
288 return CRYPT_OK; | |
289 } | |
290 | |
291 /** Terminate the context | |
277 @param skey The scheduled key | 292 @param skey The scheduled key |
278 */ | 293 */ |
279 void multi2_done(symmetric_key *skey) | 294 void multi2_done(symmetric_key *skey) |
280 { | 295 { |
296 LTC_UNUSED_PARAM(skey); | |
281 } | 297 } |
282 | 298 |
283 /** | 299 /** |
284 Gets suitable key size | 300 Gets suitable key size |
285 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. | 301 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. |
296 return CRYPT_OK; | 312 return CRYPT_OK; |
297 } | 313 } |
298 | 314 |
299 #endif | 315 #endif |
300 | 316 |
301 /* $Source$ */ | 317 /* ref: $Format:%D$ */ |
302 /* $Revision$ */ | 318 /* git commit: $Format:%H$ */ |
303 /* $Date$ */ | 319 /* commit time: $Format:%ai$ */ |