serpent.cpp
00001
00002
00003
#include "pch.h"
00004
#include "serpent.h"
00005
#include "misc.h"
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009
00010 #define LT(i,a,b,c,d,e) {\
00011 a = rotlFixed(a, 13); \
00012 c = rotlFixed(c, 3); \
00013 d = rotlFixed(d ^ c ^ (a << 3), 7); \
00014 b = rotlFixed(b ^ a ^ c, 1); \
00015 a = rotlFixed(a ^ b ^ d, 5); \
00016 c = rotlFixed(c ^ d ^ (b << 7), 22);}
00017
00018
00019
#define ILT(i,a,b,c,d,e) {\
00020
c = rotrFixed(c, 22); \
00021
a = rotrFixed(a, 5); \
00022
c ^= d ^ (b << 7); \
00023
a ^= b ^ d; \
00024
b = rotrFixed(b, 1); \
00025
d = rotrFixed(d, 7) ^ c ^ (a << 3); \
00026
b ^= a ^ c; \
00027
c = rotrFixed(c, 3); \
00028
a = rotrFixed(a, 13);}
00029
00030
00031
#define beforeS0(f) f(0,a,b,c,d,e)
00032
#define afterS0(f) f(1,b,e,c,a,d)
00033
#define afterS1(f) f(2,c,b,a,e,d)
00034
#define afterS2(f) f(3,a,e,b,d,c)
00035
#define afterS3(f) f(4,e,b,d,c,a)
00036
#define afterS4(f) f(5,b,a,e,c,d)
00037
#define afterS5(f) f(6,a,c,b,e,d)
00038
#define afterS6(f) f(7,a,c,d,b,e)
00039
#define afterS7(f) f(8,d,e,b,a,c)
00040
00041
00042
#define beforeI7(f) f(8,a,b,c,d,e)
00043
#define afterI7(f) f(7,d,a,b,e,c)
00044
#define afterI6(f) f(6,a,b,c,e,d)
00045
#define afterI5(f) f(5,b,d,e,c,a)
00046
#define afterI4(f) f(4,b,c,e,a,d)
00047
#define afterI3(f) f(3,a,b,e,c,d)
00048
#define afterI2(f) f(2,b,d,e,c,a)
00049
#define afterI1(f) f(1,a,b,c,e,d)
00050
#define afterI0(f) f(0,a,d,b,e,c)
00051
00052
00053
00054
00055
#define S0(i, r0, r1, r2, r3, r4) \
00056
{ \
00057
r3 ^= r0; \
00058
r4 = r1; \
00059
r1 &= r3; \
00060
r4 ^= r2; \
00061
r1 ^= r0; \
00062
r0 |= r3; \
00063
r0 ^= r4; \
00064
r4 ^= r3; \
00065
r3 ^= r2; \
00066
r2 |= r1; \
00067
r2 ^= r4; \
00068
r4 = ~r4; \
00069
r4 |= r1; \
00070
r1 ^= r3; \
00071
r1 ^= r4; \
00072
r3 |= r0; \
00073
r1 ^= r3; \
00074
r4 ^= r3; \
00075
}
00076
00077
#define I0(i, r0, r1, r2, r3, r4) \
00078
{ \
00079
r2 = ~r2; \
00080
r4 = r1; \
00081
r1 |= r0; \
00082
r4 = ~r4; \
00083
r1 ^= r2; \
00084
r2 |= r4; \
00085
r1 ^= r3; \
00086
r0 ^= r4; \
00087
r2 ^= r0; \
00088
r0 &= r3; \
00089
r4 ^= r0; \
00090
r0 |= r1; \
00091
r0 ^= r2; \
00092
r3 ^= r4; \
00093
r2 ^= r1; \
00094
r3 ^= r0; \
00095
r3 ^= r1; \
00096
r2 &= r3; \
00097
r4 ^= r2; \
00098
}
00099
00100
#define S1(i, r0, r1, r2, r3, r4) \
00101
{ \
00102
r0 = ~r0; \
00103
r2 = ~r2; \
00104
r4 = r0; \
00105
r0 &= r1; \
00106
r2 ^= r0; \
00107
r0 |= r3; \
00108
r3 ^= r2; \
00109
r1 ^= r0; \
00110
r0 ^= r4; \
00111
r4 |= r1; \
00112
r1 ^= r3; \
00113
r2 |= r0; \
00114
r2 &= r4; \
00115
r0 ^= r1; \
00116
r1 &= r2; \
00117
r1 ^= r0; \
00118
r0 &= r2; \
00119
r0 ^= r4; \
00120
}
00121
00122
#define I1(i, r0, r1, r2, r3, r4) \
00123
{ \
00124
r4 = r1; \
00125
r1 ^= r3; \
00126
r3 &= r1; \
00127
r4 ^= r2; \
00128
r3 ^= r0; \
00129
r0 |= r1; \
00130
r2 ^= r3; \
00131
r0 ^= r4; \
00132
r0 |= r2; \
00133
r1 ^= r3; \
00134
r0 ^= r1; \
00135
r1 |= r3; \
00136
r1 ^= r0; \
00137
r4 = ~r4; \
00138
r4 ^= r1; \
00139
r1 |= r0; \
00140
r1 ^= r0; \
00141
r1 |= r4; \
00142
r3 ^= r1; \
00143
}
00144
00145
#define S2(i, r0, r1, r2, r3, r4) \
00146
{ \
00147
r4 = r0; \
00148
r0 &= r2; \
00149
r0 ^= r3; \
00150
r2 ^= r1; \
00151
r2 ^= r0; \
00152
r3 |= r4; \
00153
r3 ^= r1; \
00154
r4 ^= r2; \
00155
r1 = r3; \
00156
r3 |= r4; \
00157
r3 ^= r0; \
00158
r0 &= r1; \
00159
r4 ^= r0; \
00160
r1 ^= r3; \
00161
r1 ^= r4; \
00162
r4 = ~r4; \
00163
}
00164
00165
#define I2(i, r0, r1, r2, r3, r4) \
00166
{ \
00167
r2 ^= r3; \
00168
r3 ^= r0; \
00169
r4 = r3; \
00170
r3 &= r2; \
00171
r3 ^= r1; \
00172
r1 |= r2; \
00173
r1 ^= r4; \
00174
r4 &= r3; \
00175
r2 ^= r3; \
00176
r4 &= r0; \
00177
r4 ^= r2; \
00178
r2 &= r1; \
00179
r2 |= r0; \
00180
r3 = ~r3; \
00181
r2 ^= r3; \
00182
r0 ^= r3; \
00183
r0 &= r1; \
00184
r3 ^= r4; \
00185
r3 ^= r0; \
00186
}
00187
00188
#define S3(i, r0, r1, r2, r3, r4) \
00189
{ \
00190
r4 = r0; \
00191
r0 |= r3; \
00192
r3 ^= r1; \
00193
r1 &= r4; \
00194
r4 ^= r2; \
00195
r2 ^= r3; \
00196
r3 &= r0; \
00197
r4 |= r1; \
00198
r3 ^= r4; \
00199
r0 ^= r1; \
00200
r4 &= r0; \
00201
r1 ^= r3; \
00202
r4 ^= r2; \
00203
r1 |= r0; \
00204
r1 ^= r2; \
00205
r0 ^= r3; \
00206
r2 = r1; \
00207
r1 |= r3; \
00208
r1 ^= r0; \
00209
}
00210
00211
#define I3(i, r0, r1, r2, r3, r4) \
00212
{ \
00213
r4 = r2; \
00214
r2 ^= r1; \
00215
r1 &= r2; \
00216
r1 ^= r0; \
00217
r0 &= r4; \
00218
r4 ^= r3; \
00219
r3 |= r1; \
00220
r3 ^= r2; \
00221
r0 ^= r4; \
00222
r2 ^= r0; \
00223
r0 |= r3; \
00224
r0 ^= r1; \
00225
r4 ^= r2; \
00226
r2 &= r3; \
00227
r1 |= r3; \
00228
r1 ^= r2; \
00229
r4 ^= r0; \
00230
r2 ^= r4; \
00231
}
00232
00233
#define S4(i, r0, r1, r2, r3, r4) \
00234
{ \
00235
r1 ^= r3; \
00236
r3 = ~r3; \
00237
r2 ^= r3; \
00238
r3 ^= r0; \
00239
r4 = r1; \
00240
r1 &= r3; \
00241
r1 ^= r2; \
00242
r4 ^= r3; \
00243
r0 ^= r4; \
00244
r2 &= r4; \
00245
r2 ^= r0; \
00246
r0 &= r1; \
00247
r3 ^= r0; \
00248
r4 |= r1; \
00249
r4 ^= r0; \
00250
r0 |= r3; \
00251
r0 ^= r2; \
00252
r2 &= r3; \
00253
r0 = ~r0; \
00254
r4 ^= r2; \
00255
}
00256
00257
#define I4(i, r0, r1, r2, r3, r4) \
00258
{ \
00259
r4 = r2; \
00260
r2 &= r3; \
00261
r2 ^= r1; \
00262
r1 |= r3; \
00263
r1 &= r0; \
00264
r4 ^= r2; \
00265
r4 ^= r1; \
00266
r1 &= r2; \
00267
r0 = ~r0; \
00268
r3 ^= r4; \
00269
r1 ^= r3; \
00270
r3 &= r0; \
00271
r3 ^= r2; \
00272
r0 ^= r1; \
00273
r2 &= r0; \
00274
r3 ^= r0; \
00275
r2 ^= r4; \
00276
r2 |= r3; \
00277
r3 ^= r0; \
00278
r2 ^= r1; \
00279
}
00280
00281
#define S5(i, r0, r1, r2, r3, r4) \
00282
{ \
00283
r0 ^= r1; \
00284
r1 ^= r3; \
00285
r3 = ~r3; \
00286
r4 = r1; \
00287
r1 &= r0; \
00288
r2 ^= r3; \
00289
r1 ^= r2; \
00290
r2 |= r4; \
00291
r4 ^= r3; \
00292
r3 &= r1; \
00293
r3 ^= r0; \
00294
r4 ^= r1; \
00295
r4 ^= r2; \
00296
r2 ^= r0; \
00297
r0 &= r3; \
00298
r2 = ~r2; \
00299
r0 ^= r4; \
00300
r4 |= r3; \
00301
r2 ^= r4; \
00302
}
00303
00304
#define I5(i, r0, r1, r2, r3, r4) \
00305
{ \
00306
r1 = ~r1; \
00307
r4 = r3; \
00308
r2 ^= r1; \
00309
r3 |= r0; \
00310
r3 ^= r2; \
00311
r2 |= r1; \
00312
r2 &= r0; \
00313
r4 ^= r3; \
00314
r2 ^= r4; \
00315
r4 |= r0; \
00316
r4 ^= r1; \
00317
r1 &= r2; \
00318
r1 ^= r3; \
00319
r4 ^= r2; \
00320
r3 &= r4; \
00321
r4 ^= r1; \
00322
r3 ^= r0; \
00323
r3 ^= r4; \
00324
r4 = ~r4; \
00325
}
00326
00327
#define S6(i, r0, r1, r2, r3, r4) \
00328
{ \
00329
r2 = ~r2; \
00330
r4 = r3; \
00331
r3 &= r0; \
00332
r0 ^= r4; \
00333
r3 ^= r2; \
00334
r2 |= r4; \
00335
r1 ^= r3; \
00336
r2 ^= r0; \
00337
r0 |= r1; \
00338
r2 ^= r1; \
00339
r4 ^= r0; \
00340
r0 |= r3; \
00341
r0 ^= r2; \
00342
r4 ^= r3; \
00343
r4 ^= r0; \
00344
r3 = ~r3; \
00345
r2 &= r4; \
00346
r2 ^= r3; \
00347
}
00348
00349
#define I6(i, r0, r1, r2, r3, r4) \
00350
{ \
00351
r0 ^= r2; \
00352
r4 = r2; \
00353
r2 &= r0; \
00354
r4 ^= r3; \
00355
r2 = ~r2; \
00356
r3 ^= r1; \
00357
r2 ^= r3; \
00358
r4 |= r0; \
00359
r0 ^= r2; \
00360
r3 ^= r4; \
00361
r4 ^= r1; \
00362
r1 &= r3; \
00363
r1 ^= r0; \
00364
r0 ^= r3; \
00365
r0 |= r2; \
00366
r3 ^= r1; \
00367
r4 ^= r0; \
00368
}
00369
00370
#define S7(i, r0, r1, r2, r3, r4) \
00371
{ \
00372
r4 = r2; \
00373
r2 &= r1; \
00374
r2 ^= r3; \
00375
r3 &= r1; \
00376
r4 ^= r2; \
00377
r2 ^= r1; \
00378
r1 ^= r0; \
00379
r0 |= r4; \
00380
r0 ^= r2; \
00381
r3 ^= r1; \
00382
r2 ^= r3; \
00383
r3 &= r0; \
00384
r3 ^= r4; \
00385
r4 ^= r2; \
00386
r2 &= r0; \
00387
r4 = ~r4; \
00388
r2 ^= r4; \
00389
r4 &= r0; \
00390
r1 ^= r3; \
00391
r4 ^= r1; \
00392
}
00393
00394
#define I7(i, r0, r1, r2, r3, r4) \
00395
{ \
00396
r4 = r2; \
00397
r2 ^= r0; \
00398
r0 &= r3; \
00399
r2 = ~r2; \
00400
r4 |= r3; \
00401
r3 ^= r1; \
00402
r1 |= r0; \
00403
r0 ^= r2; \
00404
r2 &= r4; \
00405
r1 ^= r2; \
00406
r2 ^= r0; \
00407
r0 |= r2; \
00408
r3 &= r4; \
00409
r0 ^= r3; \
00410
r4 ^= r1; \
00411
r3 ^= r4; \
00412
r4 |= r0; \
00413
r3 ^= r2; \
00414
r4 ^= r2; \
00415
}
00416
00417
00418
#define KX(r, a, b, c, d, e) {\
00419
a ^= k[4 * r + 0]; \
00420
b ^= k[4 * r + 1]; \
00421
c ^= k[4 * r + 2]; \
00422
d ^= k[4 * r + 3];}
00423
00424
void Serpent::Base::UncheckedSetKey(CipherDir direction,
const byte *userKey,
unsigned int keylen)
00425 {
00426 AssertValidKeyLength(keylen);
00427
00428 word32 *k = m_key;
00429 GetUserKey(LITTLE_ENDIAN_ORDER, k, 8, userKey, keylen);
00430
00431
if (keylen < 32)
00432 k[keylen/4] |= word32(1) << ((keylen%4)*8);
00433
00434 k += 8;
00435 word32 t = k[-1];
00436
signed int i;
00437
for (i = 0; i < 132; ++i)
00438 k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
00439 k -= 20;
00440
00441
#define LK(r, a, b, c, d, e) {\
00442
a = k[(8-r)*4 + 0]; \
00443
b = k[(8-r)*4 + 1]; \
00444
c = k[(8-r)*4 + 2]; \
00445
d = k[(8-r)*4 + 3];}
00446
00447
#define SK(r, a, b, c, d, e) {\
00448
k[(8-r)*4 + 4] = a; \
00449
k[(8-r)*4 + 5] = b; \
00450
k[(8-r)*4 + 6] = c; \
00451
k[(8-r)*4 + 7] = d;} \
00452
00453
word32 a,b,c,d,e;
00454
for (i=0; i<4; i++)
00455 {
00456 afterS2(LK); afterS2(S3); afterS3(SK);
00457 afterS1(LK); afterS1(S2); afterS2(SK);
00458 afterS0(LK); afterS0(S1); afterS1(SK);
00459 beforeS0(LK); beforeS0(S0); afterS0(SK);
00460 k += 8*4;
00461 afterS6(LK); afterS6(S7); afterS7(SK);
00462 afterS5(LK); afterS5(S6); afterS6(SK);
00463 afterS4(LK); afterS4(S5); afterS5(SK);
00464 afterS3(LK); afterS3(S4); afterS4(SK);
00465 }
00466 afterS2(LK); afterS2(S3); afterS3(SK);
00467 }
00468
00469
typedef BlockGetAndPut<word32, LittleEndian> Block;
00470
00471
void Serpent::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
00472
{
00473 word32 a, b, c, d, e;
00474
00475 Block::Get(inBlock)(a)(b)(c)(d);
00476
00477
const word32 *k = m_key + 8;
00478
unsigned int i=1;
00479
00480
do
00481 {
00482 beforeS0(KX); beforeS0(S0); afterS0(LT);
00483 afterS0(KX); afterS0(S1); afterS1(LT);
00484 afterS1(KX); afterS1(S2); afterS2(LT);
00485 afterS2(KX); afterS2(S3); afterS3(LT);
00486 afterS3(KX); afterS3(S4); afterS4(LT);
00487 afterS4(KX); afterS4(S5); afterS5(LT);
00488 afterS5(KX); afterS5(S6); afterS6(LT);
00489 afterS6(KX); afterS6(S7);
00490
00491
if (i == 4)
00492
break;
00493
00494 ++i;
00495 c = b;
00496 b = e;
00497 e = d;
00498 d = a;
00499 a = e;
00500 k += 32;
00501 beforeS0(LT);
00502 }
00503
while (
true);
00504
00505 afterS7(KX);
00506
00507 Block::Put(xorBlock, outBlock)(d)(e)(b)(a);
00508 }
00509
00510
void Serpent::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
00511
{
00512 word32 a, b, c, d, e;
00513
00514 Block::Get(inBlock)(a)(b)(c)(d);
00515
00516
const word32 *k = m_key + 104;
00517
unsigned int i=4;
00518
00519 beforeI7(KX);
00520
goto start;
00521
00522
do
00523 {
00524 c = b;
00525 b = d;
00526 d = e;
00527 k -= 32;
00528 beforeI7(ILT);
00529 start:
00530 beforeI7(I7); afterI7(KX);
00531 afterI7(ILT); afterI7(I6); afterI6(KX);
00532 afterI6(ILT); afterI6(I5); afterI5(KX);
00533 afterI5(ILT); afterI5(I4); afterI4(KX);
00534 afterI4(ILT); afterI4(I3); afterI3(KX);
00535 afterI3(ILT); afterI3(I2); afterI2(KX);
00536 afterI2(ILT); afterI2(I1); afterI1(KX);
00537 afterI1(ILT); afterI1(I0); afterI0(KX);
00538 }
00539
while (--i != 0);
00540
00541 Block::Put(xorBlock, outBlock)(a)(d)(b)(e);
00542 }
00543
00544 NAMESPACE_END
Generated on Fri Aug 27 13:36:37 2004 for Crypto++ by
1.3.8