1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
|
#pragma src "/usr/inferno/libcrypt"
#define NOSPOOKS
/*
* To use Brickell bigpow, uncomment the following and recompile everything:
* #define BRICKELL
*/
/************************************************************************/
/* system interface (can be overriden) */
enum
{
CRITICAL= 1,
WARNING= 0
};
void handle_exception(int, char*);
void *crypt_malloc(int);
void crypt_free(void*);
/************************************************************************/
/* infinite precision integer arithmetic */
/* The following all define the size of a basic unit math is performed on */
typedef ulong NumType;
#define NumTypeBits (sizeof(NumType)*8)
#define NumTypeMask (ulong)0xFFFFFFFF
typedef long SignedNumType;
typedef int Boolean;
typedef NumType *BigData;
enum
{
TRUE= 1,
FALSE= 0
};
typedef int Sign;
enum
{
POS= 1,
NEG= -1
};
/* Fundamental bigmath unit */
typedef struct Bignum {
Sign sign;
ulong length; /* length of number (in NumType units) */
ulong space; /* storage space (in NumType units) */
NumType *num;
} Bignum;
typedef Bignum * BigInt;
/* macros to get return properties of a big integer */
#define NUM(x) ((x)->num)
#define LENGTH(x) ((x)->length)
#define SIGN(x) ((x)->sign)
#define SPACE(x) ((x)->space)
#define LENGTH_IN_BYTES(N) (((N + (NumTypeBits-1) / NumTypeBits) * sizeof(NumType))
#define EVEN(a) (((NUM(a)[0] & 1) == 0) ? TRUE : FALSE)
#define ODD(a) (((NUM(a)[0] & 1) != 0) ? TRUE : FALSE)
#define BIT2BYTE 8
/* Some predefined constants in bignum form. */
#define ZERO(x) ((LENGTH(x) == 1) && (NUM(x)[0] == 0))
#define ONE(x) ((LENGTH(x) == 1) && (NUM(x)[0] == 1))
#define TWO(x) ((LENGTH(x) == 1) && (NUM(x)[0] == 2))
/* GUARANTEE is the principal macro for bigint memory allocation.
* Space is updated by this macro. If a bigint shrinks (say as the result
* of a modular reduction) space need not be freed. The length will be reduced.
* If later the reduced number is squared (say) then we don't need to realloc
* the memory. Look at bigmath.c to get a feel for how this is used.
*/
#define GUARANTEE(B,S) {\
if((B)->space < (S)) {\
(B)->space = (S);\
(B)->num = (BigData)realloc((uchar *)NUM(B), (unsigned)(sizeof(NumType)*SPACE(B)));\
memset((B)->num+LENGTH(B), 0, sizeof(NumType)*((S)-LENGTH(B)));\
}\
}
BigInt atobig(char*);
int bigtostr(BigInt, char*, int, int);
BigInt strtobig(char*, char**, int);
void bigAdd(BigInt, BigInt, BigInt);
void bigAnd(BigInt, BigInt, BigInt);
int bigBits(BigInt);
int bigBytes(BigInt);
int bigCompare(BigInt, BigInt);
int bigconv(Fmt*); /* %B */
void bigCopy(BigInt, BigInt);
void bigCube(BigInt, BigInt, BigInt);
int bigDivide(BigInt, BigInt, BigInt, BigInt);
#define bigInit(x) (itobig((NumType)(x)))
void bigLeftShift(BigInt, int, BigInt);
int bigMod(BigInt, BigInt, BigInt);
void bigMultiply(BigInt, BigInt, BigInt);
void bigOr(BigInt, BigInt, BigInt);
void bigPow(BigInt, BigInt, BigInt, BigInt);
void bigRightShift(BigInt, int, BigInt);
void bigsquare(BigInt a, BigInt res);
void bigsub(BigInt, BigInt, BigInt);
void bigSubtract(BigInt, BigInt, BigInt);
Sign bigTest(BigInt);
int bigToBuf(BigInt big, int bufsize, uchar *buf);
int bigTobeBuf(BigInt big, int bufsize, uchar *buf);
void bigXor(BigInt, BigInt, BigInt);
void bufToBig(uchar *buf, int buflen, BigInt big);
void bebufToBig(uchar *buf, int buflen, BigInt big);
void crtCombine(BigInt, BigInt, BigInt, BigInt, BigInt, BigInt);
Boolean even(BigInt);
void freeBignum(BigInt);
BigInt itobig(NumType);
void lbigmult(BigInt a, BigInt b, BigInt res);
NumType msb(NumType);
void negate(BigInt, BigInt, BigInt);
Boolean odd(BigInt);
void reset_big(BigInt a, NumType val);
void trim(BigInt);
/* always around */
extern BigInt zero, one, two;
/*********************************************************************/
/* primes */
enum
{
NIST= 0,
GORDON= 1
};
typedef int PrimeType;
void setPrimeTestAttempts(int);
Boolean primeTest(BigInt);
void getPrime(int, BigInt);
void genStrongPrimeSet(int, BigInt, int, BigInt, PrimeType);
void genStrongPrime(int, BigInt);
void getPrimitiveElement(BigInt, BigInt, BigInt);
/************************************************************************/
/* random numbers */
/* By default, REALLY ==> truerand() and PSEUDO ==> fsrRandom() */
enum
{
REALLY= 1,
PSEUDO= 0
};
typedef int RandType;
void bigRand(int, BigInt, RandType);
void bigReallyRand(int, BigInt);
void bigPseudoRand(int, BigInt);
void seed_fsr(uchar*, int);
ulong fsrRandom(void);
void getRandBetween(BigInt, BigInt, BigInt, RandType);
int randomBytes(uchar*, int, RandType);
void pseudoRandomBytes(uchar*, int);
void reallyRandomBytes(uchar*, int);
ulong truerand(void);
ulong fastrand(void);
#ifdef PRAND
#define seed_rng seed_prand
#else
#define seed_rng seed_fsr
#endif
/************************************************************************/
/* aes */
enum
{
AESbsize= 16,
AESmaxkey= 32,
AESmaxrounds= 14
};
typedef struct AESstate AESstate;
struct AESstate
{
ulong setup;
int rounds;
int keybytes;
uchar key[AESmaxkey]; /* unexpanded key */
u32int ekey[4*(AESmaxrounds + 1)]; /* encryption key */
u32int dkey[4*(AESmaxrounds + 1)]; /* decryption key */
uchar ivec[AESbsize]; /* initialization vector */
};
void setupAESstate(AESstate *s, uchar key[], int keybytes, uchar *ivec);
void aesCBCencrypt(uchar *p, int len, AESstate *s);
void aesCBCdecrypt(uchar *p, int len, AESstate *s);
/************************************************************************/
/* rc4 */
typedef struct RC4state RC4state;
struct RC4state
{
uchar state[256];
uchar x;
uchar y;
};
void setupRC4state(RC4state*, uchar*, int);
void rc4(RC4state*, uchar*, int);
void rc4skip(RC4state*, int);
void rc4back(RC4state*, int);
/************************************************************************/
/* idea */
typedef struct IDEAstate IDEAstate;
struct IDEAstate
{
uchar key[16];
ushort edkey[104];
uchar ivec[8];
};
void setupIDEAstate(IDEAstate*, uchar*, uchar*);
void idea_key_setup(uchar*, ushort*);
void idea_cipher(ushort*, uchar*, int);
/************************************************************************/
/* des */
enum
{
DESbsize= 8,
IDEAbsize= 8,
ECB= 10,
CBC= 20,
OFM= 30
};
typedef int ModeType;
/* des key conversion */
uchar *atodes(char*);
int desconv(va_list*, void*); /* %D */
/* single des */
typedef struct DESstate DESstate;
struct DESstate
{
ulong setup;
uchar key[8]; /* unexpanded key */
ulong expanded[32]; /* expanded key */
uchar ivec[8]; /* initialization vector */
};
void setupDESstate(DESstate*, uchar*, uchar*);
void des_key_setup(uchar*, ulong*);
void block_cipher(ulong*, uchar*, int);
/* The following functions are currently not used */
void key_setup(uchar*, ulong*);
void key_crunch(uchar*, int, uchar*);
void bCBCEncrypt(uchar*, uchar*, ulong*, int);
void blockECBEncrypt(uchar*, uchar*, DESstate*);
void bCBCDecrypt(uchar*, uchar*, ulong*, int);
void blockECBDecrypt(uchar*, uchar*, DESstate*);
void blockCBCEncrypt(uchar*, uchar*, uchar*, int, DESstate*);
void blockCBCDecrypt(uchar*, uchar*, uchar*, int, DESstate*);
void blockOFMEncrypt(uchar*, uchar*, uchar*, int, DESstate*);
void blockOFMDecrypt(uchar*, uchar*, uchar*, int, DESstate*);
void bufferECBEncrypt(uchar*, uchar*, int);
void bufferECBDecrypt(uchar*, uchar*, int);
void bufferCBCEncrypt(uchar*, uchar*, uchar*, int);
void bufferCBCDecrypt(uchar*, uchar*, uchar*, int);
void bufferOFMEncrypt(uchar*, uchar*, uchar*, int);
void bufferOFMDecrypt(uchar*, uchar*, uchar*, int);
/* triple des */
typedef struct DES3state DES3state;
struct DES3state
{
ulong setup;
uchar key[3][8]; /* unexpanded key */
ulong expanded[3][32]; /* expanded key */
uchar ivec[8]; /* initialization vector */
};
#define DES3D 1
void setupDES3state(DES3state*, uchar key[3][8], uchar*);
void triple_block_cipher(ulong keys[3][32], uchar*, int);
/* The following functions are currently not used */
void b3CBCEncrypt(uchar*, uchar*, ulong int_key[3][32], int);
void block3ECBEncrypt(uchar*, uchar key[3][8], DES3state*);
void b3CBCDecrypt(uchar*, uchar*, ulong int_key[3][32], int);
void block3ECBDecrypt(uchar*, uchar key[3][8], DES3state*);
void block3CBCEncrypt(uchar*, uchar*, uchar key[3][8], int, DES3state*);
void block3CBCDecrypt(uchar*, uchar*, uchar key[3][8], int, DES3state*);
void block3OFMEncrypt(uchar*, uchar*, uchar key[3][8], int, DES3state*);
void block3OFMDecrypt(uchar*, uchar*, uchar key[3][8], int, DES3state*);
void buffer3ECBEncrypt(uchar *buf, uchar key[3][8], int);
void buffer3ECBDecrypt(uchar *buf, uchar key[3][8], int);
void buffer3CBCEncrypt(uchar *buf, uchar*, uchar key[3][8], int);
void buffer3CBCDecrypt(uchar *buf, uchar*, uchar key[3][8], int);
void buffer3OFMEncrypt(uchar *buf, uchar*, uchar key[3][8], int);
void buffer3OFMDecrypt(uchar *buf, uchar*, uchar key[3][8], int);
void mbitCFMEncrypt(uchar*, uchar*, ulong*, int);
void mbitCFMDecrypt(uchar*, uchar*, ulong*, int m);
/************************************************************************/
/* digests */
enum
{
SHAdlen= 20, /* SHA digest length */
SHA1dlen = SHAdlen,
MD4dlen= 16, /* MD4 digest length */
MD5dlen= 16 /* MD5 digest length */
};
typedef struct DigestState DigestState;
struct DigestState
{
ulong len;
ulong state[5];
uchar buf[128];
int blen;
char malloced;
char seeded;
};
typedef struct DigestState SHAstate;
typedef struct DigestState SHA1state;
typedef struct DigestState MD5state;
typedef struct DigestState MD4state;
DigestState* md4(uchar*, ulong, uchar*, DigestState*);
DigestState* md5(uchar*, ulong, uchar*, DigestState*);
DigestState* sha1(uchar*, ulong, uchar*, DigestState*);
DigestState* hmac_md5(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
DigestState* hmac_sha1(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
/************************************************************************/
/* #include "bigpow.h" */
typedef struct {
unsigned length;
BigInt t[2];
} Table;
typedef struct {
BigInt N;
NumType n0p;
} Mont_set;
/* Struct for Montgomery reduction REDC */
/* Generally no reason to play with this stuff, used exclusively within bigPow */
NumType modInverse(NumType);
Mont_set *mont_set(BigInt);
BigInt res_form(BigInt big, Mont_set *ms);
/* When doing a^b mod c for a constant a and c, a table can be created using the following
* function. This is useful in El Gamal variants where the base (a) and the modulus are
* constant in groupd of keys. This is true of DSA (an El Gamal variant) as well.
*/
Table *g16_bigpow(BigInt a, BigInt modulus, NumType explength);
/* bigpow using table: Ernie Brickell's method. */
void brickell_bigpow(Table *table,
BigInt exponent,
BigInt modulus,
BigInt result);
void freeTable(Table *);
void freeMs(Mont_set *);
/************************************************************************/
/* #include "longmult.h" */
/* Not part of the cryptoLib interface - low level multiplication routines. */
NumType smult(NumType *, NumType, NumType *, int);
NumType LMULT(NumType *, NumType, NumType *, int);
void BUILDDIAG(NumType *, NumType *, int);
void SQUAREINNERLOOP(NumType *, NumType, NumType *, int, int);
/************************************************************************/
/* #include "coremult.h" */
/* Not part of the cryptoLib interface - low level multiplication routines. */
void numtype_bigmult2(NumType *, NumType *, NumType *);
void numtype_bigmult8(NumType *, NumType *, NumType *);
void numtype_bigmultN(NumType *, NumType *, NumType *, int);
void numtype_bigsquareN(NumType *, NumType *, int);
void bigmult4(BigData, BigData, BigData);
void bigmult8(BigData, BigData, BigData);
void bigmultN(BigData, BigData, BigData, int);
void bigsquare8(BigData, BigData);
void bigsquareN(BigData, BigData, int);
void numtype_bigmult(BigInt, NumType, BigInt, int);
void REDC(BigInt, Mont_set *);
/************************************************************************/
/* #include "euclid.h" */
/* Euclid's extended gcd algorithm for solving
* ax + by = gcd(a, b)
*/
void extendedGcd(BigInt a,
BigInt b,
BigInt x,
BigInt y,
BigInt gcd);
/* If gcd(a, b) = 1, x = inverse of a (mod b) and y = inverse of b (mod a) */
void getInverse(BigInt a,
BigInt b,
BigInt inverse_of_a_mod_b );
BigInt gcd(BigInt a, BigInt b);
/************************************************************************/
/* #include "jacobi.h" */
/* calculate the jacobi symbol (a/b) */
int bigJacobi(BigInt a,
BigInt b);
int jacobi(int a,
int b);
/* Return true if a is a quadratic residue mod p*q where p and q are prime. */
int bigIsQR(BigInt a,
BigInt p,
BigInt q);
int isQR(int a,
int p,
int q);
/************************************************************************/
/* quadratic residues */
/* Return true if a is a quadratic residue mod p */
Boolean quadResidue(BigInt a,
BigInt p);
/* Return true if a is a quadratic residue mod p*q where p and q are prime. */
Boolean compositeQuadResidue(BigInt a,
BigInt p,
BigInt q);
/* return the square root of a (mod p) where p is prime. */
void squareRoot(BigInt a,
BigInt p,
BigInt result);
/* return the 2 linearly independent square roots of a (mod p*q) for p and q prime. */
/* The other 2 roots are n-root1 and n-root2 */
void compositeSquareRoot(BigInt a,
BigInt p,
BigInt q,
BigInt root1,
BigInt root2);
/************************************************************************/
/* El Gamal Crypto system stuff */
/* p is prime, q is a large prime factor of p-1. alpha is the base
* g_table is included as part of the key to enable Brickell exponentiation.
* If one set {p, q, alpha} is used by "everyone" then this table can be constant.
* That is, {p, q, alpha, g_table} is public. The private key is then
* the exponent (or secret) and the public key is alpha^exponent mod p.
*/
typedef struct EGParams {
BigInt p, q, alpha;
} EGParams;
typedef struct EGPrivateKey {
BigInt p, q;
BigInt alpha;
BigInt publicKey;
BigInt secret;
Table *g_table;
} EGPrivateKey;
typedef struct EGPublicKey {
BigInt p, q;
BigInt alpha;
BigInt publicKey;
Table *g_table, *y_table;
} EGPublicKey;
typedef struct EGKeySet {
EGPublicKey *publicKey;
EGPrivateKey *privateKey;
} EGKeySet;
typedef struct EGSignature {
BigInt r, s;
} EGSignature;
/* generate global p, q, and alpha */
EGParams * genEGParams(int, int);
/* generate alpha and p numbits long */
void genDiffieHellmanSet(BigInt p,
BigInt alpha,
int pbits,
int qbits);
/* generate public and private keys corresponding to params */
EGKeySet * genEGKeySet(EGParams *params);
/* generate private key */
EGPrivateKey * genEGPrivateKey(EGParams *params);
/* El Gamal signature */
void * EGSign(BigInt big,
void *key);
/* Verify signature of big */
Boolean EGVerify(BigInt big,
void *sig,
void *key);
/* El Gamal encrypt and decrypt functions -- these are not reversible as in RSA
* That is, Decrypt(Encrypt(m, pubkey), privkey) is NOT the same as
* Encrypt(Decrypt(m, privkey), pubkey). This symmetry doesn't exist with
* El Gamal.
*/
BigInt EGEncrypt(BigInt, EGPublicKey *);
BigInt EGDecrypt(BigInt, EGPrivateKey *);
/* El Gamal Cleanup functions -- be sure to use these! */
void freeEGPublicKey(void *);
void freeEGPrivateKey(void *);
void freeEGKeys(EGKeySet *);
void freeEGSig(void *);
void freeEGParams(EGParams *);
/************************************************************************/
/* DSS == modified Elgamal */
/* The digital signature standard doesn't introduce new structures...we reuse the
* El Gamal structs and parameter generation stuff.
*/
typedef EGSignature DSSSignature;
typedef EGPublicKey DSSPublicKey;
typedef EGPrivateKey DSSPrivateKey;
typedef EGParams DSSParams;
typedef EGKeySet DSSKeySet;
void *DSSSign(BigInt big, void *key);
Boolean DSSVerify(BigInt big, void *sig, void *key);
#define genDSSParams genEGParams
#define genDSSKeySet genEGKeySet
#define genDSSPrivateKey genEGPrivateKey
void freeDSSSig(void *);
#define freeDSSPublicKey freeEGPublicKey
#define freeDSSPrivateKey freeEGPrivateKey
#define freeDSSKeys freeEGKeys
#define freeDSSParams freeEGParams
/************************************************************************/
/* base 64 conversions */
int dec64(uchar *out, int lim, char *in, int n);
int enc64(char *out, int lim, uchar *in, int n);
/************************************************************************/
/* RSA Cryptosystem stuff */
/* The private key contains material to enable the Chinese Remainder speedup
* of decryption (or signing). For RSA,
* Decrypt(Encrypt(m, pubkey), privkey) = Encrypt(Decrypt(m, privkey), pubkey) = m
*/
typedef struct Key_exps {
BigInt e;
BigInt d;
} Key_exps;
typedef struct ChineseRemStruct {
BigInt p, q; /* SECRET primes */
BigInt dp, dq; /* d mod p, d mod q */
BigInt c12; /* inverse of p (mod q) */
} ChineseRemStruct;
typedef struct RSAPublicKey {
BigInt publicExponent;
BigInt modulus;
} RSAPublicKey;
typedef struct RSAPrivateKey {
BigInt publicExponent;
BigInt privateExponent; /* SECRET */
BigInt modulus;
ChineseRemStruct *crt; /* SECRET */
} RSAPrivateKey;
typedef struct RSAKeySet {
RSAPublicKey *publicKey;
RSAPrivateKey *privateKey;
} RSAKeySet;
typedef Bignum RSASignature;
/* generate an RSA key set with modulus length = modbits and
* public exponent length = explen. If explen = 2, the public exponent = 3.
*/
RSAKeySet * genRSAKeySet(int, int);
void freeRSAPublicKey(void *);
void freeRSAPrivateKey(void *);
void freeRSAKeys(RSAKeySet *);
void freeRSASig(void *);
/* RSA Encryption(m) = m^publicExponent mod modulus */
BigInt RSAEncrypt(BigInt msg,
RSAPublicKey *key);
/* RSA Decryption = m^privateExponent mod modulus */
BigInt RSADecrypt(BigInt msg,
RSAPrivateKey *key);
/* Signing is just RSADecrypt */
void * RSASign(BigInt msg, void *key);
/* Verifying is just RSAEncrypt */
Boolean RSAVerify(BigInt msg,
void *sig,
void *key);
#pragma varargck type "B" Bignum*
#pragma varargck type "U" Bignum*
|