Mercurial > dropbear
changeset 0:d7da3b1e1540 libtomcrypt
put back the 0.95 makefile which was inadvertently merged over
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,9 @@ +LibTomCrypt is public domain. As should all quality software be. + +All of the software was either written by or donated to Tom St Denis for the purposes +of this project. The only exception is the SAFER.C source which has no known +license status (assumed copyrighted) which is why SAFER,C is shipped as disabled. + +Tom St Denis + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PLAN Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,38 @@ +The following functions are marked for removal and/or behavioural change by v1.00 of LibTomCrypt + +1. RSA Support + + rsa_pad, rsa_signpad, rsa_depad, rsa_signdepad, rsa_import, rsa_export + +They will be replaced with PKCS #1 compliant OAEP/PSS padding function as early as v0.96 + +2. DSA Support + + dsa_import, dsa_export + +Will be replaced with suitable DSS [what is the standard?] compliant formats. Planned for v0.96 + +3. Key Ring Support + + (all) + +The entire API will be dropped as early as v0.96. It was just an experiment and nobody uses it anyways. + +4. Test Harness + + demos/test.c + +The test harness is well overdue for a makeover. Planned for as early as v0.97 + + +Put things in order... + +v0.96 -- removed keyring.c and gf.c + -- removed LTC RSA padding + -- DSS support [whatever this entails] + -- Bug fixes/updates to the PKCS/DSS support, should be stable in this release + +v0.97 -- Re-written test harness + -- More demos in the manual and demos/ directory + +... future???
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aes.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,606 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* AES implementation by Tom St Denis + * + * Derived from the Public Domain source code by + +--- + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <[email protected]> + * @author Antoon Bosselaers <[email protected]> + * @author Paulo Barreto <[email protected]> +--- + */ + +#include "mycrypt.h" + +#ifdef RIJNDAEL + +const struct _cipher_descriptor rijndael_desc = +{ + "rijndael", + 6, + 16, 32, 16, 10, + &rijndael_setup, + &rijndael_ecb_encrypt, + &rijndael_ecb_decrypt, + &rijndael_test, + &rijndael_keysize +}; + +const struct _cipher_descriptor aes_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + &rijndael_setup, + &rijndael_ecb_encrypt, + &rijndael_ecb_decrypt, + &rijndael_test, + &rijndael_keysize +}; + +#include "aes_tab.c" + +int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey) +{ + int i, j; + ulong32 temp, *rk, *rrk; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) { + return CRYPT_INVALID_ROUNDS; + } + + skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; + + /* setup the forward key */ + i = 0; + rk = skey->rijndael.eK; + LOAD32H(rk[0], key ); + LOAD32H(rk[1], key + 4); + LOAD32H(rk[2], key + 8); + LOAD32H(rk[3], key + 12); + if (keylen == 16) { + j = 44; + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + break; + } + rk += 4; + } + } else if (keylen == 24) { + j = 52; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; + #else + temp = rk[5]; + #endif + rk[ 6] = rk[ 0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + break; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } else if (keylen == 32) { + j = 60; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + LOAD32H(rk[6], key + 24); + LOAD32H(rk[7], key + 28); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; + #else + temp = rk[7]; + #endif + rk[ 8] = rk[ 0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + break; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4_3[byte(temp, 3)]) ^ + (Te4_2[byte(temp, 2)]) ^ + (Te4_1[byte(temp, 1)]) ^ + (Te4_0[byte(temp, 0)]); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } else { + /* this can't happen */ + j = 4; + } + + /* setup the inverse key now */ + rk = skey->rijndael.dK; + rrk = skey->rijndael.eK + j - 4; + + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + /* copy first */ + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + rk -= 3; rrk -= 3; + + for (i = 1; i < skey->rijndael.Nr; i++) { + rrk -= 4; + rk += 4; + #ifdef SMALL_CODE + temp = rrk[0]; + rk[0] = + Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); + temp = rrk[1]; + rk[1] = + Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); + temp = rrk[2]; + rk[2] = + Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); + temp = rrk[3]; + rk[3] = + Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); + #else + temp = rrk[0]; + rk[0] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[1]; + rk[1] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[2]; + rk[2] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[3]; + rk[3] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + #endif + + } + + /* copy last */ + rrk -= 4; + rk += 4; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.eK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, pt ); s0 ^= rk[0]; + LOAD32H(s1, pt + 4); s1 ^= rk[1]; + LOAD32H(s2, pt + 8); s2 ^= rk[2]; + LOAD32H(s3, pt + 12); s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)) ^ + rk[4]; + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)) ^ + rk[5]; + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)) ^ + rk[6]; + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0(byte(t0, 3)) ^ + Te1(byte(t1, 2)) ^ + Te2(byte(t2, 1)) ^ + Te3(byte(t3, 0)) ^ + rk[0]; + s1 = + Te0(byte(t1, 3)) ^ + Te1(byte(t2, 2)) ^ + Te2(byte(t3, 1)) ^ + Te3(byte(t0, 0)) ^ + rk[1]; + s2 = + Te0(byte(t2, 3)) ^ + Te1(byte(t3, 2)) ^ + Te2(byte(t0, 1)) ^ + Te3(byte(t1, 0)) ^ + rk[2]; + s3 = + Te0(byte(t3, 3)) ^ + Te1(byte(t0, 2)) ^ + Te2(byte(t1, 1)) ^ + Te3(byte(t2, 0)) ^ + rk[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4_3[(t0 >> 24) ]) ^ + (Te4_2[(t1 >> 16) & 0xff]) ^ + (Te4_1[(t2 >> 8) & 0xff]) ^ + (Te4_0[(t3 ) & 0xff]) ^ + rk[0]; + STORE32H(s0, ct); + s1 = + (Te4_3[(t1 >> 24) ]) ^ + (Te4_2[(t2 >> 16) & 0xff]) ^ + (Te4_1[(t3 >> 8) & 0xff]) ^ + (Te4_0[(t0 ) & 0xff]) ^ + rk[1]; + STORE32H(s1, ct+4); + s2 = + (Te4_3[(t2 >> 24) ]) ^ + (Te4_2[(t3 >> 16) & 0xff]) ^ + (Te4_1[(t0 >> 8) & 0xff]) ^ + (Te4_0[(t1 ) & 0xff]) ^ + rk[2]; + STORE32H(s2, ct+8); + s3 = + (Te4_3[(t3 >> 24) ]) ^ + (Te4_2[(t0 >> 16) & 0xff]) ^ + (Te4_1[(t1 >> 8) & 0xff]) ^ + (Te4_0[(t2 ) & 0xff]) ^ + rk[3]; + STORE32H(s3, ct+12); +} + +#ifdef CLEAN_STACK +void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + _rijndael_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); +} +#endif + +#ifdef CLEAN_STACK +static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.dK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, ct ); s0 ^= rk[0]; + LOAD32H(s1, ct + 4); s1 ^= rk[1]; + LOAD32H(s2, ct + 8); s2 ^= rk[2]; + LOAD32H(s3, ct + 12); s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + + t0 = + Td0(byte(s0, 3)) ^ + Td1(byte(s3, 2)) ^ + Td2(byte(s2, 1)) ^ + Td3(byte(s1, 0)) ^ + rk[4]; + t1 = + Td0(byte(s1, 3)) ^ + Td1(byte(s0, 2)) ^ + Td2(byte(s3, 1)) ^ + Td3(byte(s2, 0)) ^ + rk[5]; + t2 = + Td0(byte(s2, 3)) ^ + Td1(byte(s1, 2)) ^ + Td2(byte(s0, 1)) ^ + Td3(byte(s3, 0)) ^ + rk[6]; + t3 = + Td0(byte(s3, 3)) ^ + Td1(byte(s2, 2)) ^ + Td2(byte(s1, 1)) ^ + Td3(byte(s0, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + + s0 = + Td0(byte(t0, 3)) ^ + Td1(byte(t3, 2)) ^ + Td2(byte(t2, 1)) ^ + Td3(byte(t1, 0)) ^ + rk[0]; + s1 = + Td0(byte(t1, 3)) ^ + Td1(byte(t0, 2)) ^ + Td2(byte(t3, 1)) ^ + Td3(byte(t2, 0)) ^ + rk[1]; + s2 = + Td0(byte(t2, 3)) ^ + Td1(byte(t1, 2)) ^ + Td2(byte(t0, 1)) ^ + Td3(byte(t3, 0)) ^ + rk[2]; + s3 = + Td0(byte(t3, 3)) ^ + Td1(byte(t2, 2)) ^ + Td2(byte(t1, 1)) ^ + Td3(byte(t0, 0)) ^ + rk[3]; + } + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]; + STORE32H(s0, pt); + s1 = + (Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]; + STORE32H(s1, pt+4); + s2 = + (Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]; + STORE32H(s2, pt+8); + s3 = + (Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]; + STORE32H(s3, pt+12); +} + + +#ifdef CLEAN_STACK +void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + _rijndael_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); +} +#endif + +int rijndael_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } + }, { + 24, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } + }, { + 32, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } + } + }; + + symmetric_key key; + unsigned char tmp[2][16]; + int i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); + rijndael_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (memcmp(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rijndael_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + return CRYPT_OK; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + return CRYPT_OK; + } else { + *desired_keysize = 32; + return CRYPT_OK; + } +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aes_tab.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1008 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* The precomputed tables for AES */ +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const ulong32 TE0[256] = { + 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, + 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, + 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, + 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, + 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, + 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, + 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, + 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, + 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, + 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, + 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, + 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, + 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, + 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, + 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, + 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, + 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, + 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, + 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, + 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, + 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, + 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, + 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, + 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, + 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, + 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, + 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, + 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, + 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, + 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, + 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, + 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, + 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, + 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, + 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, + 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, + 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, + 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, + 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, + 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, + 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, + 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, + 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, + 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, + 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, + 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, + 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, + 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, + 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, + 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, + 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, + 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, + 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, + 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, + 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, + 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, + 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, + 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, + 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, + 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, + 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, + 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, + 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, + 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, +}; + +static const ulong32 Te4[256] = { + 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, + 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, + 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, + 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, + 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, + 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, + 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, + 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, + 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, + 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, + 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, + 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, + 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, + 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, + 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, + 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, + 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, + 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, + 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, + 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, + 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, + 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, + 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, + 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, + 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, + 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, + 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, + 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, + 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, + 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, + 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, + 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, + 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, + 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, + 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, + 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, + 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, + 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, + 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, + 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, + 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, + 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, + 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, + 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, + 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, + 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, + 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, + 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, + 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, + 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, + 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, + 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, + 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, + 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, + 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, + 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, + 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, + 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, + 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, + 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, + 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, + 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, + 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, + 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, +}; + +static const ulong32 TD0[256] = { + 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, + 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, + 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, + 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, + 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, + 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, + 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, + 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, + 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, + 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, + 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, + 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, + 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, + 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, + 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, + 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, + 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, + 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, + 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, + 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, + 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, + 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, + 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, + 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, + 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, + 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, + 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, + 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, + 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, + 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, + 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, + 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, + 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, + 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, + 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, + 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, + 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, + 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, + 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, + 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, + 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, + 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, + 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, + 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, + 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, + 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, + 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, + 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, + 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, + 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, + 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, + 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, + 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, + 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, + 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, + 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, + 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, + 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, + 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, + 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, + 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, + 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, + 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, + 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, +}; + +static const ulong32 Td4[256] = { + 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, + 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, + 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, + 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, + 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, + 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, + 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, + 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, + 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, + 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, + 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, + 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, + 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, + 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, + 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, + 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, + 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, + 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, + 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, + 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, + 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, + 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, + 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, + 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, + 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, + 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, + 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, + 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, + 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, + 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, + 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, + 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, + 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, + 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, + 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, + 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, + 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, + 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, + 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, + 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, + 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, + 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, + 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, + 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, + 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, + 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, + 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, + 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, + 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, + 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, + 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, + 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, + 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, + 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, + 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, + 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, + 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, + 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, + 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, + 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, + 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, + 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, + 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, + 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, +}; + +#ifdef SMALL_CODE + +#define Te0(x) TE0[x] +#define Te1(x) ROR(TE0[x], 8) +#define Te2(x) ROR(TE0[x], 16) +#define Te3(x) ROR(TE0[x], 24) + +#define Td0(x) TD0[x] +#define Td1(x) ROR(TD0[x], 8) +#define Td2(x) ROR(TD0[x], 16) +#define Td3(x) ROR(TD0[x], 24) + +#define Te4_0 0x000000FF & Te4 +#define Te4_1 0x0000FF00 & Te4 +#define Te4_2 0x00FF0000 & Te4 +#define Te4_3 0xFF000000 & Te4 + +#else + +#define Te0(x) TE0[x] +#define Te1(x) TE1[x] +#define Te2(x) TE2[x] +#define Te3(x) TE3[x] + +#define Td0(x) TD0[x] +#define Td1(x) TD1[x] +#define Td2(x) TD2[x] +#define Td3(x) TD3[x] + +static const ulong32 TE1[256] = { + 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, + 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, + 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, + 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, + 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, + 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, + 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, + 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, + 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, + 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, + 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, + 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, + 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, + 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, + 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, + 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, + 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, + 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, + 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, + 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, + 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, + 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, + 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, + 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, + 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, + 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, + 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, + 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, + 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, + 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, + 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, + 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, + 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, + 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, + 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, + 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, + 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, + 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, + 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, + 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, + 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, + 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, + 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, + 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, + 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, + 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, + 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, + 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, + 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, + 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, + 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, + 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, + 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, + 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, + 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, + 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, + 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, + 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, + 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, + 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, + 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, + 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, + 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, + 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, +}; +static const ulong32 TE2[256] = { + 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, + 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, + 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, + 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, + 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, + 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, + 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, + 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, + 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, + 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, + 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, + 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, + 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, + 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, + 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, + 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, + 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, + 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, + 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, + 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, + 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, + 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, + 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, + 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, + 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, + 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, + 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, + 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, + 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, + 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, + 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, + 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, + 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, + 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, + 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, + 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, + 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, + 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, + 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, + 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, + 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, + 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, + 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, + 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, + 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, + 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, + 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, + 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, + 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, + 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, + 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, + 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, + 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, + 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, + 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, + 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, + 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, + 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, + 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, + 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, + 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, + 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, + 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, + 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, +}; +static const ulong32 TE3[256] = { + + 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, + 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, + 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, + 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, + 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, + 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, + 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, + 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, + 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, + 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, + 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, + 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, + 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, + 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, + 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, + 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, + 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, + 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, + 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, + 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, + 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, + 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, + 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, + 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, + 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, + 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, + 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, + 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, + 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, + 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, + 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, + 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, + 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, + 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, + 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, + 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, + 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, + 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, + 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, + 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, + 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, + 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, + 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, + 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, + 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, + 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, + 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, + 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, + 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, + 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, + 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, + 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, + 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, + 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, + 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, + 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, + 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, + 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, + 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, + 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, + 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, + 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, + 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, + 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, +}; + +static const ulong32 Te4_0[] = { +0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, +0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, +0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, +0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, +0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, +0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, +0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, +0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, +0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, +0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, +0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, +0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, +0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, +0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, +0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, +0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, +0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, +0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, +0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, +0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, +0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, +0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, +0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, +0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, +0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, +0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, +0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, +0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, +0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, +0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, +0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, +0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL +}; + +static const ulong32 Te4_1[] = { +0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, +0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, +0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, +0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, +0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, +0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, +0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, +0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, +0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, +0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, +0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, +0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, +0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, +0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, +0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, +0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, +0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, +0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, +0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, +0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, +0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, +0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, +0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, +0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, +0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, +0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, +0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, +0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, +0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, +0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, +0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, +0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL +}; + +static const ulong32 Te4_2[] = { +0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, +0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, +0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, +0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, +0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, +0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, +0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, +0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, +0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, +0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, +0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, +0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, +0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, +0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, +0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, +0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, +0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, +0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, +0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, +0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, +0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, +0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, +0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, +0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, +0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, +0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, +0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, +0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, +0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, +0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, +0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, +0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL +}; + +static const ulong32 Te4_3[] = { +0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, +0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, +0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, +0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, +0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, +0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, +0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, +0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, +0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, +0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, +0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, +0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, +0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, +0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, +0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, +0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, +0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, +0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, +0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, +0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, +0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, +0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, +0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, +0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, +0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, +0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, +0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, +0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, +0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, +0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, +0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, +0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL +}; + +static const ulong32 TD1[256] = { + 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, + 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, + 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, + 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, + 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, + 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, + 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, + 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, + 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, + 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, + 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, + 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, + 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, + 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, + 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, + 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, + 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, + 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, + 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, + 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, + 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, + 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, + 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, + 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, + 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, + 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, + 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, + 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, + 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, + 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, + 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, + 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, + 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, + 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, + 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, + 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, + 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, + 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, + 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, + 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, + 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, + 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, + 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, + 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, + 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, + 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, + 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, + 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, + 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, + 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, + 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, + 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, + 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, + 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, + 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, + 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, + 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, + 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, + 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, + 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, + 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, + 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, + 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, + 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, +}; +static const ulong32 TD2[256] = { + 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, + 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, + 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, + 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, + 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, + 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, + 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, + 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, + 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, + 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, + 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, + 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, + 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, + 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, + 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, + 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, + 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, + 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, + 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, + 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, + 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, + 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, + 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, + 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, + 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, + 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, + 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, + 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, + 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, + 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, + 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, + 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, + 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, + 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, + 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, + 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, + 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, + 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, + 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, + 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, + 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, + 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, + 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, + 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, + 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, + 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, + 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, + 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, + 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, + 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, + 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, + 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, + 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, + 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, + 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, + 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, + 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, + 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, + 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, + 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, + 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, + 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, + 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, + 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, +}; +static const ulong32 TD3[256] = { + 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, + 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, + 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, + 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, + 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, + 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, + 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, + 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, + 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, + 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, + 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, + 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, + 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, + 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, + 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, + 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, + 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, + 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, + 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, + 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, + 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, + 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, + 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, + 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, + 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, + 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, + 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, + 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, + 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, + 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, + 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, + 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, + 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, + 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, + 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, + 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, + 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, + 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, + 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, + 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, + 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, + 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, + 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, + 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, + 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, + 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, + 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, + 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, + 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, + 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, + 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, + 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, + 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, + 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, + 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, + 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, + 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, + 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, + 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, + 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, + 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, + 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, + 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, + 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, +}; + +static const ulong32 Tks0[] = { +0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, +0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, +0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, +0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, +0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, +0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, +0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, +0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, +0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, +0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, +0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, +0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, +0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, +0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, +0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, +0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, +0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, +0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, +0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, +0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, +0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, +0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, +0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, +0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, +0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, +0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, +0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, +0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, +0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, +0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, +0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, +0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL +}; + +static const ulong32 Tks1[] = { +0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, +0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, +0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, +0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, +0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, +0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, +0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, +0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, +0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, +0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, +0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, +0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, +0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, +0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, +0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, +0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, +0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, +0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, +0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, +0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, +0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, +0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, +0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, +0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, +0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, +0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, +0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, +0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, +0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, +0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, +0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, +0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL +}; + +static const ulong32 Tks2[] = { +0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, +0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, +0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, +0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, +0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, +0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, +0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, +0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, +0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, +0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, +0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, +0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, +0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, +0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, +0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, +0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, +0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, +0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, +0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, +0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, +0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, +0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, +0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, +0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, +0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, +0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, +0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, +0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, +0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, +0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, +0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, +0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL +}; + +static const ulong32 Tks3[] = { +0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, +0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, +0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, +0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, +0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, +0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, +0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, +0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, +0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, +0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, +0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, +0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, +0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, +0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, +0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, +0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, +0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, +0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, +0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, +0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, +0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, +0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, +0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, +0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, +0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, +0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, +0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, +0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, +0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, +0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, +0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, +0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL +}; + +#endif /* SMALL CODE */ + +static const ulong32 rcon[] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ampi.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,55 @@ +/* Code submitted by Svante Seleborg, cleaned up by Tom St Denis */ + +#include "mycrypt.h" +#include <stdarg.h> + +#ifdef MPI + +mp_err mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + +/* + Clear all arguments given, ended by a NULL marker. +*/ +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/authors Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,55 @@ +This is a list of people who have contributed [directly or indirectly] to the project +[in no partcular order]. If you have helped and your name is not here email me at [email protected]. + + +1) [email protected] + + Gave help porting the lib to MSVC particularly pointed out various warnings and errors. + +2) Richard Heathfield + + Gave a lot of help concerning valid C portable code. + +3) Ajay K. Agrawal + + Helped port the library to MSVC and spotted a few bugs and errors. + +4) Brian Gladman + + Wrote the AES and Serpent code used. Found a bug in the hash code for certain types of inputs. + +5) Svante Seleborg + + Submitted the "ampi.c" code as well as many suggestions on improving the readability of the source code. + +6) Clay Culver + + Submitted a fix for "rsa.c" which cleaned up some code. Submited some other fixes too. :-) + Clay has helped find bugs in various pieces of code including the registry functions, base64 routines + and the make process. He is also now the primary author of the libtomcrypt reference manual and has plan + at making a HTML version. + +7) Jason Klapste + + Submitted fixes to the yarrow, hash, make process and test code as well as other subtle bug fixes. The +yarrow code can now default to any cipher/hash that is left after you remove them from a build. + +8) Dobes Vandermeer <[email protected]> + + Submitted HMAC code that worked flawlessly out of the box... good job! Also submitted a MD4 routine. + Submitted some modified DES code that was merged into the code base [using the libtomcrypt API] + +9) Wayne Scott ([email protected]) + + Submitted base64 that complies with the RFC standards. Submitted some ideas to improve the RSA key generation + as well. + +10) Sky Schulz ([email protected]) + + Has submitted a set of ideas to improve the library and make it more attractive for professional users. + +11) Mike Frysinger + + Together with Clay came up with a more "unix friendly" makefile. Mike Frysinger has been keeping copies of + the library for the Gentoo linux distribution. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base64.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,121 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* compliant base64 code donated by Wayne Scott ([email protected]) */ +#include "mycrypt.h" + +#ifdef BASE64 + +static const char *codes = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const unsigned char map[256] = { +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 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, 255, 255, 255, 255, 255, +255, 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, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 }; + +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, len2, leven; + unsigned char *p; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* valid output size ? */ + len2 = 4 * ((len + 2) / 3); + if (*outlen < len2 + 1) { + return CRYPT_BUFFER_OVERFLOW; + } + p = out; + leven = 3*(len / 3); + for (i = 0; i < leven; i += 3) { + *p++ = codes[(in[0] >> 2) & 0x3F]; + *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; + *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; + *p++ = codes[in[2] & 0x3F]; + in += 3; + } + /* Pad it if necessary... */ + if (i < len) { + unsigned a = in[0]; + unsigned b = (i+1 < len) ? in[1] : 0; + + *p++ = codes[(a >> 2) & 0x3F]; + *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; + *p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '='; + *p++ = '='; + } + + /* append a NULL byte */ + *p = '\0'; + + /* return ok */ + *outlen = p - out; + return CRYPT_OK; +} + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen) +{ + unsigned long t, x, y, z; + unsigned char c; + int g; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + g = 3; + for (x = y = z = t = 0; x < len; x++) { + c = map[in[x]&0xFF]; + if (c == 255) continue; + if (c == 254) { c = 0; g--; } + t = (t<<6)|c; + if (++y == 4) { + if (z + g > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + out[z++] = (unsigned char)((t>>16)&255); + if (g > 1) out[z++] = (unsigned char)((t>>8)&255); + if (g > 2) out[z++] = (unsigned char)(t&255); + y = t = 0; + } + } + if (y != 0) { + return CRYPT_INVALID_PACKET; + } + *outlen = z; + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/blowfish.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,541 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef BLOWFISH + +const struct _cipher_descriptor blowfish_desc = +{ + "blowfish", + 0, + 8, 56, 8, 16, + &blowfish_setup, + &blowfish_ecb_encrypt, + &blowfish_ecb_decrypt, + &blowfish_test, + &blowfish_keysize +}; + +static const ulong32 ORIG_P[16 + 2] = { + 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL, + 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL, + 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL, + 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL, + 0x9216D5D9UL, 0x8979FB1BUL +}; + +static const ulong32 ORIG_S[4][256] = { + { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL, + 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL, + 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL, + 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL, + 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL, + 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL, + 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL, + 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL, + 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL, + 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL, + 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL, + 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL, + 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL, + 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL, + 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL, + 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL, + 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL, + 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL, + 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL, + 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL, + 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL, + 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL, + 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL, + 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL, + 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL, + 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL, + 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL, + 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL, + 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL, + 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL, + 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL, + 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL, + 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL, + 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL, + 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL, + 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL, + 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL, + 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL, + 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL, + 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL, + 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL, + 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL, + 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL, + 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL, + 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL, + 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL, + 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL, + 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL, + 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL, + 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL, + 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL, + 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL, + 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL, + 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL, + 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL, + 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL, + 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL, + 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL, + 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL, + 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL, + 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL, + 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL, + 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL, + 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL }, + { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL, + 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL, + 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL, + 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL, + 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL, + 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL, + 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL, + 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL, + 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL, + 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL, + 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL, + 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL, + 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL, + 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL, + 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL, + 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL, + 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL, + 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL, + 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL, + 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL, + 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL, + 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL, + 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL, + 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL, + 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL, + 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL, + 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL, + 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL, + 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL, + 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL, + 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL, + 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL, + 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL, + 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL, + 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL, + 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL, + 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL, + 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL, + 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL, + 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL, + 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL, + 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL, + 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL, + 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL, + 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL, + 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL, + 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL, + 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL, + 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL, + 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL, + 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL, + 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL, + 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL, + 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL, + 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL, + 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL, + 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL, + 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL, + 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL, + 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL, + 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL, + 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL, + 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL, + 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL }, + { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL, + 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL, + 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL, + 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL, + 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL, + 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL, + 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL, + 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL, + 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL, + 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL, + 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL, + 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL, + 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL, + 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL, + 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL, + 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL, + 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL, + 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL, + 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL, + 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL, + 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL, + 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL, + 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL, + 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL, + 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL, + 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL, + 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL, + 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL, + 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL, + 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL, + 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL, + 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL, + 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL, + 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL, + 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL, + 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL, + 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL, + 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL, + 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL, + 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL, + 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL, + 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL, + 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL, + 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL, + 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL, + 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL, + 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL, + 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL, + 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL, + 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL, + 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL, + 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL, + 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL, + 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL, + 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL, + 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL, + 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL, + 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL, + 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL, + 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL, + 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL, + 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL, + 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL, + 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL }, + { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL, + 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL, + 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL, + 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL, + 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL, + 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL, + 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL, + 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL, + 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL, + 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL, + 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL, + 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL, + 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL, + 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL, + 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL, + 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL, + 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL, + 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL, + 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL, + 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL, + 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL, + 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL, + 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL, + 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL, + 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL, + 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL, + 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL, + 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL, + 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL, + 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL, + 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL, + 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL, + 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL, + 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL, + 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL, + 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL, + 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL, + 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL, + 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL, + 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL, + 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL, + 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL, + 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL, + 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL, + 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL, + 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL, + 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL, + 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL, + 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL, + 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL, + 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL, + 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL, + 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL, + 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL, + 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL, + 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL, + 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL, + 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL, + 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL, + 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL, + 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL, + 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL, + 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL, + 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL } +}; + +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, + symmetric_key *skey) +{ + ulong32 x, y, z, A; + unsigned char B[8]; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check key length */ + if (keylen < 8 || keylen > 56) { + return CRYPT_INVALID_KEYSIZE; + } + + /* check rounds */ + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + /* load in key bytes (Supplied by David Hopwood) */ + for (x = y = 0; x < 18; x++) { + A = 0; + for (z = 0; z < 4; z++) { + A = (A << 8) | ((ulong32)key[y++] & 255); + if (y == (ulong32)keylen) { + y = 0; + } + } + skey->blowfish.K[x] = ORIG_P[x] ^ A; + } + + /* copy sboxes */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y++) { + skey->blowfish.S[x][y] = ORIG_S[x][y]; + } + } + + /* encrypt K array */ + for (x = 0; x < 8; x++) { + B[x] = 0; + } + + for (x = 0; x < 18; x += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.K[x], &B[0]); + LOAD32H(skey->blowfish.K[x+1], &B[4]); + } + + /* encrypt S array */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.S[x][y], &B[0]); + LOAD32H(skey->blowfish.S[x][y+1], &B[4]); + } + } + +#ifdef CLEAN_STACK + zeromem(B, sizeof(B)); +#endif + + return CRYPT_OK; +} + +#ifndef __GNUC__ +#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)] +#else +#define F(x) ((key->blowfish.S[0][byte(x,3)] + key->blowfish.S[1][byte(x,2)]) ^ key->blowfish.S[2][byte(x,1)]) + key->blowfish.S[3][byte(x,0)] +#endif + +#ifdef CLEAN_STACK +static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#ifndef __GNUC__ + S1 = key->blowfish.S[0]; + S2 = key->blowfish.S[1]; + S3 = key->blowfish.S[2]; + S4 = key->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(L, &pt[0]); + LOAD32H(R, &pt[4]); + + /* do 16 rounds */ + for (r = 0; r < 16; ) { + L ^= key->blowfish.K[r++]; R ^= F(L); + R ^= key->blowfish.K[r++]; L ^= F(R); + L ^= key->blowfish.K[r++]; R ^= F(L); + R ^= key->blowfish.K[r++]; L ^= F(R); + } + + /* last keying */ + R ^= key->blowfish.K[17]; + L ^= key->blowfish.K[16]; + + /* store */ + STORE32H(R, &ct[0]); + STORE32H(L, &ct[4]); +} + +#ifdef CLEAN_STACK +void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _blowfish_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#ifndef __GNUC__ + S1 = key->blowfish.S[0]; + S2 = key->blowfish.S[1]; + S3 = key->blowfish.S[2]; + S4 = key->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(R, &ct[0]); + LOAD32H(L, &ct[4]); + + /* undo last keying */ + R ^= key->blowfish.K[17]; + L ^= key->blowfish.K[16]; + + /* do 16 rounds */ + for (r = 15; r > 0; ) { + L ^= F(R); R ^= key->blowfish.K[r--]; + R ^= F(L); L ^= key->blowfish.K[r--]; + L ^= F(R); R ^= key->blowfish.K[r--]; + R ^= F(L); L ^= key->blowfish.K[r--]; + } + + /* store */ + STORE32H(L, &pt[0]); + STORE32H(R, &pt[4]); +} + +#ifdef CLEAN_STACK +void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _blowfish_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + + +int blowfish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + symmetric_key key; + static const struct { + unsigned char key[8], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78} + }, + { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A} + }, + { + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2} + } + }; + unsigned char tmp[2][8]; + int x, y; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key); + blowfish_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if ((memcmp(tmp[0], tests[x].ct, 8) != 0) || (memcmp(tmp[1], tests[x].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int blowfish_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 56) { + *desired_keysize = 56; + } + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/burn_stack.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,21 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +void burn_stack(unsigned long len) +{ + unsigned char buf[32]; + zeromem(buf, sizeof(buf)); + if (len > (unsigned long)sizeof(buf)) + burn_stack(len - sizeof(buf)); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cast5.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,669 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Implementation of CAST5 (RFC 2144) by Tom St Denis */ +#include "mycrypt.h" + +#ifdef CAST5 + +const struct _cipher_descriptor cast5_desc = { + "cast5", + 15, + 5, 16, 8, 16, + &cast5_setup, + &cast5_ecb_encrypt, + &cast5_ecb_decrypt, + &cast5_test, + &cast5_keysize +}; + +static const ulong32 S1[256] = { +0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, +0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, +0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL, +0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL, +0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, +0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, +0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL, +0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL, +0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, +0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, +0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL, +0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL, +0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, +0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, +0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL, +0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL, +0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, +0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, +0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL, +0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL, +0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, +0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, +0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL, +0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL, +0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, +0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, +0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL, +0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL, +0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, +0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, +0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL, +0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL, +0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, +0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, +0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL, +0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL, +0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, +0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, +0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL, +0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL, +0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, +0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, +0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL}; + +static const ulong32 S2[256] = { +0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, +0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, +0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL, +0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL, +0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, +0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, +0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL, +0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL, +0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, +0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, +0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL, +0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL, +0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, +0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, +0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL, +0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL, +0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, +0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, +0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL, +0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL, +0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, +0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, +0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL, +0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL, +0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, +0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, +0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL, +0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL, +0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, +0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, +0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL, +0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL, +0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, +0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, +0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL, +0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL, +0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, +0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, +0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL, +0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL, +0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, +0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, +0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL}; + +static const ulong32 S3[256] = { +0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, +0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, +0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL, +0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL, +0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, +0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, +0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL, +0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL, +0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, +0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, +0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL, +0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL, +0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, +0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, +0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL, +0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL, +0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, +0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, +0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL, +0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL, +0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, +0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, +0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL, +0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL, +0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, +0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, +0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL, +0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL, +0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, +0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, +0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL, +0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL, +0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, +0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, +0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL, +0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL, +0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, +0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, +0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL, +0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL, +0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, +0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, +0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL}; + +static const ulong32 S4[256] = { +0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, +0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, +0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL, +0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL, +0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, +0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, +0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL, +0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL, +0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, +0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, +0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL, +0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL, +0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, +0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, +0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL, +0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL, +0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, +0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, +0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL, +0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL, +0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, +0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, +0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL, +0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL, +0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, +0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, +0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL, +0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL, +0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, +0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, +0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL, +0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL, +0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, +0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, +0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL, +0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL, +0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, +0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, +0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL, +0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL, +0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, +0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, +0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL}; + +static const ulong32 S5[256] = { +0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, +0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, +0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL, +0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL, +0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, +0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, +0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL, +0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL, +0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, +0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, +0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL, +0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL, +0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, +0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, +0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL, +0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL, +0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, +0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, +0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL, +0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL, +0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, +0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, +0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL, +0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL, +0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, +0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, +0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL, +0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL, +0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, +0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, +0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL, +0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL, +0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, +0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, +0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL, +0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL, +0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, +0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, +0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL, +0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL, +0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, +0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, +0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL}; + +static const ulong32 S6[256] = { +0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, +0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, +0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL, +0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL, +0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, +0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, +0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL, +0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL, +0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, +0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, +0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL, +0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL, +0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, +0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, +0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL, +0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL, +0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, +0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, +0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL, +0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL, +0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, +0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, +0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL, +0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL, +0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, +0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, +0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL, +0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL, +0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, +0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, +0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL, +0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL, +0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, +0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, +0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL, +0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL, +0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, +0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, +0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL, +0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL, +0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, +0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, +0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL}; + +static const ulong32 S7[256] = { +0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, +0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, +0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL, +0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL, +0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, +0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, +0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL, +0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL, +0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, +0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, +0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL, +0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL, +0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, +0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, +0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL, +0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL, +0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, +0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, +0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL, +0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL, +0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, +0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, +0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL, +0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL, +0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, +0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, +0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL, +0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL, +0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, +0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, +0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL, +0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL, +0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, +0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, +0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL, +0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL, +0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, +0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, +0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL, +0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL, +0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, +0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, +0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL}; + +static const ulong32 S8[256] = { +0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, +0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, +0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL, +0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL, +0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, +0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, +0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL, +0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL, +0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, +0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, +0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL, +0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL, +0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, +0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, +0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL, +0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL, +0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, +0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, +0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL, +0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL, +0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, +0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, +0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL, +0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL, +0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, +0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, +0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL, +0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL, +0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, +0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, +0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL, +0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL, +0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, +0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, +0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL, +0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL, +0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, +0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, +0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL, +0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL, +0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, +0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, +0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL}; + +/* returns the i'th byte of a variable */ +#ifdef _MSC_VER + #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))) +#else + #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255) +#endif + +#ifdef CLEAN_STACK +static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 x[4], z[4]; + unsigned char buf[16]; + int y, i; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (num_rounds == 12 && keylen > 10) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen < 5 || keylen > 16) { + return CRYPT_INVALID_KEYSIZE; + } + + /* extend the key as required */ + zeromem(buf, sizeof(buf)); + memcpy(buf, key, (size_t)keylen); + + /* load and start the awful looking network */ + for (y = 0; y < 4; y++) { + LOAD32H(x[3-y],buf+4*y); + } + + for (i = y = 0; y < 2; y++) { + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)]; + skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)]; + skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)]; + + /* second half */ + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)]; + skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)]; + skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)]; + } + + skey->cast5.keylen = keylen; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + zeromem(x, sizeof(x)); + zeromem(z, sizeof(z)); +#endif + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int z; + z = _cast5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2); + return z; +} +#endif + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km + R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)]; +} + +INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km ^ R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)]; +} + +INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km - R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)]; +} + +#ifdef CLEAN_STACK +static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 R, L; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32H(L,&pt[0]); + LOAD32H(R,&pt[4]); + L ^= FI(R, key->cast5.K[0], key->cast5.K[16]); + R ^= FII(L, key->cast5.K[1], key->cast5.K[17]); + L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]); + R ^= FI(L, key->cast5.K[3], key->cast5.K[19]); + L ^= FII(R, key->cast5.K[4], key->cast5.K[20]); + R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]); + L ^= FI(R, key->cast5.K[6], key->cast5.K[22]); + R ^= FII(L, key->cast5.K[7], key->cast5.K[23]); + L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]); + R ^= FI(L, key->cast5.K[9], key->cast5.K[25]); + L ^= FII(R, key->cast5.K[10], key->cast5.K[26]); + R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]); + if (key->cast5.keylen > 10) { + L ^= FI(R, key->cast5.K[12], key->cast5.K[28]); + R ^= FII(L, key->cast5.K[13], key->cast5.K[29]); + L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]); + R ^= FI(L, key->cast5.K[15], key->cast5.K[31]); + } + STORE32H(R,&ct[0]); + STORE32H(L,&ct[4]); +} + + +#ifdef CLEAN_STACK +void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _cast5_ecb_encrypt(pt,ct,key); + burn_stack(sizeof(ulong32)*3); +} +#endif + +#ifdef CLEAN_STACK +static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 R, L; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32H(R,&ct[0]); + LOAD32H(L,&ct[4]); + if (key->cast5.keylen > 10) { + R ^= FI(L, key->cast5.K[15], key->cast5.K[31]); + L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]); + R ^= FII(L, key->cast5.K[13], key->cast5.K[29]); + L ^= FI(R, key->cast5.K[12], key->cast5.K[28]); + } + R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]); + L ^= FII(R, key->cast5.K[10], key->cast5.K[26]); + R ^= FI(L, key->cast5.K[9], key->cast5.K[25]); + L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]); + R ^= FII(L, key->cast5.K[7], key->cast5.K[23]); + L ^= FI(R, key->cast5.K[6], key->cast5.K[22]); + R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]); + L ^= FII(R, key->cast5.K[4], key->cast5.K[20]); + R ^= FI(L, key->cast5.K[3], key->cast5.K[19]); + L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]); + R ^= FII(L, key->cast5.K[1], key->cast5.K[17]); + L ^= FI(R, key->cast5.K[0], key->cast5.K[16]); + STORE32H(L,&pt[0]); + STORE32H(R,&pt[4]); +} + +#ifdef CLEAN_STACK +void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _cast5_ecb_decrypt(ct,pt,key); + burn_stack(sizeof(ulong32)*3); +} +#endif + +int cast5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16]; + unsigned char pt[8]; + unsigned char ct[8]; + } tests[] = { + { 16, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2} + }, + { 10, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + }, + { 5, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E} + } + }; + int i, y, err; + symmetric_key key; + unsigned char tmp[2][8]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + cast5_ecb_encrypt(tests[i].pt, tmp[0], &key); + cast5_ecb_decrypt(tmp[0], tmp[1], &key); + if ((memcmp(tmp[0], tests[i].ct, 8) != 0) || (memcmp(tmp[1], tests[i].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; + #endif +} + +int cast5_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 5) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 16) { + *desired_keysize = 16; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbc_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,56 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CBC + +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc) +{ + int x, err; + unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cbc != NULL); + + /* decrypt the block from ct into tmp */ + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); + + /* is blocklen valid? */ + if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + /* xor IV against the plaintext of the previous step */ + for (x = 0; x < cbc->blocklen; x++) { + /* copy CT in case ct == pt */ + tmp2[x] = ct[x]; + + /* actually decrypt the byte */ + pt[x] = tmp[x] ^ cbc->IV[x]; + } + + /* replace IV with this current ciphertext */ + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = tmp2[x]; + } + #ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); + zeromem(tmp2, sizeof(tmp2)); + #endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbc_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CBC + +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc) +{ + int x, err; + unsigned char tmp[MAXBLOCKSIZE]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + /* xor IV against plaintext */ + for (x = 0; x < cbc->blocklen; x++) { + tmp[x] = pt[x] ^ cbc->IV[x]; + } + + /* encrypt */ + cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key); + + /* store IV [ciphertext] for a future block */ + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = ct[x]; + } + + #ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); + #endif + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbc_start.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CBC + +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(cbc != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* copy IV */ + cbc->blocklen = cipher_descriptor[cipher].block_length; + cbc->cipher = cipher; + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = IV[x]; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cfb_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,48 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CFB + +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = *ct; + *pt = *ct ^ cfb->IV[cfb->padlen]; + ++pt; + ++ct; + ++cfb->padlen; + } + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cfb_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CFB + +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); + ++pt; + ++ct; + ++cfb->padlen; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cfb_start.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,47 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CFB + +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + + /* copy data */ + cfb->cipher = cipher; + cfb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < cfb->blocklen; x++) + cfb->IV[x] = IV[x]; + + /* init the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the IV */ + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); + cfb->padlen = 0; + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/changes Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,957 @@ +May 12th, 2004 +v0.95 -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact + the transforms are circulant. AES dropped 5KB and WHIRLPOOL dropped 13KB + using the default build options on the x86. + -- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when + CLEAN_STACK has been defined. + -- added LTC_TEST support to rmd160 + -- updates to mycrypt_pk.h + -- updated rand_prime() to faciliate making RSA composites + -- DSA/RSA now makes composites of the exact size desired. + -- Refactored quite a bit of the code, fewer functions per C file + -- cleaned up the makefiles to organize the objects logically + -- added ICC makefile along with "profiled" targets for both GNU and ICC compilers + -- Marked functions for removal before v1.00 see PLAN for more information + -- GCC 3.4.0 tested and seems to work + -- Added PKCS #5 support + -- Fixed typo in comment header of .C files ;-) + -- Added PKCS #1 OAEP and PSS support. + +Feb 20th, 2004 +v0.94 -- removed unused variables from ocb.c and fixed it to match known test vectors. + -- Added PMAC support, minor changes to OMAC/EAX code [I think....] + -- Teamed up with Brian Gladman. His code verifies against my vectors and my code + verifies against his test vectors. Hazaa for co-operation! + -- Various small changes (added missing ARGCHKs and cleaned up indentation) + -- Optimization to base64, removed unused variable "c" + -- Added base64 gen to demos/tv_gen.c + -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird... + -- Fixed up all of the PK code by adding missing error checking, removed "res" variables, + shrunk some stack variables, removed non-required stack variables and added proper + error conversion from MPI to LTC codes. I also spotted a few "off by one" error + checking which could have been used to force the code to read past the end of + the buffer (in theory, haven't checked if it would work) by a few bytes. + -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I + also modded it so it stores in the output provided to the function (that is not on + the local stack) which saves memory and time. + -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later) + -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my + Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte]. This code uses the + teams new sbox design (not the original NESSIE one). + + +Jan 25th, 2004 +v0.93 -- [note: deleted v0.93 changes by accident... recreating from memory...] + -- Fix to RC2 to not deference pointer before ARGCHK + -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit + -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish + -- Fix to OMAC to test cipher block size first [prevents wasting any time] + -- Added more OMAC test vectors + -- Added EAX Encrypt+Authenticate support + -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin] + -- Added common headers to all C files + -- CTR mode supports big and little [default] endian counters now. + -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table. + -- added find_hash_any() akin to find_cipher_any(). + -- Added EAX code to demos/tv_gen.c Hazaa! + -- Removed SONY defines and files from codebase. + -- Added OCB support [patents be damned] and to demos/tv_gen.c + -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h + -- Made appropriate changes to the debug string in crypt.c + +Dec 24th, 2003 +v0.92 -- Updated the config.pl script so the options have more details. + -- Updated demos/tv_gen to include RIPEMD hashes + -- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table + is included [speedup: slight, about 4k cycles on my Athlon]. + -- Re-wrote the twofish large key generation [the four 8x32 key dependent tables]. Now about twice as fast. + With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled + in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size. + -- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops] + -- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified + (e.g. not PK_PRIVATE or PK_PUBLIC) + -- Fixed up demos/x86_prof so it sorts the output now :-) + -- The project is now powered by radioactive rubber pants. + -- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it + will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do] + -- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?] + -- Massive updates to the prime generation code. I use the LTM random prime functions [and provide a nice + interface between the LTC PRNG's and the LTM generic prng prototype]. I also use a variable number of tests + depending on the input size. This nicely speeds up most prime generation/testing within the library. + -- Added SHA-224 to the list of hashes. + -- Made HMAC test vectors constant and static [takes ROM space instead of RAM] + -- This release was brought to you by the letter P which stands for Patent Infringement. + -- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions + I also optimized the compression functions of all but MD2 to not perform input copies when avoidable. + -- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon] + -- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code. + -- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and + demos/x86_prof.c] + -- Added mechanical testing to cipher test vector routines. Now it encrypts 1000 times, then decrypts and + compares. Any fault (e.g. bug in code, compiler) in the routines is likely to show through. Doesn't + stress test the key gen though... + -- Matt Johnson found a bug in the blowfish.c apparently I was out of my mind and put twofish defines in there + The code now builds with any config. Thanks. + -- Added OMAC1 Message Authentication Code support to the library. + -- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit]. + Updated HMAC code to use them too. Hazaa! + -- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash(). + -- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin + conversion [now returns CRYPT_MEM, will fix it up better later] + -- Added DSA to the list of supported PK algorithms. + -- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent + problems on platforms where CHAR_BIT != 8 + -- Merged in LibTomMath v0.28 + -- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable + /dev/random]. + -- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/ + -- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line) + -- Fixed bug in hmac_done(). Apparently FIPS-198 [HMAC] specifies that the output can be truncated. My code + would not support that (does now just like the new OMAC code). + -- Removed "hashsize" from hmac_state as it wasn't being used. + -- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going). + -- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos]. + -- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version. Dropped +10 cycles/byte + on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz) + -- Added _ARGCHK() calls to is_prime() for the two input pointers. + +Sept 25th, 2003 +v0.91 -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash. + -- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines. + -- Added RIPEMD hashes to the hashsum demo. + -- Added hashsum demo to MSVC makefile. + -- Added RMD160 to the x86_prof demo [oops] + -- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28 + Fixes another potential memory leak. + +Sept 7th, 2003 +v0.90 -- new ROL/ROR for x86 GCC + -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library + when not required. + == By default the KR code is not enabled [it's only a demo anyways!] + -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes] + -- hmac_done() now requires you pass it the size of the destination buffer to prevent + buffer overflows. (API CHANGE) + -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined. + -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default + configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size, + +768-bit, 4 vs. 10 +1024-bit, 8 vs. 18 +1280-bit, 12 vs. 34 +1536-bit, 20 vs. 56 +1792-bit 28 vs. 88 +2048-bit, 40 vs. 124 +2560-bit, 71 vs. 234 +3072-bit, 113 vs. 386 +4096-bit, 283 vs. 916 + + Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary + incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR + reductions for quite some time. + -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total]. + -- The project has been released as public domain. TDCAL no longer applies. + +July 15th, 2003 +v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc + -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!] + -- Removed the LTC version of next_prime() and replaced it with a call to the + mp_prime_next_prime() from LibTomMath + -- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC + or cygwin. + +Jul 10th, 2003 +v0.88 -- Sped up CAST5 key schedule for MSVC + -- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in + ciphers like blowfish and AES to be 32-bits. E.g. when unsigned long is 64-bits. + -- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!] + -- Optimized SHA-1 and SHA-256 quite a bit too. + -- Fixed up the makefile to use -fomit-frame-pointer more liberally + -- Added tv_gen program which makes test vectors for ciphers/hashes + -- Merged in LibTomMath v0.22 + +Jun 19th, 2003 +v0.87 -- Many MSVC optimizations to the code base + -- Improved the AES and Twofish key schedule [faster, more constant time] + -- Tons of optimizations here and there. + +Jun 15th, 2003 +v0.86 -- Fixed up AES to workaround MSVC optimizer bug + -- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC + -- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte. + -- Fixed up demos/encrypt to remove serpent_desc from the list + -- Re-enabled MSVC optimizations w00t w00t + -- Replaced "errno" with "err" in all functions that had it so it wouldn't clash + with the global "errno" + -- Removed a set of unused variables from certain functions + -- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C :-) + +Jun 11th, 2003 +v0.85 -- Swapped in a new AES routine + -- Removed Serpent + -- Added TDCAL policy document + +Jun 1st, 2003 +v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more + -- Fixed another potential buffer problem. Not an overflow but could cause the + PK import routines to read past the end of the buffer. + -- Optimized the ECC mulmod more by removing a if condition that will always be false + -- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime + test from LibTomMath now + -- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h] + -- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now]. + + +Mar 29th, 2003 +v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space + -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL + -- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy + buffer overflow. + -- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return + errors now. + +Mar 15th, 2003 +v0.82 -- Manual updated + -- Added MSVC makefile [back, actually its written from scratch to work with NMAKE] + -- Change to HMAC helper functions API to avoid buffer overflow [source changes] + -- the rsa_encrypt_key was supposed to reject key sizes out of bounds ... + same fix to the rsa_sign_hash + -- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid + structures when being called. E.g. the indexes to the pad/ivs are not out of bounds + -- Cleaned up the DES code and simplified the core desfunc routine. + -- Simplified one of the boolean functions in MD4 + +Jan 16th, 2003 +v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger + -- Sped up the ECC mulmod() routine by making the word size adapt to the input. Saves a whopping 9 point + operations on 521-bit keys now (translates to about 8ms on my Athlon XP). I also now use barrett reduction + as much as possible. This sped the routine up quite a bit. + -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed. + -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format + (fix due to Mika Bostr�m) + -- Merged in LibTomMath for kicks + -- Changed the build process so that by default "mycrypt_custom.h" is included and provided + The makefile doesn't include any build options anymore + -- Removed the PS2 and VC makefiles. + +Dec 16th, 2002 +v0.80 -- Found a change I made to the MPI that is questionable. Not quite a bug but definately not desired. Had todo + with the digit shifting. In v0.79 I simply truncated without zeroing. It didn't cause problems during my + testing but I fixed it up none the less. + -- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes. + -- Fixed in rsa_exptmod() where I was getting the size of the result. Basically it accomplishes the same thing + but the fixed code is more readable. + -- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been. I've + also made the #define FAST_PK speed up signatures as well. Essentially FAST_PK tells the DH sub-system to + limit any private exponent to 256-bits. Note that when FAST_PK is defined does not make the library + binary or source incompatible with a copy of the library with it undefined. + -- Removed the DSA code. If you want fast diffie-hellman just define FAST_PK :-) + -- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums. Saves two bytes but is not binary + compatible with the previous release... sorry! I've performed the same fix to the ecc code as well. + -- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now] + -- Fixed a bug in the DH code where it missed trapping a few errors if they occurred. + -- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function. Essentially it was + testing to ensure that in the loop that searches for the next candidate that the step never grows beyond + 65000. Should have been testing for MP_DIGIT_MAX + -- Spruced up the config.pl script. It now makes a header file "mycrypt_custom.h" which can be included *before* + you include mycrypt.h. This allows you to add libtomcrypt to a project without completely changing your make + system around. Note that you should use the makefile it writes to at least build the library initially. + -- Used splint to check alot of the code out. Tons of minor fixes and explicit casts added. + -- Also made all the internal functions of MPI are now static to avoid poluting the namespace + -- **Notice**: There are no planned future releases for at least a month from the this release date. + +Dec 14th, 2002 +v0.79 -- Change to PK code [binary and source]. I made it so you have to pass the buffer size to the *_decrypt_key and + *_verify_hash functions. This prevents malformed packets from performing buffer overflows. I've also trimmed + the packet header size [by 4 bytes]. + -- Made the test program halt on the first error it occurs. Also made it trap more errors than before. + -- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website! + -- Included a perl script "config.pl" that will make "makefile.out" according to the users needs. + -- Added shell script to look for latest release + -- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles + -- updated the makefile to use BSD friendly archiving invokations + -- Changed the DH and ECC code to use base64 static key settings [e.g. the primes]. Dropped the code size by 3KB + and is ever-so-slightly faster than before. + -- added "mp_shrink" function to shrink the size of bignums. Specially useful for PK code :-) + -- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto + sized numbers]. Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of + heap todo the calculation. Both are #define'able controlled + -- Added XREALLOC macro to provide realloc() functionality. + -- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's + not being used. + -- Fixed potential bug in the ECC code. Only would occur on platforms where char is not eight bits [which isn't + often!] + -- Fixed up the ECC point multiplication, its about 15% faster now + -- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines + so they export as "unsigned" types saving 1 byte per bignum outputted. Not a lot but heck why not. + +Nov 28th, 2002 +v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB. + -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly. + -- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition. + -- Made the KR code check if the other PK systems are included [provides error when building otherwise]. + -- Made "aes" an alias for Rijndael via a pre-processor macro. Now you can use "aes_ecb_encrypt", etc... :-) + Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion. + -- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt). The *_sign_hash and *_encrypt_key functions + are all that is to remain. + -- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter. This fixes a + bug where improperly made key packets could result in reading passed the end of the buffer. This means + the code is no longer source compatible but still binary compatible. + -- Fixed a few other minor bugs in the PK import code while I was at it. + +Nov 26th, 2002 +v0.77 -- Updated the XTEA code to use pre-computed keys. With optimizations for speed it achieves 222Mbit/sec + compared to the 121Mbit/sec before. It is 288 bytes bigger than before. + -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes) + -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys] + -- Removed most test cases from Blowfish, left three of them there. Makes it smaller and faster to test. + -- Changed the primality routines around. I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve + step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work. + -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity. This means + that a invalid value could have caused segfaults, etc... + -- **NOTE** Changed the way the ECC/DH export/import functions work. They are source but not binary compatible + with v0.76. Essentially insteading of exporting the setting index like before I export the key size. Now + if you ever re-configure which key settings are supported the lib will still be able to make use of your + keys. + -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the + rest. It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before. The new blowfish + object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller. So the code is both smaller and + faster! + -- Optimized Twofish as well by inlining the round function. Gets ~400Mbit/sec compared to 280Mbit/sec before + and the code is only 78 bytes larger than the previous copy. + -- Removed SMALL_PRIME_TAB build option. I use the smaller table always. + -- Fixed some mistakes concerning prime generation in the manual. + -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz] + +Nov 25th, 2002 +v0.76 -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size. Got the lib + downto 265KB using GCC 3.2 on my x86 box. + -- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design. + -- Updated all other test vector routines to return as soon as an error is found + -- fixed a bug in the test program where errors in the hash test routines would not be reported + correctly. I found this by temporarily changing one of the bytes of the test vectors. All the + hashes check out [the demos/test.c would still have reported an error, just the wrong one]. + + +Nov 24th, 2002 +v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL + -- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would + not be closed. + -- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code + In the next release "-Wconversion" will be enabled which will deal with all implicit casts. + +Nov 22nd, 2002 [later in the day] +v0.74 -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms + -- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions] + -- Wrote a small variant of Rijndael (trimmed 13KB) + -- Trimmed the TIGER/192 hash function a bit + -- Overall the entire lib compiled is 295KB [down from 400KB before] + -- Fixed a few minor oversights in the MSVC makefile + +Nov 22nd, 2002 +v0.73 -- Fixed bug in RC4 code where it could only use 255 byte keys. + -- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it... + -- Removed the ecc compress/expand points from the global scope. Reduces namespace polution + -- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be + able todo since the SPRNG has no state... + -- Corrected some oversights in the manual and the examples... + -- By default the GF(2^W) math library is excluded from the build. The source is maintained because I wrote it + and like it :-). This way the built library is a tad smaller + -- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized. + +Nov 21th, 2002 +v0.72 -- Fixed bug in the prime testing. In the Miller-Rabin test I was raising the base to "N-1" not "r". + The math still worked out fine because in effect it was performing a Fermat test. Tested the new code and it + works properly + -- Fixed some of the code where it was still using the old error syntax + -- Sped up the RSA decrypt/sign routines + -- Optimized the ecc_shared_secret routine to not use so much stack + -- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip + to + +Nov 19th, 2002 +v0.71 -- HELP TOM. I need tuition for the January semester. Now I don't want to force donations [nor will I ever] + but I really need the help! See my website http://tom.iahu.ca/help_tom.html for more details. Please help + if you can! + -------------------------------------------------------------------------------------------------------------- + -- Officially the library is no longer supported in GCC 3.2 in windows [cygwin]. + In windows you can either use GCC 2.95.3 or try your luck with 3.2 It seems that + "-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???] + If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2" + -- Started new error handling API. Similar to the previous except there are more error codes than just + CRYPT_ERROR + -- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!] + -- Merged in more changes from Sky Schulz. I have to make mention here that he has been a tremendous help in + getting me motivated to make some much needed updates to the library! + -- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards + -- Fixed a bug in the RC4 code [wasn't setting up the key correctly] + -- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...) + -- Fixed numerous bugs in the PK code. Essentially I was "freeing" keys when the import failed. This is neither + required nor a good a idea [double free]. + -- Tom needs a job. + -- Fixed up the test harness as requested by Sky Schulz. Also modifed the timing routines to run for X seconds + and count # of ops performed. This is more suitable than say encrypting 10 million blocks on a slow processor + where it could take minutes! + -- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax + -- Removed the PKCS code since it was incomplete. In the future I plan on writing a "add-on" library that + provides PKCS support... + -- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h + -- Willing to work on an hourly basis for 15$ CDN per hour. + -- updated the test program to not test ciphers not included + -- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...] + -- fixed numerous failures to detect buffer overflows [minor] in the PK code. + -- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup + function + -- check out my CV at http://tom.iahu.ca/cv.html + -- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...] + -- merged in rudimentary [for testing] PS2 RNG from Sky Schulz + -- merged in PS2 timer code [only shell included due to NDA reasons...] + -- updated HMAC code to return errors where possible + -- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt] + +Nov 12th, 2002 +v0.70 -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz) + -- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h + -- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?] + -- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz.... + -- Added support for substituting out the clock() function (Sky Schulz) + -- Fixed up makefile to include new headers in the HEADERS variable + -- Removed "coin.c" as its not really useful anyways + -- Removed many "debug" printfs that would show up on failures. Basically I wanted to ensure the only output + would be from the developer themselves. + -- Added "rc4.c" a RC4 implementation with a PRNG interface. Since RC4 isn't a block cipher it wouldn't work + too well as a block cipher. + -- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code + -- updated makefile to make subdirectory properly (Sku Schulz) + -- Started towards new API setup. Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK" + In future releases functions will return things other than CRYPT_ERROR on error to give more useful + thread safe error reporting. The manual will be updated to reflect this. For this release all + errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change. + -- Removed the zlib branch since its not really required anyways. Makes the package smaller + +Nov 11th, 2002 +v0.69 -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers + -- Note I forgot to change the CRYPT version tag in v0.68... fixed now. + +Nov 8th, 2002 +v0.68 -- Fixed flaw in kr_import/kr_export that wasted 4 bytes. Source but not binary compatible with v0.67 + -- Fixed bug in kr_find_name that used memcmp to match strings. Uses strncmp now. + -- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing] + -- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt. + -- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the + respective ciphers can use. + -- Fixed a bug in hashsum demo that would report the hash for files that don't exist! + +Oct 16th, 2002 +v0.67 -- Moved the function prototypes into files mycrypt_*.h. To "install" the lib just copy all the + header files "*.h" from the base of this project into your global include path. + -- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int" + -- Added keyring support for the PK functions + -- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key. Basically + move the first argument to the next to last. + -- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group + -- replaced the primes in the DH code with new ones that are larger than the size they are + associated with. That is a 1024-bit DH key will have a 1025-bit prime as the modulus + -- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66] + -- major editing of the manual, started Docer program + -- added 160 and 224 bit key settings for ECC. This makes the DH and ECC binary wise incompatible with v0.66 + -- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit + -- Removed ID_TAG from all files [meh, not a big fan...] + -- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo + -- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start() + -- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls + Returns int now instead of void. + +Sept 24th, 2002 +v0.66 -- Updated the /demos/test.c program to time the hashes correctly. Also it uses the yarrow PRNG for all of the + tests meaning its possible to run on RNG less platforms + -- Updated the /demos/hashsum.c program to hash from the standard input + -- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same + time. + -- Dan Kaminsky suggested some cleanups for the code and the MPI config + Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want + to read the stuff you'll have to convert it + -- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed + +Sept 20th, 2002 +v0.65 -- Wayne Scott ([email protected]) made a few of suggestions to improve the library. Most + importantly he pointed out the math lib is not really required. He's also tested the lib on 18 + different platforms. According to him with only a few troubles [lack of /dev/random, etc] the + library worked as it was supposed to. You can find the list at + http://www.bitkeeper.com/Products.BitKeeper.Platforms.html + -- Updated the hash_file and hash_memory functions to keep track of the size of the output + -- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more + -- Modified the mycrypt_cfg.h to autodetect x86-32 machines + +Sept 19th, 2002 +v0.64 -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally] + -- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages + -- fixed more typos in the manual + -- removed all unused variables from the core library (ignore the ID_TAG stuff) + -- added "const char *crypt_build_settings" string which is a build time constant that gives a listing + of all the build time options. Useful for debugging since you can send that to me and I will know what + exactly you had set for the mycrypt_cfg.h file. + -- Added control over endianess. Out of the box it defaults to endianess neutral but you can trivially + configure the library for your platform. Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my + Athlon box. See "mycrypt_cfg.h" for more information. + +Sept 11th, 2002 +v0.63 -- Made hashsum demo output like the original md5sum program + -- Made additions to the examples in the manual (fixed them up a bunch) + -- Merged in the base64 code from Wayne Scott ([email protected]) + +Aug 29th, 2002 +v0.62 -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update. + +Aug 9th, 2002 +v0.61 -- Fixed a bug in the DES code [oops I read something wrong]. + +Aug 8th, 2002 +v0.60 -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V. + +Aug 7th, 2002 +v0.59 -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC. + -- Cleaned up a little in the makefile + -- added code that times the hash functions too in the test program + +Aug 3rd, 2002 +v0.58 -- Added more stack cleaning conditionals throughout the code. + -- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK + -- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message + now they only make one call to ctr_encrypt()/ctr_decrypt(). + +Aug 2nd, 2002 +v0.57 -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name. + -- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a + key size. By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that + down if required. + -- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus). + -- The padding method for RSA is more clearly documented. Namely if you want to encrypt/sign something of length + N then your modulus must be of length 1+3N. So to sign a message with say SHA-384 [48 bytes] you need a + 145 byte (1160 bits) modulus. This is all in the manual now. + -- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every + cipher/hash call + -- Sped up the hash "process()" functions by not copying one byte at a time. + ++ (added just after I uploaded...) + MD4 process() now handles input buffers > 64 bytes + +Aug 1st, 2002 +v0.56 -- Cleaned up the comments in the Blowfish code. + -- Oh yeah, in v0.55 I made all of the descriptor elements constant. I just forgot to mention it. + -- fixed a couple of places where descriptor indexes were tested wrong. Not a huge bug but now its harder + to mess up. + -- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library. + -- Added the RC2 block cipher to the library. + -- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers + can use them with less confusion. + +July 29th, 2002 +v0.55 -- My god stupid Blowfish has yet again been fixed. I swear I hate that cipher. Next bug in it and boom its out of the + library. Use AES or something else cuz I really hate Blowfish at this stage.... + -- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!] + +July 19th, 2002 +v0.54 -- Blowfish now conforms to known test vectors. Silly bad coding tom! + -- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before] + +July 18th, 2002 +v0.53 -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)] + -- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code + with an invalid index ever now. + -- Simplified the Yarrow code once again :-) + +July 12th, 2002 +v0.52 -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512. Now MD4 will work with + all the routines... + -- Fixed the comments in SHA-512 to be a bit more meaningful + -- In md4 I made the PADDING array const [again to store it in ROM] + -- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer + -- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1 + -- Fixed a logical error in the CTR code which would make it skip the first IV value. This means + the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more + sense this way. + -- Added {} braces for as many if/for/blocks of code I could find. My rule is that every for/if/while/do block + must have {} braces around it. + -- made the rounds table in saferp_setup const [again for the ROM think about the ROM!] + -- fixed RC5 since it no longer requires rc5 to be registered in the lib. It used to since the descriptors used to + be part of the table... + -- the packet.c code now makes crypt_error literal string errors when an error occurs + -- cleaned up the SAFER+ key schedule to be a bit easier to read. + -- fixed a huge bug in Twofish with the TWOFISH_SMALL define. Because I clean the stack now I had + changed the "g_func()" to be called indirectly. I forgot to actually return the return of the Twofish + g_func() function which caused it not to work... [does now :-)] + +July 11th, 2002 +v0.51 -- Fixed a bug in SHA512/384 code for multi-block messages. + -- Added more test vectors to the SHA384/512 and TIGER hash functions + -- cleaned up the hash done routines to make more sense + +July 10th, 2002 +v0.50 -- Fixed yarrow.c so that the cipher/hash used would be registered. Also fixed + a bug where the SAFER+ name was "safer" but should have been "safer+". + -- Added an element to the hash descriptors that gives the size of a block [sent into the compressor] + -- Cleaned up the support for HMAC's + -- Cleaned up the test vector routines to make the test vector data const. This means on some platforms it will be + placed in ROM not RAM now. + -- Added MD4 code submited by Dobes Vandermeer ([email protected]) + -- Added "burn_stack" function [idea taken from another source of crypto code]. The idea is if a function has + alot of variables it will clean up better. Functions like the ecb serpent and twofish code will now have their + stacks cleaned and the rest of the code is getting much more straightforward. + -- Added a hashing demo by Daniel Richards ([email protected]) + -- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style. + For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec. + -- Fixed the register/unregister functions to properly report errors in crypt_error + -- Correctly updated yarrow code to remove a few unused variables. + -- Updated manual to fix a few erroneous examples. + -- Added section on Hash based Message Authentication Codes (HMAC) to the manual + +June 19th, 2002 +v0.46 -- Added in HMAC code from Dobes Vandermeer ([email protected]) + +June 8th, 2002 +v0.45 -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause + undefined behaviour. + -- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key. + -- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h + +Apr 4th, 2002 +v0.44 -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it. + +Mar 22nd, 2002 +v0.43 -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug. + -- Updated the GCC makefile not to use -O3 or -funroll-loops + -- Version tag in mycrypt.h has been updated :-) + +Mar 10th, 2002 +v0.42 -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste) + +Mar 3rd, 2002 +v0.41 -- Added support to link and use ciphers at compile time. This can greatly reduce the code size! + -- Added a demo to show off how small an application can get... 46kb! + -- Disastry pointed out that Blowfish is supposed to be high endian. + -- Made registry code for the PRNGs as well [now the smallest useable link is 43kb] + +Feb 11th, 2002 +v0.40 -- RSA signatures use [and check for] fixed padding scheme. + -- I'm developing in Linux now :-) + -- No more warnings from GCC 2.96 + +Feb 5th, 2002 +v0.39 -- Updated the XTEA code to work in accordance with the XTEA design + +January 24th, 2002 +v0.38 -- CFB and OFB modes can now handle blocks of variable size like the CTR code + -- Wrote a wrapper around the memory compress functions in Zlib that act like the functions + in the rest of my crypto lib + +January 23rd, 2002 +v0.37 -- Added support code so that if a hash size and key size for a cipher don't match up they will + use the next lower key supported. (mainly for the PK code). So you can now use SHA-1 with + Twofish, etc... + -- Added more options for Twofish. You can now tell it to use precomputed sboxes and MDS multiplications + This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes. + -- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB + -- Fixed all of the PK packet code to use the same header format [see packet.c]. This makes the PK code + binary wise incompatible with previous releases while the API has not changed at all. + +January 22nd, 2002 +v0.36 -- Corrections to the manual + -- Made a modification to Twofish which lets you build a "small ram" variant. It requires + about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal + variant requires. + -- Reduced the stack space used in all of the PK routines. + +January 19th, 2002 +v0.35 -- If you removed the first hash or cipher from the library it wouldn't return an error if + you used an ID=0 [i.e blowfish or sha256] in any routine. Now it checks for that and will + return an error like it should + -- Merged in new routines from Clay Culver. These routines are for the PK code so you can easily + encode a symmetric key for multiple recipients. + -- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed. + Originally I wanted to ensure that the keys were smaller than the order of the field used + However, the bias is so insignifcant using full sizes. For example, with a ECC-192 key the order + is about 2^191.99, so instead I rounded down and used a 184-bit secret key. Now I simply use a full 192-bit + key the code will work just the same except that some 192-bit keys will be duplicates which is not a big + deal since 1/2^192 is a very small bias! + -- Made the configuration a bit simpler and more exacting. You can for example now select which DH or ECC + key settings you wish to support without including the data for all other key settings. I put the #defines + in a new file called "mycrypt_cfg.h" + -- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used + -- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues. The yarrow code will now + use what ever remaining hash/cipher combo is left [after you #undef them] at build time. He also suggested + a fix to remove unused structures from the symmetric_key and hash_state unions. + -- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can + encrypt messages any size block at a time. + -- Simplified the yarrow code to take advantage of the new CTR code. + -- Added a 4096-bit DH key setting. That took me about 36 hours to find! + -- Changed the base64 routines to use a real base64 encoding scheme. + -- Added in DH and ECC "encrypt_key()" functions. They are still rather "beta"ish. + -- Added **Twofish** to the list of ciphers! + +January 18th, 2002 +v0.34 -- Added "sha512" to the list of hashes. Produces a 512-bit message digest. Note that with the current + padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures. + -- Cleaned up the other hash functions to use the LOAD and STORE macros... + +January 17th, 2002 +v0.33 -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't + work with the padding scheme and large symmetric keys. + -- Added information concerning the Zlib license to the manual + -- Added a 3072-bit key setting for the DH code. + -- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion. + -- Fixed an embarassing typo in the manual concerning the hashes. Thank's Clay for finding it! + -- Fixed rand_prime() so that it makes primes bigger than the setting you give. For example, + if you want a 1024-bit prime it would make a 1023-bit one. Now it ensures that the prime + it makes is always greater than 2^(8n) (n == bytes in prime). This doesn't have a huge + impact on security but I corrected it just the same. + -- Fixed the CTR routine to work on platforms where char != 8-bits + -- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries + I "AND" with 0xFFFFFFFF. That forces only the lower 32-bits to have information in it. On x86 platforms + most compilers optimize out the AND operation since its a nop. + +January 16th, 2002 +v0.32 -- Made Rijndael's setup function fully static so it is thread safe + -- Svante Seleborg suggested a cosmetic style fixup for aes.c, + basically to remove some of the #defines to clean it up + -- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes + the PK message formats *incompatible* with previous releases. + -- Merge in Zlib :-) + + +January 15th, 2002 +v0.31 -- The RSA routines can now use CRT to speed up decryption/signatures. The routines are backwards + compatible with previous releases. + -- Fixed another bug that Svante Seleborg found. Basically you could buffer-overrun the + rsa_exptmod() function itself if you're not careful. That's fixed now. Fixed another bug in + rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used + memory. + -- improved the readability of the PK import/export functions + -- Added a fix to RSA.C by Clay Culver + -- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64". + +January 14th, 2002 +v0.30 -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found. + Basically if you added entropy to the pool in small increments it could in fact + cancel out. Now I hash the pool with the new data which is way smarter. + +January 12th, 2002 +v0.29 -- Added MPI code written by Svante Seleborg to the library. This will make the PK code much + easier to follow and debug. Actually I've already fixed a memory leak in dh_shared_secret(). + -- Memory leaks found and correct in all three PK routines. The leaks would occur when a bignum + operation fails so it wouldn't normally turn up in the course of a program + -- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es + +January 11th, 2002 +v0.28 -- Cleaned up some code so that it doesn't assume "char == 8bits". Mainly SAFER+ has been + changed. + -- ***HUGE*** changes in the PK code. I check all return values in the bignum code so if there + are errors [insufficient memory, etc..] it will be reported. This makes the code fairly more + robust and likely to catch any errors. + -- Updated the is_prime() function to use a new prototype [it can return errors now] and it also + does trial divisions against more primes before the Rabin Miller steps + -- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations. + -- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation. + I should note that there is not alot of concrete information about the cipher. "Ansi C" versions + I found did not address endianess and were not even portable!. This code is portable and to the + best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper. + -- Reformated the manual to include the **FULL** source code optimized to be pritable. + +January 9th, 2002 +v0.27 -- Changed the char constants to numerical values. It is backwards compatible and should work on + platforms where 'd' != 100 [for example]. + -- Made a change to rand_prime() which takes the input length as a signed type so you can pass + a negative len to get a "3 mod 4" style prime... oops + -- changed the MSVC makefile to build with a warning level of three, no warnings! + +January 8th, 2002 +v0.26 -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt + the output + -- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions. + -- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int() + I added a work around that catches the error and continues normally. + +January 8th, 2002 +v0.25 -- Added a stupid define so MSVC 6.00 can build the library. + -- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC + +January 7th, 2002 +v0.24 -- Sped up Blowfish by unrolling and removing the swaps. + -- Made the code comply with more traditional ANSI C standards + Should compile with MSVC with less errors + -- moved the demos and documentation into their own directories + so you can easily build the library with other tool chains + by compiling the files in the root + -- converted functions with length of outputs to use + "unsigned long" so 16-bit platforms will like this library more. + +January 5th, 2002 +v0.23 -- Fixed a small error in the MPI config it should build fine anywhere. + +January 4th, 2002 +v0.22 -- faster gf_mul() code + -- gf_shl() and gf_shr() are safe on 64-bit platforms now + -- Fixed an error in the hashes that Brian Gladman found. + Basically if the message has exactly 56 bytes left to be + compressed I handled them incorrectly. + +January 4th, 2002 +v0.21 -- sped up the ECC code by removing redundant divisions in the + point add and double routines. I also extract the bits more + efficiently in "ecc_mulmod()" now. + -- sped up [and documented] the rand_prime() function. Now it just + makes a random integer and increments by two until a prime is found + This is faster since it doesn't require alot of calls to the PRNG and + it doesn't require loading huge integers over and over. rand_prime() + can also make primes congruent to 3 mod 4 [i.e for a blum integer] + -- added a gf_sqrt() function that finds square roots in a GF(2^w) field + -- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator + divisor than the dividend. + +January 4th, 2002 +v0.20 -- Added the fixed MPI back in so RSA and DH are much faster again + +v0.19 -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code. + -- DH, ECC and RSA signature/decryption functions check if the key is private + -- new DH signature/verification code works just like the RSA/ECC versions + +January 3rd, 2002 +v0.18 -- Added way more comments to each .C file + -- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer] + -- fixed RC5 so it reads the default rounds out of the cipher_descriptor table + -- cleaned up ecc_export() + -- Cleaned up dh_import() and ecc_import() which also perform more + error checking now + -- Fixed a serious flaw in rsa_import() with private keys. + +January 2nd, 2002 +v0.17 -- Fixed a bug in the random prime generator that fixes the wrong bits to one + -- ECC and DH code verify that the moduli and orders are in fact prime. That + slows down the test routines alot but what are you gonna do? + -- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some + values of p. I replaced it with a slow function. Once the author of MPI fixes his faster routine + I will switch back. + +January 1st, 2002 [whoa new year!] +v0.16 -- Improved GF division code that is faster. + -- documented the GF code + +December 31st, 2001 +v0.15 -- A 1792-bit and 2048-bit DH setting was added. Took me all night to + find a 1792 and 2048-bit strong prime but what the heck + -- Library now has polynomial-basis GF(2^w) routines I wrote myself. Can be used to perform + ECC over GF(2^w) later on.... + -- Fixed a bug with the defines that allows it to build in windows + +December 30th, 2001 +v0.14 -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size + for the cipher used. It was defaulting to making a 256-bit IV... + -- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed... + -- spell checked the manual again... :-) + +December 30th, 2001 +v0.13 -- Switching back to older copy of MPI since it works! arrg.. + -- Added sign/verify functions for ECC + -- all signature verification routines default to invalid signatures. + -- Changed all calls to memset to zeromem. Fixed up some buffer problems + in other routines. All calls to zeromem let the compiler determine the size + of the data to wipe. + +December 29th, 2001 +v0.12 -- Imported a new version of MPI [the bignum library] that should + be a bit more stable [if you want to write your own bignum + routines with the library that is...] + -- Manual has way more info + -- hash_file() clears stack now [like it should] + -- The artificial cap on the hash input size of 2^32 bits has been + removed. Basically I was too lazy todo 64-bit math before + [don't ask why... I can't remember]. Anyways the hashes + support the size of 2^64 bits [if you ever use that many bits in a message + that's just wierd...] + -- The hashes now wipe the "hash_state" after the digest is computed. This helps + prevent the internal state of the hash being leaked accidently [i.e stack problems] + +December 29th, 2001 +v0.11 -- Made #define's so you can trim the library down by removing + ciphers, hashs, modes of operation, prngs, and even PK algorithms + For example, the library with rijndael+ctr+sha1+ECC is 91KB compared + to the 246kb the full library takes. + -- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to + the RSA packet routines. + -- ECC now compresses the public key, a ECC-192 public key takes 33 bytes + for example.... + +December 28th, 2001 +v0.10 -- going to restart the manual from scratch to make it more + clear and professional + -- Added ECC over Z/pZ. Basically provides as much as DH + except its faster since the numbers are smaller. For example, + A comparable 256-bit ECC key provides as much security as expected + from a DH key over 1024-bits. + -- Cleaned up the DH code to not export the symbol "sets[]" + -- Fixed a bug in the DH code that would not make the correct size + random string if you made the key short. For instance if you wanted + a 512-bit DH key it would make a 768-bit one but only make up 512-bits + for the exponent... now it makes the full 768 bits [or whatever the case + is] + -- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit + keys by mistake. + +December 25th, 2001 +v0.09 -- Includes a demo program called file_crypt which shows off + how to use the library to make a command line tool which + allows the user to encode/decode a file with any + hash (on the passphrase) and cipher in CTR mode. + -- Switched everything to use typedef's now to clear up the code. + -- Added AES (128/192 and 256 bit key modes) + +December 24th, 2001 +v0.08 -- fixed a typo in the manual. MPI stores its bignums in + BIG endian not little. + -- Started adding a RNG to the library. Right now it tries + to open /dev/random and if that fails it uses either the + MS CSP or the clock drift RNG. It also allows callbacks + since the drift RNG is slow (about 3.5 bytes/sec) + -- the RNG can also automatically setup a PRNG as well now + +v0.07 -- Added basic DH routines sufficient to + negotiate shared secrets + [see the manual for a complete example!] + -- Fixed rsa_import to detect when the input + could be corrupt. + -- added more to the manual. + +December 22nd, 2001 +v0.06 -- Fixed some formatting errors in + the hash functions [just source code cleaning] + -- Fixed a typo in the error message for sha256 :-) + -- Fixed an error in base64_encode() that + would fail to catch all buffer overruns + -- Test program times the RSA and symmetric cipher + routines for kicks... + -- Added the "const" modifier to alot of routines to + clear up the purpose of each function. + -- Changed the name of the library to "TomCrypt" + following a suggestion from a sci.crypt reader.... + +v0.05 -- Fixed the ROL/ROR macro to be safe on platforms + where unsigned long is not 32-bits + -- I have added a bit more to the documentation + manual "crypt.pdf" provided. + -- I have added a makefile for LCC-Win32. It should be + easy to port to other LCC platforms by changing a few lines. + -- Ran a spell checker over the manual. + -- Changed the header and library from "crypt" to "mycrypt" to not + clash with the *nix package "crypt". + +v0.04 -- Fixed a bug in the RC5,RC6,Blowfish key schedules + where if the key was not a multiple of 4 bytes it would + not get loaded correctly. + +December 21st, 2001 + +v0.03 -- Added Serpent to the list of ciphers. + +v0.02 -- Changed RC5 to only allow 12 to 24 rounds + -- Added more to the manual. + +v0.01 -- We will call this the first version.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,232 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* Dropbear doesn't need these + +const char *crypt_build_settings = + "LibTomCrypt " SCRYPT "\n\n" + "Endianess: " +#if defined(ENDIAN_NEUTRAL) + "neutral\n" +#elif defined(ENDIAN_LITTLE) + "little" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#elif defined(ENDIAN_BIG) + "big" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#endif + "Clean stack: " +#if defined(CLEAN_STACK) + "enabled\n" +#else + "disabled\n" +#endif + "Ciphers built-in:\n" +#if defined(BLOWFISH) + " Blowfish\n" +#endif +#if defined(RC2) + " RC2\n" +#endif +#if defined(RC5) + " RC5\n" +#endif +#if defined(RC6) + " RC6\n" +#endif +#if defined(SAFERP) + " Safer+\n" +#endif +#if defined(SAFER) + " Safer\n" +#endif +#if defined(RIJNDAEL) + " Rijndael\n" +#endif +#if defined(XTEA) + " XTEA\n" +#endif +#if defined(TWOFISH) + " Twofish " + #if defined(TWOFISH_SMALL) && defined(TWOFISH_TABLES) + "(small, tables)\n" + #elif defined(TWOFISH_SMALL) + "(small)\n" + #elif defined(TWOFISH_TABLES) + "(tables)\n" + #else + "\n" + #endif +#endif +#if defined(DES) + " DES\n" +#endif +#if defined(CAST5) + " CAST5\n" +#endif +#if defined(NOEKEON) + " Noekeon\n" +#endif +#if defined(SKIPJACK) + " Skipjack\n" +#endif + + "\nHashes built-in:\n" +#if defined(SHA512) + " SHA-512\n" +#endif +#if defined(SHA384) + " SHA-384\n" +#endif +#if defined(SHA256) + " SHA-256\n" +#endif +#if defined(SHA224) + " SHA-224\n" +#endif +#if defined(TIGER) + " TIGER\n" +#endif +#if defined(SHA1) + " SHA1\n" +#endif +#if defined(MD5) + " MD5\n" +#endif +#if defined(MD4) + " MD4\n" +#endif +#if defined(MD2) + " MD2\n" +#endif +#if defined(RIPEMD128) + " RIPEMD128\n" +#endif +#if defined(RIPEMD160) + " RIPEMD160\n" +#endif + + "\nBlock Chaining Modes:\n" +#if defined(CFB) + " CFB\n" +#endif +#if defined(OFB) + " OFB\n" +#endif +#if defined(ECB) + " ECB\n" +#endif +#if defined(CBC) + " CBC\n" +#endif +#if defined(CTR) + " CTR\n" +#endif + + "\nPRNG:\n" +#if defined(YARROW) + " Yarrow\n" +#endif +#if defined(SPRNG) + " SPRNG\n" +#endif +#if defined(RC4) + " RC4\n" +#endif + + "\nPK Algs:\n" +#if defined(MRSA) + " RSA\n" +#endif +#if defined(MDH) + " DH\n" +#endif +#if defined(MECC) + " ECC\n" +#endif +#if defined(MDSA) + " DSA\n" +#endif +#if defined(KR) + " KR\n" +#endif + + "\nCompiler:\n" +#if defined(WIN32) + " WIN32 platform detected.\n" +#endif +#if defined(__CYGWIN__) + " CYGWIN Detected.\n" +#endif +#if defined(__DJGPP__) + " DJGPP Detected.\n" +#endif +#if defined(_MSC_VER) + " MSVC compiler detected.\n" +#endif +#if defined(__GNUC__) + " GCC compiler detected.\n" +#endif +#if defined(INTEL_CC) + " Intel C Compiler detected.\n" +#endif + + "\nVarious others: " +#if defined(GF) + " GF " +#endif +#if defined(BASE64) + " BASE64 " +#endif +#if defined(MPI) + " MPI " +#endif +#if defined(HMAC) + " HMAC " +#endif +#if defined(OMAC) + " OMAC " +#endif +#if defined(PMAC) + " PMAC " +#endif +#if defined(EAX_MODE) + " EAX_MODE " +#endif +#if defined(OCB_MODE) + " OCB_MODE " +#endif +#if defined(TRY_UNRANDOM_FIRST) + " TRY_UNRANDOM_FIRST " +#endif +#if defined(LTC_TEST) + " LTC_TEST " +#endif +#if defined(PKCS_1) + " PKCS#1 " +#endif +#if defined(PKCS_5) + " PKCS#5 " +#endif + "\n" + "\n\n\n" + ; + */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt.out Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,88 @@ +\BOOKMARK [0][-]{chapter.1}{Introduction}{} +\BOOKMARK [1][-]{section.1.1}{What is the LibTomCrypt?}{chapter.1} +\BOOKMARK [2][-]{subsection.1.1.1}{What the library IS for?}{section.1.1} +\BOOKMARK [2][-]{subsection.1.1.2}{What the library IS NOT for?}{section.1.1} +\BOOKMARK [1][-]{section.1.2}{Why did I write it?}{chapter.1} +\BOOKMARK [2][-]{subsection.1.2.1}{Modular}{section.1.2} +\BOOKMARK [1][-]{section.1.3}{License}{chapter.1} +\BOOKMARK [1][-]{section.1.4}{Patent Disclosure}{chapter.1} +\BOOKMARK [1][-]{section.1.5}{Building the library}{chapter.1} +\BOOKMARK [1][-]{section.1.6}{Building against the library}{chapter.1} +\BOOKMARK [1][-]{section.1.7}{Thanks}{chapter.1} +\BOOKMARK [0][-]{chapter.2}{The Application Programming Interface \(API\)}{} +\BOOKMARK [1][-]{section.2.1}{Introduction}{chapter.2} +\BOOKMARK [1][-]{section.2.2}{Macros}{chapter.2} +\BOOKMARK [1][-]{section.2.3}{Functions with Variable Length Output}{chapter.2} +\BOOKMARK [1][-]{section.2.4}{Functions that need a PRNG}{chapter.2} +\BOOKMARK [1][-]{section.2.5}{Functions that use Arrays of Octets}{chapter.2} +\BOOKMARK [0][-]{chapter.3}{Symmetric Block Ciphers}{} +\BOOKMARK [1][-]{section.3.1}{Core Functions}{chapter.3} +\BOOKMARK [1][-]{section.3.2}{Key Sizes and Number of Rounds}{chapter.3} +\BOOKMARK [1][-]{section.3.3}{The Cipher Descriptors}{chapter.3} +\BOOKMARK [2][-]{subsection.3.3.1}{Notes}{section.3.3} +\BOOKMARK [1][-]{section.3.4}{Symmetric Modes of Operations}{chapter.3} +\BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4} +\BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4} +\BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4} +\BOOKMARK [1][-]{section.3.5}{Encrypt and Authenticate Modes}{chapter.3} +\BOOKMARK [2][-]{subsection.3.5.1}{EAX Mode}{section.3.5} +\BOOKMARK [2][-]{subsection.3.5.2}{OCB Mode}{section.3.5} +\BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{} +\BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4} +\BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4} +\BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2} +\BOOKMARK [0][-]{chapter.5}{Message Authentication Codes}{} +\BOOKMARK [1][-]{section.5.1}{HMAC Protocol}{chapter.5} +\BOOKMARK [1][-]{section.5.2}{OMAC Support}{chapter.5} +\BOOKMARK [1][-]{section.5.3}{PMAC Support}{chapter.5} +\BOOKMARK [0][-]{chapter.6}{Pseudo-Random Number Generators}{} +\BOOKMARK [1][-]{section.6.1}{Core Functions}{chapter.6} +\BOOKMARK [2][-]{subsection.6.1.1}{Remarks}{section.6.1} +\BOOKMARK [2][-]{subsection.6.1.2}{Example}{section.6.1} +\BOOKMARK [1][-]{section.6.2}{PRNG Descriptors}{chapter.6} +\BOOKMARK [1][-]{section.6.3}{The Secure RNG}{chapter.6} +\BOOKMARK [2][-]{subsection.6.3.1}{The Secure PRNG Interface}{section.6.3} +\BOOKMARK [0][-]{chapter.7}{RSA Routines}{} +\BOOKMARK [1][-]{section.7.1}{Background}{chapter.7} +\BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7} +\BOOKMARK [1][-]{section.7.3}{Packet Routines}{chapter.7} +\BOOKMARK [1][-]{section.7.4}{Remarks}{chapter.7} +\BOOKMARK [0][-]{chapter.8}{Diffie-Hellman Key Exchange}{} +\BOOKMARK [1][-]{section.8.1}{Background}{chapter.8} +\BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8} +\BOOKMARK [2][-]{subsection.8.2.1}{Remarks on Usage}{section.8.2} +\BOOKMARK [2][-]{subsection.8.2.2}{Remarks on The Snippet}{section.8.2} +\BOOKMARK [1][-]{section.8.3}{Other Diffie-Hellman Functions}{chapter.8} +\BOOKMARK [1][-]{section.8.4}{DH Packet}{chapter.8} +\BOOKMARK [0][-]{chapter.9}{Elliptic Curve Cryptography}{} +\BOOKMARK [1][-]{section.9.1}{Background}{chapter.9} +\BOOKMARK [1][-]{section.9.2}{Core Functions}{chapter.9} +\BOOKMARK [1][-]{section.9.3}{ECC Packet}{chapter.9} +\BOOKMARK [1][-]{section.9.4}{ECC Keysizes}{chapter.9} +\BOOKMARK [0][-]{chapter.10}{Digital Signature Algorithm}{} +\BOOKMARK [1][-]{section.10.1}{Introduction}{chapter.10} +\BOOKMARK [1][-]{section.10.2}{Key Generation}{chapter.10} +\BOOKMARK [1][-]{section.10.3}{Key Verification}{chapter.10} +\BOOKMARK [1][-]{section.10.4}{Signatures}{chapter.10} +\BOOKMARK [1][-]{section.10.5}{Import and Export}{chapter.10} +\BOOKMARK [0][-]{chapter.11}{Public Keyrings}{} +\BOOKMARK [1][-]{section.11.1}{Introduction}{chapter.11} +\BOOKMARK [1][-]{section.11.2}{The Keyring API}{chapter.11} +\BOOKMARK [0][-]{chapter.12}{GF\(2w\) Math Routines}{} +\BOOKMARK [0][-]{chapter.13}{Miscellaneous}{} +\BOOKMARK [1][-]{section.13.1}{Base64 Encoding and Decoding}{chapter.13} +\BOOKMARK [1][-]{section.13.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.13} +\BOOKMARK [2][-]{subsection.13.2.1}{Binary Forms of ``mp\137int'' Variables}{section.13.2} +\BOOKMARK [2][-]{subsection.13.2.2}{Primality Testing}{section.13.2} +\BOOKMARK [0][-]{chapter.14}{Programming Guidelines}{} +\BOOKMARK [1][-]{section.14.1}{Secure Pseudo Random Number Generators}{chapter.14} +\BOOKMARK [1][-]{section.14.2}{Preventing Trivial Errors}{chapter.14} +\BOOKMARK [1][-]{section.14.3}{Registering Your Algorithms}{chapter.14} +\BOOKMARK [1][-]{section.14.4}{Key Sizes}{chapter.14} +\BOOKMARK [2][-]{subsection.14.4.1}{Symmetric Ciphers}{section.14.4} +\BOOKMARK [2][-]{subsection.14.4.2}{Assymetric Ciphers}{section.14.4} +\BOOKMARK [1][-]{section.14.5}{Thread Safety}{chapter.14} +\BOOKMARK [0][-]{chapter.15}{Configuring the Library}{} +\BOOKMARK [1][-]{section.15.1}{Introduction}{chapter.15} +\BOOKMARK [1][-]{section.15.2}{mycrypt\137cfg.h}{chapter.15} +\BOOKMARK [1][-]{section.15.3}{The Configure Script}{chapter.15}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt.tex Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,3040 @@ +\documentclass[b5paper]{book} +\usepackage{hyperref} +\usepackage{makeidx} +\usepackage{amssymb} +\usepackage{color} +\usepackage{alltt} +\usepackage{graphicx} +\usepackage{layout} +\def\union{\cup} +\def\intersect{\cap} +\def\getsrandom{\stackrel{\rm R}{\gets}} +\def\cross{\times} +\def\cat{\hspace{0.5em} \| \hspace{0.5em}} +\def\catn{$\|$} +\def\divides{\hspace{0.3em} | \hspace{0.3em}} +\def\nequiv{\not\equiv} +\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} +\def\lcm{{\rm lcm}} +\def\gcd{{\rm gcd}} +\def\log{{\rm log}} +\def\ord{{\rm ord}} +\def\abs{{\mathit abs}} +\def\rep{{\mathit rep}} +\def\mod{{\mathit\ mod\ }} +\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} +\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} +\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} +\def\Or{{\rm\ or\ }} +\def\And{{\rm\ and\ }} +\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} +\def\implies{\Rightarrow} +\def\undefined{{\rm ``undefined"}} +\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} +\let\oldphi\phi +\def\phi{\varphi} +\def\Pr{{\rm Pr}} +\newcommand{\str}[1]{{\mathbf{#1}}} +\def\F{{\mathbb F}} +\def\N{{\mathbb N}} +\def\Z{{\mathbb Z}} +\def\R{{\mathbb R}} +\def\C{{\mathbb C}} +\def\Q{{\mathbb Q}} + +\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} + +\def\gap{\vspace{0.5ex}} +\makeindex +\begin{document} +\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.95} +\author{Tom St Denis \\ +\\ [email protected] \\ +http://libtomcrypt.org \\ \\ +Phone: 1-613-836-3160\\ +111 Banning Rd \\ +Kanata, Ontario \\ +K2L 1C3 \\ +Canada +} +\maketitle +This text and source code library are both hereby placed in the public domain. This book has been +formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. + +\vspace{10cm} + +\begin{flushright}Open Source. Open Academia. Open Minds. + +\mbox{ } + +Tom St Denis, + +Ontario, Canada +\end{flushright} +\newpage +\tableofcontents +\chapter{Introduction} +\section{What is the LibTomCrypt?} +LibTomCrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes, +pseudo-random number generators, public key cryptography (via RSA,DH or ECC/DH) and a plethora of support +routines. It is designed to compile out of the box with the GNU C Compiler (GCC) version 2.95.3 (and higher) +and with MSVC version 6 in win32. + +The library has been successfully tested on quite a few other platforms ranging from the ARM7TDMI in a +Gameboy Advanced to various PowerPC processors and even the MIPS processor in the PlayStation 2. Suffice it +to say the code is portable. + +The library is designed so new ciphers/hashes/PRNGs can be added at runtime and the existing API (and helper API functions) will +be able to use the new designs automatically. There exist self-check functions for each cipher and hash to ensure that +they compile and execute to the published design specifications. The library also performs extensive parameter error checking +and will give verbose error messages when possible. + +Essentially the library saves the time of having to implement the ciphers, hashes, prngs yourself. Typically implementing +useful cryptography is an error prone business which means anything that can save considerable time and effort is a good +thing. + +\subsection{What the library IS for?} + +The library typically serves as a basis for other protocols and message formats. For example, it should be possible to +take the RSA routines out of this library, apply the appropriate message padding and get PKCS compliant RSA routines. +Similarly SSL protocols could be formed on top of the low-level symmetric cipher functions. The goal of this package is +to provide these low level core functions in a robust and easy to use fashion. + +The library also serves well as a toolkit for applications where they don't need to be OpenPGP, PKCS, etc. compliant. +Included are fully operational public key routines for encryption, decryption, signature generation and verification. +These routines are fully portable but are not conformant to any known set of standards. They are all based on established +number theory and cryptography. + +\subsection{What the library IS NOT for?} + +The library is not designed to be in anyway an implementation of the SSL or OpenPGP standards. The library +is not designed to be compliant with any known form of API or programming hierarchy. It is not a port of any other +library and it is not platform specific (like the MS CSP). So if you're looking to drop in some buzzword +compliant crypto library this is not for you. The library has been written from scratch to provide basic functions as +well as non-standard higher level functions. + +This is not to say that the library is a ``homebrew'' project. All of the symmetric ciphers and one-way hash functions +conform to published test vectors. The public key functions are derived from publicly available material and the majority +of the code has been reviewed by a growing community of developers. + +\subsubsection{Why not?} +You may be asking why I didn't choose to go all out and support standards like P1363, PKCS and the whole lot. The reason +is quite simple too much money gets in the way. When I tried to access the P1363 draft documents and was denied (it +requires a password) I realized that they're just a business anyways. See what happens is a company will sit down and +invent a ``standard''. Then they try to sell it to as many people as they can. All of a sudden this ``standard'' is +everywhere. Then the standard is updated every so often to keep people dependent. Then you become RSA. If people are +supposed to support these standards they had better make them more accessible. + +\section{Why did I write it?} +You may be wondering, ``Tom, why did you write a crypto library. I already have one.''. Well the reason falls into +two categories: +\begin{enumerate} + \item I am too lazy to figure out someone else's API. I'd rather invent my own simpler API and use that. + \item It was (still is) good coding practice. +\end{enumerate} + +The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc. I'm trying to write my +{\bf own} crypto library and hopefully along the way others will appreciate the work. + +With this library all core functions (ciphers, hashes, prngs) have the {\bf exact} same prototype definition. They all load +and store data in a format independent of the platform. This means if you encrypt with Blowfish on a PPC it should decrypt +on an x86 with zero problems. The consistent API also means that if you learn how to use blowfish with my library you +know how to use Safer+ or RC6 or Serpent or ... as well. With all of the core functions there are central descriptor tables +that can be used to make a program automatically pick between ciphers, hashes and PRNGs at runtime. That means your +application can support all ciphers/hashes/prngs without changing the source code. + +\subsection{Modular} +The LibTomCrypt package has also been written to be very modular. The block ciphers, one-way hashes and +pseudo-random number generators (PRNG) are all used within the API through ``descriptor'' tables which +are essentially structures with pointers to functions. While you can still call particular functions +directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their +usage of the library. + +For example, consider a hardware platform with a specialized RNG device. Obviously one would like to tap +that for the PRNG needs within the library (\textit{e.g. making a RSA key}). All the developer has todo +is write a descriptor and the few support routines required for the device. After that the rest of the +API can make use of it without change. Similiarly imagine a few years down the road when AES2 (\textit{or whatever they call it}) is +invented. It can be added to the library and used within applications with zero modifications to the +end applications provided they are written properly. + +This flexibility within the library means it can be used with any combination of primitive algorithms and +unlike libraries like OpenSSL is not tied to direct routines. For instance, in OpenSSL there are CBC block +mode routines for every single cipher. That means every time you add or remove a cipher from the library +you have to update the associated support code as well. In LibTomCrypt the associated code (\textit{chaining modes in this case}) +are not directly tied to the ciphers. That is a new cipher can be added to the library by simply providing +the key setup, ECB decrypt and encrypt and test vector routines. After that all five chaining mode routines +can make use of the cipher right away. + + +\section{License} + +All of the source code except for the following files have been written by the author or donated to the project +under a public domain license: + +\begin{enumerate} + \item rc2.c + \item safer.c +\end{enumerate} + +`mpi.c'' was originally written by Michael Fromberger ([email protected]) but has since been replaced with my LibTomMath +library. + +``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c'' +was written by Richard De Moliner ([email protected]) and is public domain. + +The project is hereby released as public domain. + +\section{Patent Disclosure} + +The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice. To the best +of the authors knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers. +They can be removed from a build by simply commenting out the two appropriate lines in the makefile script. The rest +of the ciphers and hashes are patent free or under patents that have since expired. + +The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use +the ciphers you just can't advertise that you are doing so. + +\section{Building the library} + +To build the library on a GCC equipped platform simply type ``make'' at your command prompt. It will build the library +file ``libtomcrypt.a''. + +To install the library copy all of the ``.h'' files into your ``\#include'' path and the single libtomcrypt.a file into +your library path. + +With MSVC you can build the library with ``nmake -f makefile.msvc''. This will produce a ``tomcrypt.lib'' file which +is the core library. Copy the header files into your MSVC include path and the library in the lib path (typically +under where VC98 is installed). + +\section{Building against the library} + +In the recent versions the build steps have changed. The build options are now stored in ``mycrypt\_custom.h'' and +no longer in the makefile. If you change a build option in that file you must re-build the library from clean to +ensure the build is intact. The perl script ``config.pl'' will help setup the custom header and a custom makefile +if you want one (the provided ``makefile'' will work with custom configs). + +\section{Thanks} +I would like to give thanks to the following people (in no particular order) for helping me develop this project: +\begin{enumerate} + \item Richard van de Laarschot + \item Richard Heathfield + \item Ajay K. Agrawal + \item Brian Gladman + \item Svante Seleborg + \item Clay Culver + \item Jason Klapste + \item Dobes Vandermeer + \item Daniel Richards + \item Wayne Scott + \item Andrew Tyler + \item Sky Schulz + \item Christopher Imes +\end{enumerate} + +\chapter{The Application Programming Interface (API)} +\section{Introduction} +\index{CRYPT\_ERROR} \index{CRYPT\_OK} + +In general the API is very simple to memorize and use. Most of the functions return either {\bf void} or {\bf int}. Functions +that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful or one of the many error codes +if it failed. Certain functions that return int will return $-1$ to indicate an error. These functions will be explicitly +commented upon. When a function does return a CRYPT error code it can be translated into a string with + +\begin{verbatim} +const char *error_to_string(int errno); +\end{verbatim} + +An example of handling an error is: +\begin{verbatim} +void somefunc(void) +{ + int errno; + + /* call a cryptographic function */ + if ((errno = some_crypto_function(...)) != CRYPT_OK) { + printf("A crypto error occured, %s\n", error_to_string(errno)); + /* perform error handling */ + } + /* continue on if no error occured */ +} +\end{verbatim} + +There is no initialization routine for the library and for the most part the code is thread safe. The only thread +related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads. Normally +that is not an issue. + +To include the prototypes for ``LibTomCrypt.a'' into your own program simply include ``mycrypt.h'' like so: +\begin{verbatim} +#include <mycrypt.h> +int main(void) { + return 0; +} +\end{verbatim} + +The header file ``mycrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and ``mpi.h'' +(the bignum library routines). + +\section{Macros} + +There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing +32/64-bit words in little/big endian format. The macros are: + +\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} +\index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|} + \hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\ + \hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\ + \hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\ + \hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\ + \hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\ + \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\ + \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\ + \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\ + \hline BSWAP(x) & {\bf unsigned long} x & Swaps the byte order of x. \\ + \hline +\end{tabular} +\end{center} +\end{small} + +There are 32-bit cyclic rotations as well: +\index{ROL} \index{ROR} +\begin{center} +\begin{tabular}{|c|c|c|} + \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y$ \\ + \hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y$ \\ + \hline +\end{tabular} +\end{center} + +\section{Functions with Variable Length Output} +Certain functions such as (for example) ``rsa\_export()'' give an output that is variable length. To prevent buffer overflows you +must pass it the length of the buffer\footnote{Extensive error checking is not in place but it will be in future releases so it is a good idea to follow through with these guidelines.} where +the output will be stored. For example: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) { + rsa_key key; + unsigned char buffer[1024]; + unsigned long x; + int errno; + + /* ... Make up the RSA key somehow */ + + /* lets export the key, set x to the size of the output buffer */ + x = sizeof(buffer); + if ((errno = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) { + printf("Export error: %s\n", error_to_string(errno)); + return -1; + } + + /* if rsa_export() was successful then x will have the size of the output */ + printf("RSA exported key takes %d bytes\n", x); + + /* ... do something with the buffer */ + + return 0; +} +\end{verbatim} +\end{small} +In the above example if the size of the RSA public key was more than 1024 bytes this function would not store anything in +either ``buffer'' or ``x'' and simply return an error code. If the function suceeds it stores the length of the output +back into ``x'' so that the calling application will know how many bytes used. + +\section{Functions that need a PRNG} +Certain functions such as ``rsa\_make\_key()'' require a PRNG. These functions do not setup the PRNG themselves so it is +the responsibility of the calling function to initialize the PRNG before calling them. + +\section{Functions that use Arrays of Octets} +Most functions require inputs that are arrays of the data type ``unsigned char''. Whether it is a symmetric key, IV +for a chaining mode or public key packet it is assumed that regardless of the actual size of ``unsigned char'' only the +lower eight bits contain data. For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine +you must pass it in (a pointer to) an array of 32 ``unsigned char'' variables. Certain routines +(such as SAFER+) take special care to work properly on platforms where an ``unsigned char'' is not eight bits. + +For the purposes of this library the term ``byte'' will refer to an octet or eight bit word. Typically an array of +type ``byte'' will be synonymous with an array of type ``unsigned char''. + +\chapter{Symmetric Block Ciphers} +\section{Core Functions} + +Libtomcrypt provides several block ciphers all in a plain vanilla ECB block mode. Its important to first note that you +should never use the ECB modes directly to encrypt data. Instead you should use the ECB functions to make a chaining mode +or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of +the API to grow in a modular fashion. + +All ciphers store their scheduled keys in a single data type called ``symmetric\_key''. This allows all ciphers to +have the same prototype and store their keys as naturally as possible. All ciphers provide five visible functions which +are (given that XXX is the name of the cipher): +\index{Cipher Setup} +\begin{verbatim} +int XXX_setup(const unsigned char *key, int keylen, int rounds, + symmetric_key *skey); +\end{verbatim} + +The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes). +The number of rounds can be set to zero to use the default, which is generally a good idea. + +If the function returns successfully the variable ``skey'' will have a scheduled key stored in it. Its important to note +that you should only used this scheduled key with the intended cipher. For example, if you call +``blowfish\_setup()'' do not pass the scheduled key onto ``rc5\_ecb\_encrypt()''. All setup functions do not allocate +memory off the heap so when you are done with a key you can simply discard it (e.g. they can be on the stack). + +To encrypt or decrypt a block in ECB mode there are these two functions: +\index{Cipher Encrypt} \index{Cipher Decrypt} +\begin{verbatim} +void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct, + symmetric_key *skey); + +void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt, + symmetric_key *skey); +\end{verbatim} +These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on +which cipher you are using.} and store the result where you want it. It is possible that the input and output buffer are +the same buffer. For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and ``ct'' is the output. +For the decryption function its the opposite. To test a particular cipher against test vectors\footnote{As published in their design papers.} call: \index{Cipher Testing} +\begin{verbatim} +int XXX_test(void); +\end{verbatim} +This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is +based upon. Finally for each cipher there is a function which will help find a desired key size: +\begin{verbatim} +int XXX_keysize(int *keysize); +\end{verbatim} +Essentially it will round the input keysize in ``keysize'' down to the next appropriate key size. This function +return {\bf CRYPT\_OK} if the key size specified is acceptable. For example: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + int keysize, errno; + + /* now given a 20 byte key what keysize does Twofish want to use? */ + keysize = 20; + if ((errno = twofish_keysize(&keysize)) != CRYPT_OK) { + printf("Error getting key size: %s\n", error_to_string(errno)); + return -1; + } + printf("Twofish suggested a key size of %d\n", keysize); + return 0; +} +\end{verbatim} +\end{small} +This should indicate a keysize of sixteen bytes is suggested. An example snippet that encodes a block with +Blowfish in ECB mode is below. + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + unsigned char pt[8], ct[8], key[8]; + symmetric_key skey; + int errno; + + /* ... key is loaded appropriately in ``key'' ... */ + /* ... load a block of plaintext in ``pt'' ... */ + + /* schedule the key */ + if ((errno = blowfish_setup(key, 8, 0, &skey)) != CRYPT_OK) { + printf("Setup error: %s\n", error_to_string(errno)); + return -1; + } + + /* encrypt the block */ + blowfish_ecb_encrypt(pt, ct, &skey); + + /* decrypt the block */ + blowfish_ecb_decrypt(ct, pt, &skey); + + return 0; +} +\end{verbatim} +\end{small} + +\section{Key Sizes and Number of Rounds} +\index{Symmetric Keys} +As a general rule of thumb do not use symmetric keys under 80 bits if you can. Only a few of the ciphers support smaller +keys (mainly for test vectors anyways). Ideally your application should be making at least 256 bit keys. This is not +because you're supposed to be paranoid. Its because if your PRNG has a bias of any sort the more bits the better. For +example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the +total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$. So if $\gamma$ +were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have +only 53 bits of entropy. + +The number of rounds of most ciphers is not an option you can change. Only RC5 allows you to change the number of +rounds. By passing zero as the number of rounds all ciphers will use their default number of rounds. Generally the +ciphers are configured such that the default number of rounds provide adequate security for the given block size. + +\section{The Cipher Descriptors} +\index{Cipher Descriptor} +To facilitate automatic routines an array of cipher descriptors is provided in the array ``cipher\_descriptor''. An element +of this array has the following format: + +\begin{verbatim} +struct _cipher_descriptor { + char *name; + unsigned long min_key_length, max_key_length, + block_length, default_rounds; + int (*setup) (const unsigned char *key, int keylength, + int num_rounds, symmetric_key *skey); + void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, + symmetric_key *key); + void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, + symmetric_key *key); + int (*test) (void); + int (*keysize) (int *desired_keysize); +}; +\end{verbatim} + +Where ``name'' is the lower case ASCII version of the name. The fields ``min\_key\_length'', ``max\_key\_length'' and +``block\_length'' are all the number of bytes not bits. As a good rule of thumb it is assumed that the cipher supports +the min and max key lengths but not always everything in between. The ``default\_rounds'' field is the default number +of rounds that will be used. + +The remaining fields are all pointers to the core functions for each cipher. The end of the cipher\_descriptor array is +marked when ``name'' equals {\bf NULL}. + +As of this release the current cipher\_descriptors elements are + +\begin{small} +\begin{center} +\begin{tabular}{|c|c|c|c|c|c|} + \hline Name & Descriptor Name & Block Size & Key Range & Rounds \\ + \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\ + \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\ + \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\ + \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\ + \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\ + \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\ + \hline Safer K64 & safer\_k64\_desc & 8 & 8 & 6 $\ldots$ 13 \\ + \hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 $\ldots$ 13 \\ + \hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 $\ldots$ 13 \\ + \hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 $\ldots$ 13 \\ + \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ + \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\ + \hline DES & des\_desc & 8 & 7 & 16 \\ + \hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\ + \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\ + \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\ + \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\ + \hline +\end{tabular} +\end{center} +\end{small} + +\subsection{Notes} +For the 64-bit SAFER famliy of ciphers (e.g K64, SK64, K128, SK128) the ecb\_encrypt() and ecb\_decrypt() +functions are the same. So if you want to use those functions directly just call safer\_ecb\_encrypt() +or safer\_ecb\_decrypt() respectively. + +Note that for ``DES'' and ``3DES'' they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in +fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24 +byte string from the real 7/21 byte key. + +Note that ``Twofish'' has additional configuration options that take place at build time. These options are found in +the file ``mycrypt\_cfg.h''. The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish code +to not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes. This means that a scheduled +key will require less ram but the resulting cipher will be slower. The second option is ``TWOFISH\_TABLES'' which when +defined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplication +by the polynomials 5B and EF used in the MDS multiplication. As a result the code is faster and slightly larger. The +speed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of the +Twofish round function. + +\begin{small} +\begin{center} +\begin{tabular}{|l|l|l|} +\hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\ +\hline undefined & undefined & Very fast, 4.2KB of ram. \\ +\hline undefined & defined & As above, faster keysetup, larger code (1KB more). \\ +\hline defined & undefined & Very slow, 0.2KB of ram. \\ +\hline defined & defined & Somewhat faster, 0.2KB of ram, larger code. \\ +\hline +\end{tabular} +\end{center} +\end{small} + +To work with the cipher\_descriptor array there is a function: +\begin{verbatim} +int find_cipher(char *name) +\end{verbatim} +Which will search for a given name in the array. It returns negative one if the cipher is not found, otherwise it returns +the location in the array where the cipher was found. For example, to indirectly setup Blowfish you can also use: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + unsigned char key[8]; + symmetric_key skey; + int errno; + + /* you must register a cipher before you use it */ + if (register_cipher(&blowfish_desc)) == -1) { + printf("Unable to register Blowfish cipher."); + return -1; + } + + /* generic call to function (assuming the key in key[] was already setup) */ + if ((errno = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) { + printf("Error setting up Blowfish: %s\n", error_to_string(errno)); + return -1; + } + + /* ... use cipher ... */ +} +\end{verbatim} +\end{small} + +A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function. In order +to use a cipher with the descriptor table you must register it first using: +\begin{verbatim} +int register_cipher(const struct _cipher_descriptor *cipher); +\end{verbatim} +Which accepts a pointer to a descriptor and returns the index into the global descriptor table. If an error occurs such +as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}. If you try to add the same cipher more +than once it will just return the index of the first copy. To remove a cipher call: +\begin{verbatim} +int unregister_cipher(const struct _cipher_descriptor *cipher); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if it removes it otherwise it returns {\bf CRYPT\_ERROR}. Consider: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + int errno; + + /* register the cipher */ + if (register_cipher(&rijndael_desc) == -1) { + printf("Error registering Rijndael\n"); + return -1; + } + + /* use Rijndael */ + + /* remove it */ + if ((errno = unregister_cipher(&rijndael_desc)) != CRYPT_OK) { + printf("Error removing Rijndael: %s\n", error_to_string(errno)); + return -1; + } + + return 0; +} +\end{verbatim} +\end{small} +This snippet is a small program that registers only Rijndael only. + +\section{Symmetric Modes of Operations} +\subsection{Background} +A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block +size of the cipher. Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block +$P$ under the key $k$ as $E_k(P)$. In some modes there exists an initial vector denoted as $C_{-1}$. + +\subsubsection{ECB Mode} +ECB or Electronic Codebook Mode is the simplest method to use. It is given as: +\begin{equation} +C_i = E_k(P_i) +\end{equation} +This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more +than once. + +\subsubsection{CBC Mode} +CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers. +It is given as: +\begin{equation} +C_i = E_k(P_i \oplus C_{i - 1}) +\end{equation} +It is important that the initial vector be unique and preferably random for each message encrypted under the same key. + +\subsubsection{CTR Mode} +CTR or Counter Mode is a mode which only uses the encryption function of the cipher. Given a initial vector which is +treated as a large binary counter the CTR mode is given as: +\begin{eqnarray} +C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\ +C_i = P_i \oplus E_k(C_{-1}) +\end{eqnarray} +Where $W$ is the size of a block in bits (e.g. 64 for Blowfish). As long as the initial vector is random for each message +encrypted under the same key replay and swap attacks are infeasible. CTR mode may look simple but it is as secure +as the block cipher is under a chosen plaintext attack (provided the initial vector is unique). + +\subsubsection{CFB Mode} +CFB or Ciphertext Feedback Mode is a mode akin to CBC. It is given as: +\begin{eqnarray} +C_i = P_i \oplus C_{-1} \nonumber \\ +C_{-1} = E_k(C_i) +\end{eqnarray} +Note that in this library the output feedback width is equal to the size of the block cipher. That is this mode is used +to encrypt whole blocks at a time. However, the library will buffer data allowing the user to encrypt or decrypt partial +blocks without a delay. When this mode is first setup it will initially encrypt the initial vector as required. + +\subsubsection{OFB Mode} +OFB or Output Feedback Mode is a mode akin to CBC as well. It is given as: +\begin{eqnarray} +C_{-1} = E_k(C_{-1}) \nonumber \\ +C_i = P_i \oplus C_{-1} +\end{eqnarray} +Like the CFB mode the output width in CFB mode is the same as the width of the block cipher. OFB mode will also +buffer the output which will allow you to encrypt or decrypt partial blocks without delay. + +\subsection{Choice of Mode} +My personal preference is for the CTR mode since it has several key benefits: +\begin{enumerate} + \item No short cycles which is possible in the OFB and CFB modes. + \item Provably as secure as the block cipher being used under a chosen plaintext attack. + \item Technically does not require the decryption routine of the cipher. + \item Allows random access to the plaintext. + \item Allows the encryption of block sizes that are not equal to the size of the block cipher. +\end{enumerate} +The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size. They +accomplish this by buffering the data required to complete a block. This allows you to encrypt or decrypt any size +block of memory with either of the three modes. + +The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore they are less flexible than the +other modes. + +\subsection{Implementation} +\index{CBC Mode} \index{CTR Mode} +\index{OFB Mode} \index{CFB Mode} +The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode +you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to +use that mode. They have identical setup routines (except ECB mode for obvious reasons): +\begin{verbatim} +int XXX_start(int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, symmetric_XXX *XXX); + +int ecb_start(int cipher, const unsigned char *key, int keylen, + int num_rounds, symmetric_ECB *ecb); +\end{verbatim} + +In each case ``cipher'' is the index into the cipher\_descriptor array of the cipher you want to use. The ``IV'' value is +the initialization vector to be used with the cipher. You must fill the IV yourself and it is assumed they are the same +length as the block size\footnote{In otherwords the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} +of the cipher you choose. It is important that the IV be random for each unique message you want to encrypt. The +parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call. The final parameter +is a pointer to the structure you want to hold the information for the mode of operation. + +Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. To +actually encrypt or decrypt the following routines are provided: +\begin{verbatim} +int XXX_encrypt(const unsigned char *pt, unsigned char *ct, + symmetric_XXX *XXX); +int XXX_decrypt(const unsigned char *ct, unsigned char *pt, + symmetric_XXX *XXX); + +int YYY_encrypt(const unsigned char *pt, unsigned char *ct, + unsigned long len, symmetric_YYY *YYY); +int YYY_decrypt(const unsigned char *ct, unsigned char *pt, + unsigned long len, symmetric_YYY *YYY); +\end{verbatim} +Where ``XXX'' is one of (ecb, cbc) and ``YYY'' is one of (ctr, ofb, cfb). In the CTR, OFB and CFB cases ``len'' is the +size of the buffer (as number of chars) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not +chunk sensitive. That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F'' +and end up with the same ciphertext. However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts. All +five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions. + +To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used) +and use the decrypt routine on all of the blocks. When you are done working with either mode you should wipe the +memory (using ``zeromem()'') to help prevent the key from leaking. For example: +\newpage +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + unsigned char key[16], IV[16], buffer[512]; + symmetric_CTR ctr; + int x, errno; + + /* register twofish first */ + if (register_cipher(&twofish_desc) == -1) { + printf("Error registering cipher.\n"); + return -1; + } + + /* somehow fill out key and IV */ + + /* start up CTR mode */ + if ((errno = ctr_start(find_cipher("twofish"), IV, key, 16, 0, &ctr)) != CRYPT_OK) { + printf("ctr_start error: %s\n", error_to_string(errno)); + return -1; + } + + /* somehow fill buffer than encrypt it */ + if ((errno = ctr_encrypt(buffer, buffer, sizeof(buffer), &ctr)) != CRYPT_OK) { + printf("ctr_encrypt error: %s\n", error_to_string(errno)); + return -1; + } + + /* make use of ciphertext... */ + + /* clear up and return */ + zeromem(key, sizeof(key)); + zeromem(&ctr, sizeof(ctr)); + + return 0; +} +\end{verbatim} +\end{small} + +\section{Encrypt and Authenticate Modes} + +\subsection{EAX Mode} +LibTomCrypt provides support for a mode called EAX\footnote{See +M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the +way it was intended to be used. + +First a short description of what EAX mode is before I explain how to use it. EAX is a mode that requires a cipher, +CTR and OMAC support and provides encryption and authentication. It is initialized with a random ``nonce'' that can +be shared publicly as well as a ``header'' which can be fixed and public as well as a random secret symmetric key. + +The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages). It can +be added at anytime during an EAX stream and is part of the authentication tag. That is, changes in the meta-data can +be detected by an invalid output tag. + +The mode can then process plaintext producing ciphertext as well as compute a partial checksum. The actual checksum +called a ``tag'' is only emitted when the message is finished. In the interim though the user can process any arbitrary +sized message block to send to the recipient as ciphertext. This makes the EAX mode especially suited for streaming modes +of operation. + +The mode is initialized with the following function. +\begin{verbatim} +int eax_init(eax_state *eax, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); +\end{verbatim} + +Where ``eax'' is the EAX state. ``cipher'' is the index of the desired cipher in the descriptor table. +``key'' is the shared secret symmetric key of length ``keylen''. ``nonce'' is the random public string of +length ``noncelen''. ``header'' is the random (or fixed or \textbf{NULL}) header for the message of length +``headerlen''. + +When this function completes ``eax'' will be initialized such that you can now either have data decrypted or +encrypted in EAX mode. Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL}. It will still +initialize the EAX ``H'' value to the correct value. + +To encrypt or decrypt data in a streaming mode use the following. +\begin{verbatim} +int eax_encrypt(eax_state *eax, const unsigned char *pt, + unsigned char *ct, unsigned long length); + +int eax_decrypt(eax_state *eax, const unsigned char *ct, + unsigned char *pt, unsigned long length); +\end{verbatim} +The function ``eax\_encrypt'' will encrypt the bytes in ``pt'' of ``length'' bytes and store the ciphertext in +``ct''. Note that ``ct'' and ``pt'' may be the same region in memory. This function will also send the ciphertext +through the OMAC function. The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''. This also allows +``pt'' and ``ct'' to be the same region in memory. + +Note that both of these functions allow you to send the data in any granularity but the order is important. While +the eax\_init() function allows you to add initial header data to the stream you can also add header data during the +EAX stream with the following. + +Also note that you cannot both encrypt or decrypt with the same ``eax'' context. For bi-directional communication you +will need to initialize two EAX contexts (preferably with different headers and nonces). + +\begin{verbatim} +int eax_addheader(eax_state *eax, + const unsigned char *header, unsigned long length); +\end{verbatim} + +This will add the ``length'' bytes from ``header'' to the given ``eax'' stream. Once the message is finished the +``tag'' (checksum) may be computed with the following function. + +\begin{verbatim} +int eax_done(eax_state *eax, + unsigned char *tag, unsigned long *taglen); +\end{verbatim} +This will terminate the EAX state ``eax'' and store upto ``taglen'' bytes of the message tag in ``tag''. The function +then stores how many bytes of the tag were written out back into ``taglen''. + +The EAX mode code can be tested to ensure it matches the test vectors by calling the following function. +\begin{verbatim} +int eax_test(void); +\end{verbatim} +This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first. + +\subsection{OCB Mode} +LibTomCrypt provides support for a mode called OCB\footnote{See +P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.} +in a mode somewhat similar to as it was meant to be used. + +OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode +but is less flexible. Let's review how to initialize an OCB context. + +\begin{verbatim} +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce); +\end{verbatim} + +This will initialize the ``ocb'' context using cipher descriptor ``cipher''. It will use a ``key'' of length ``keylen'' +and the random ``nonce''. Note that ``nonce'' must be a random (public) string the same length as the block ciphers +block size (e.g. 16 for AES). + +This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream. +To encrypt or decrypt data use the following. + +\begin{verbatim} +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); +\end{verbatim} + +This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter). +They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size. Note that you cannot call +both functions given a single ``ocb'' state. For bi-directional communication you will have to initialize two ``ocb'' +states (with different nonces). Also ``pt'' and ``ct'' may point to the same location in memory. + +When you are finished encrypting the message you call the following function to compute the tag. + +\begin{verbatim} +int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); +\end{verbatim} + +This will terminate an encrypt stream ``ocb''. If you have trailing bytes of plaintext that will not complete a block +you can pass them here. This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''. It will also +store upto ``taglen'' bytes of the tag into ``tag''. + +Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen. Also note that if you have +an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. + +To terminate a decrypt stream and compared the tag you call the following. + +\begin{verbatim} +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *res); +\end{verbatim} + +Similarly to the previous function you can pass trailing message bytes into this function. This will compute the +tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided. By default +``res'' is set to zero. If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated +message). + +To make life simpler the following two functions are provided for memory bound OCB. + +\begin{verbatim} +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); +\end{verbatim} + +This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''. The length ``ptlen'' +can be any arbitrary length. + +\begin{verbatim} +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *res); +\end{verbatim} + +Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set +appropriately. + + + +\chapter{One-Way Cryptographic Hash Functions} +\section{Core Functions} + +Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''. +To initialize hash XXX (where XXX is the name) call: +\index{Hash Functions} +\begin{verbatim} +void XXX_init(hash_state *md); +\end{verbatim} + +This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the +message being hashed call: +\begin{verbatim} +int XXX_process(hash_state *md, const unsigned char *in, unsigned long len); +\end{verbatim} + +Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which +are buffered. The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest +(hash output) will be the same. For example, this means that: +\begin{verbatim} +md5_process(&md, "hello ", 6); +md5_process(&md, "world", 5); +\end{verbatim} +Will produce the same message digest as the single call: +\index{Message Digest} +\begin{verbatim} +md5_process(&md, "hello world", 11); +\end{verbatim} + +To finally get the message digest (the hash) call: +\begin{verbatim} +int XXX_done(hash_state *md, + unsigned char *out); +\end{verbatim} + +This function will finish up the hash and store the result in the ``out'' array. You must ensure that ``out'' is long +enough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functions +will wipe the ``md'' variable before returning automatically. + +To test a hash function call: +\begin{verbatim} +int XXX_test(void); +\end{verbatim} + +This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code. An +example snippet that hashes a message with md5 is given below. +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + hash_state md; + unsigned char *in = "hello world", out[16]; + + /* setup the hash */ + md5_init(&md); + + /* add the message */ + md5_process(&md, in, strlen(in)); + + /* get the hash in out[0..15] */ + md5_done(&md, out); + + return 0; +} +\end{verbatim} +\end{small} + +\section{Hash Descriptors} +\index{Hash Descriptors} +Like the set of ciphers the set of hashes have descriptors too. They are stored in an array called ``hash\_descriptor'' and +are defined by: +\begin{verbatim} +struct _hash_descriptor { + char *name; + unsigned long hashsize; /* digest output size in bytes */ + unsigned long blocksize; /* the block size the hash uses */ + void (*init) (hash_state *); + int (*process)(hash_state *, const unsigned char *, unsigned long); + int (*done) (hash_state *, unsigned char *); + int (*test) (void); +}; +\end{verbatim} + +Similarly ``name'' is the name of the hash function in ASCII (all lowercase). ``hashsize'' is the size of the digest output +in bytes. The remaining fields are pointers to the functions that do the respective tasks. There is a function to +search the array as well called ``int find\_hash(char *name)''. It returns -1 if the hash is not found, otherwise the +position in the descriptor table of the hash. + +You can use the table to indirectly call a hash function that is chosen at runtime. For example: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + unsigned char buffer[100], hash[MAXBLOCKSIZE]; + int idx, x; + hash_state md; + + /* register hashes .... */ + if (register_hash(&md5_desc) == -1) { + printf("Error registering MD5.\n"); + return -1; + } + + /* register other hashes ... */ + + /* prompt for name and strip newline */ + printf("Enter hash name: \n"); + fgets(buffer, sizeof(buffer), stdin); + buffer[strlen(buffer) - 1] = 0; + + /* get hash index */ + idx = find_hash(buffer); + if (idx == -1) { + printf("Invalid hash name!\n"); + return -1; + } + + /* hash input until blank line */ + hash_descriptor[idx].init(&md); + while (fgets(buffer, sizeof(buffer), stdin) != NULL) + hash_descriptor[idx].process(&md, buffer, strlen(buffer)); + hash_descriptor[idx].done(&md, hash); + + /* dump to screen */ + for (x = 0; x < hash_descriptor[idx].hashsize; x++) + printf("%02x ", hash[x]); + printf("\n"); + return 0; +} +\end{verbatim} +\end{small} + +Note the usage of ``MAXBLOCKSIZE''. In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE in +length. This provides a simple size you can set your automatic arrays to that will not get overrun. + +There are three helper functions as well: +\index{hash\_memory()} \index{hash\_file()} +\begin{verbatim} +int hash_memory(int hash, const unsigned char *data, + unsigned long len, unsigned char *dst, + unsigned long *outlen); + +int hash_file(int hash, const char *fname, + unsigned char *dst, + unsigned long *outlen); + +int hash_filehandle(int hash, FILE *in, + unsigned char *dst, unsigned long *outlen); +\end{verbatim} + +The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}). +The ``*outlen'' variable is used to keep track of the output size. You +must set it to the size of your output buffer before calling the functions. When they complete succesfully they store +the length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle'' +function assumes that ``in'' is an file handle opened in binary mode. It will hash to the end of file and not reset +the file position when finished. + +To perform the above hash with md5 the following code could be used: +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + int idx, errno; + unsigned long len; + unsigned char out[MAXBLOCKSIZE]; + + /* register the hash */ + if (register_hash(&md5_desc) == -1) { + printf("Error registering MD5.\n"); + return -1; + } + + /* get the index of the hash */ + idx = find_hash("md5"); + + /* call the hash */ + len = sizeof(out); + if ((errno = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) { + printf("Error hashing data: %s\n", error_to_string(errno)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +The following hashes are provided as of this release: +\begin{center} +\begin{tabular}{|c|c|c|} + \hline Name & Descriptor Name & Size of Message Digest (bytes) \\ + \hline WHIRLPOOL & whirlpool\_desc & 64 \\ + \hline SHA-512 & sha512\_desc & 64 \\ + \hline SHA-384 & sha384\_desc & 48 \\ + \hline SHA-256 & sha256\_desc & 32 \\ + \hline SHA-224 & sha224\_desc & 28 \\ + \hline TIGER-192 & tiger\_desc & 24 \\ + \hline SHA-1 & sha1\_desc & 20 \\ + \hline RIPEMD-160 & rmd160\_desc & 20 \\ + \hline RIPEMD-128 & rmd128\_desc & 16 \\ + \hline MD5 & md5\_desc & 16 \\ + \hline MD4 & md4\_desc & 16 \\ + \hline MD2 & md2\_desc & 16 \\ + \hline +\end{tabular} +\end{center} + +Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functions +work exactly like those of the cipher registration code. The functions are: +\begin{verbatim} +int register_hash(const struct _hash_descriptor *hash); +int unregister_hash(const struct _hash_descriptor *hash); +\end{verbatim} + +\subsection{Notice} +It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes. +These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators +(e.g. Yarrow). + +The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure +for all purposes you would normally use a hash for. + +\chapter{Message Authentication Codes} +\section{HMAC Protocol} +Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short. An HMAC +of a message is a keyed authenication code that only the owner of a private symmetric key will be able to verify. The purpose is +to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct. Any impostor or +eavesdropper will not be able to verify the authenticity of a message. + +The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key +and its length. The key is much like a key you would pass to a cipher. That is, it is simply an array of octets stored in +chars. The initialization routine is: +\begin{verbatim} +int hmac_init(hmac_state *hmac, int hash, + const unsigned char *key, unsigned long keylen); +\end{verbatim} +The ``hmac'' parameter is the state for the HMAC code. ``hash'' is the index into the descriptor table of the hash you want +to use to authenticate the message. ``key'' is the pointer to the array of chars that make up the key. ``keylen'' is the +length (in octets) of the key you want to use to authenticate the message. To send octets of a message through the HMAC system you must use the following function: +\begin{verbatim} +int hmac_process(hmac_state *hmac, const unsigned char *buf, + unsigned long len); +\end{verbatim} +``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process. ``len'' is the +number of octets to process. Like the hash process routines you can send the data in arbitrarly sized chunks. When you +are finished with the HMAC process you must call the following function to get the HMAC code: +\begin{verbatim} +int hmac_done(hmac_state *hmac, unsigned char *hashOut, + unsigned long *outlen); +\end{verbatim} +``hmac'' is the HMAC state you are working with. ``hashOut'' is the array of octets where the HMAC code should be stored. You must +set ``outlen'' to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code +produced (depending on which hash was picked). If ``outlen'' is less than the size of the message digest (and ultimately +the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first ``outlen'' bytes). + +There are two utility functions provided to make using HMACs easier todo. They accept the key and information about the +message (file pointer, address in memory) and produce the HMAC result in one shot. These are useful if you want to avoid +calling the three step process yourself. + +\begin{verbatim} +int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, + const unsigned char *data, unsigned long len, + unsigned char *dst, unsigned long *dstlen); +\end{verbatim} +This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor +table must be provided in ``hash''. It uses the key from ``key'' with a key length of ``keylen''. +The result is stored in the array of octets ``dst'' and the length in ``dstlen''. The value of ``dstlen'' must be set +to the size of the destination buffer before calling this function. Similarly for files there is the following function: +\begin{verbatim} +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +\end{verbatim} +``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process. +``key'' is the array of octets to use as the key of length ``keylen''. ``dst'' is the array of octets where the +result should be stored. + +To test if the HMAC code is working there is the following function: +\begin{verbatim} +int hmac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the +HMAC system is given below. + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + int idx, errno; + hmac_state hmac; + unsigned char key[16], dst[MAXBLOCKSIZE]; + unsigned long dstlen; + + /* register SHA-1 */ + if (register_hash(&sha1_desc) == -1) { + printf("Error registering SHA1\n"); + return -1; + } + + /* get index of SHA1 in hash descriptor table */ + idx = find_hash("sha1"); + + /* we would make up our symmetric key in "key[]" here */ + + /* start the HMAC */ + if ((errno = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) { + printf("Error setting up hmac: %s\n", error_to_string(errno)); + return -1; + } + + /* process a few octets */ + if((errno = hmac_process(&hmac, "hello", 5) != CRYPT_OK) { + printf("Error processing hmac: %s\n", error_to_string(errno)); + return -1; + } + + /* get result (presumably to use it somehow...) */ + dstlen = sizeof(dst); + if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { + printf("Error finishing hmac: %s\n", error_to_string(errno)); + return -1; + } + printf("The hmac is %lu bytes long\n", dstlen); + + /* return */ + return 0; +} +\end{verbatim} +\end{small} + +\section{OMAC Support} +OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an +algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. From an API +standpoint the OMAC routines work much like the HMAC routines do. Instead in this case a cipher is used instead of a hash. + +To start an OMAC state you call + +\begin{verbatim} +int omac_init(omac_state *omac, int cipher, + const unsigned char *key, unsigned long keylen); +\end{verbatim} +The ``omac'' variable is the state for the OMAC algorithm. ``cipher'' is the index into the cipher\_descriptor table +of the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you +wish to use. ``key'' and ``keylen'' are the keys used to authenticate the data. + +To send data through the algorithm call +\begin{verbatim} +int omac_process(omac_state *state, + const unsigned char *buf, unsigned long len); +\end{verbatim} +This will send ``len'' bytes from ``buf'' through the active OMAC state ``state''. Returns \textbf{CRYPT\_OK} if the +function succeeds. The function is not sensitive to the granularity of the data. For example, + +\begin{verbatim} +omac_process(&mystate, "hello", 5); +omac_process(&mystate, " world", 6); +\end{verbatim} + +Would produce the same result as, + +\begin{verbatim} +omac_process(&mystate, "hello world", 11); +\end{verbatim} + +When you are done processing the message you can call the following to compute the message tag. + +\begin{verbatim} +int omac_done(omac_state *state, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +Which will terminate the OMAC and output the \textit{tag} (MAC) to ``out''. Note that unlike the HMAC and other code +``outlen'' can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC +specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher than +the output MAC code will only be five bytes long. If ``outlen'' is larger than the default size it is set to the default +size to show how many bytes were actually used. + +Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the +following function. + +\begin{verbatim} +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the OMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher +specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same +rules as omac\_done. + +To OMAC a file use +\begin{verbatim} +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will OMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes +and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with +the same rules as omac\_done. + +To test if the OMAC code is working there is the following function: +\begin{verbatim} +int omac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the +OMAC system is given below. + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + int idx, err; + omac_state omac; + unsigned char key[16], dst[MAXBLOCKSIZE]; + unsigned long dstlen; + + /* register Rijndael */ + if (register_cipher(&rijndael_desc) == -1) { + printf("Error registering Rijndael\n"); + return -1; + } + + /* get index of Rijndael in cipher descriptor table */ + idx = find_cipher("rijndael"); + + /* we would make up our symmetric key in "key[]" here */ + + /* start the OMAC */ + if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) { + printf("Error setting up omac: %s\n", error_to_string(err)); + return -1; + } + + /* process a few octets */ + if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) { + printf("Error processing omac: %s\n", error_to_string(err)); + return -1; + } + + /* get result (presumably to use it somehow...) */ + dstlen = sizeof(dst); + if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) { + printf("Error finishing omac: %s\n", error_to_string(err)); + return -1; + } + printf("The omac is %lu bytes long\n", dstlen); + + /* return */ + return 0; +} +\end{verbatim} +\end{small} + +\section{PMAC Support} +The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''} +protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the same +API as the provided OMAC code. + +A PMAC state is initialized with the following. + +\begin{verbatim} +int pmac_init(pmac_state *pmac, int cipher, + const unsigned char *key, unsigned long keylen); +\end{verbatim} +Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes. The chosen cipher +must have a 64 or 128 bit block size (e.x. AES). + +To MAC data simply send it through the process function. + +\begin{verbatim} +int pmac_process(pmac_state *state, + const unsigned char *buf, unsigned long len); +\end{verbatim} +This will process ``len'' bytes of ``buf'' in the given ``state''. The function is not sensitive to the granularity of the +data. For example, + +\begin{verbatim} +pmac_process(&mystate, "hello", 5); +pmac_process(&mystate, " world", 6); +\end{verbatim} + +Would produce the same result as, + +\begin{verbatim} +pmac_process(&mystate, "hello world", 11); +\end{verbatim} + +When a complete message has been processed the following function can be called to compute the message tag. + +\begin{verbatim} +int pmac_done(pmac_state *state, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''. Note that if ``outlen'' is larger +than the size of the tag it is set to the amount of bytes stored in ``out''. + +Similar to the PMAC code the file and memory functions are also provided. To PMAC a buffer of memory in one shot use the +following function. + +\begin{verbatim} +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This will compute the PMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher +specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same +rules as omac\_done. + +To PMAC a file use +\begin{verbatim} +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Which will PMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes +and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with +the same rules as omac\_done. + +To test if the PMAC code is working there is the following function: +\begin{verbatim} +int pmac_test(void); +\end{verbatim} +Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. + + +\chapter{Pseudo-Random Number Generators} +\section{Core Functions} + +The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is +used to expand a shorter bit string into a longer bit string. PRNGs are used wherever random data is required such as Public Key (PK) +key generation. There is a universal structure called ``prng\_state''. To initialize a PRNG call: +\begin{verbatim} +int XXX_start(prng_state *prng); +\end{verbatim} + +This will setup the PRNG for future use and not seed it. In order +for the PRNG to be cryptographically useful you must give it entropy. Ideally you'd have some OS level source to tap +like in UNIX (see section 5.3). To add entropy to the PRNG call: +\begin{verbatim} +int XXX_add_entropy(const unsigned char *in, unsigned long len, + prng_state *prng); +\end{verbatim} + +Which returns {\bf CRYPTO\_OK} if the entropy was accepted. Once you think you have enough entropy you call another +function to put the entropy into action. +\begin{verbatim} +int XXX_ready(prng_state *prng); +\end{verbatim} + +Which returns {\bf CRYPTO\_OK} if it is ready. Finally to actually read bytes call: +\begin{verbatim} +unsigned long XXX_read(unsigned char *out, unsigned long len, + prng_state *prng); +\end{verbatim} + +Which returns the number of bytes read from the PRNG. + +\subsection{Remarks} + +It is possible to be adding entropy and reading from a PRNG at the same time. For example, if you first seed the PRNG +and call ready() you can now read from it. You can also keep adding new entropy to it. The new entropy will not be used +in the PRNG until ready() is called again. This allows the PRNG to be used and re-seeded at the same time. No real error +checking is guaranteed to see if the entropy is sufficient or if the PRNG is even in a ready state before reading. + +\subsection{Example} + +Below is a simple snippet to read 10 bytes from yarrow. Its important to note that this snippet is {\bf NOT} secure since +the entropy added is not random. + +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + prng_state prng; + unsigned char buf[10]; + int err; + + /* start it */ + if ((err = yarrow_start(&prng)) != CRYPT_OK) { + printf("Start error: %s\n", error_to_string(err)); + } + /* add entropy */ + if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) { + printf("Add_entropy error: %s\n", error_to_string(err)); + } + /* ready and read */ + if ((err = yarrow_ready(&prng)) != CRYPT_OK) { + printf("Ready error: %s\n", error_to_string(err)); + } + printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng)); + return 0; +} +\end{verbatim} + +\section{PRNG Descriptors} +\index{PRNG Descriptor} +PRNGs have descriptors too (surprised?). Stored in the structure ``prng\_descriptor''. The format of an element is: +\begin{verbatim} +struct _prng_descriptor { + char *name; + int (*start) (prng_state *); + int (*add_entropy)(const unsigned char *, unsigned long, prng_state *); + int (*ready) (prng_state *); + unsigned long (*read)(unsigned char *, unsigned long len, prng_state *); +}; +\end{verbatim} + +There is a ``int find\_prng(char *name)'' function as well. Returns -1 if the PRNG is not found, otherwise it returns +the position in the prng\_descriptor array. + +Just like the ciphers and hashes you must register your prng before you can use it. The two functions provided work +exactly as those for the cipher registry functions. They are: +\begin{verbatim} +int register_prng(const struct _prng_descriptor *prng); +int unregister_prng(const struct _prng_descriptor *prng); +\end{verbatim} + +\subsubsection{PRNGs Provided} +Currently Yarrow (yarrow\_desc), RC4 (rc4\_desc) and the secure RNG (sprng\_desc) are provided as PRNGs within the +library. + +RC4 is provided with a PRNG interface because it is a stream cipher and not well suited for the symmetric block cipher +interface. You provide the key for RC4 via the rc4\_add\_entropy() function. By calling rc4\_ready() the key will be used +to setup the RC4 state for encryption or decryption. The rc4\_read() function has been modified from RC4 since it will +XOR the output of the RC4 keystream generator against the input buffer you provide. The following snippet will demonstrate +how to encrypt a buffer with RC4: + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + prng_state prng; + unsigned char buf[32]; + int err; + + if ((err = rc4_start(&prng)) != CRYPT_OK) { + printf("RC4 init error: %s\n", error_to_string(err)); + exit(-1); + } + + /* use ``key'' as the key */ + if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) { + printf("RC4 add entropy error: %s\n", error_to_string(err)); + exit(-1); + } + + /* setup RC4 for use */ + if ((err = rc4_ready(&prng)) != CRYPT_OK) { + printf("RC4 ready error: %s\n", error_to_string(err)); + exit(-1); + } + + /* encrypt buffer */ + strcpy(buf,"hello world"); + if (rc4_read(buf, 11, &prng) != 11) { + printf("RC4 read error\n"); + exit(-1); + } + return 0; +} +\end{verbatim} +\end{small} +To decrypt you have to do the exact same steps. + +\section{The Secure RNG} +\index{Secure RNG} +An RNG is related to a PRNG except that it doesn't expand a smaller seed to get the data. They generate their random bits +by performing some computation on fresh input bits. Possibly the hardest thing to get correctly in a cryptosystem is the +PRNG. Computers are deterministic beasts that try hard not to stray from pre-determined paths. That makes gathering +entropy needed to seed the PRNG a hard task. + +There is one small function that may help on certain platforms: +\index{rng\_get\_bytes()} +\begin{verbatim} +unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, + void (*callback)(void)); +\end{verbatim} + +Which will try one of three methods of getting random data. The first is to open the popular ``/dev/random'' device which +on most *NIX platforms provides cryptographic random bits\footnote{This device is available in Windows through the Cygwin compiler suite. It emulates ``/dev/random'' via the Microsoft CSP.}. +The second method is to try the Microsoft Cryptographic Service Provider and read the RNG. The third method is an ANSI C +clock drift method that is also somewhat popular but gives bits of lower entropy. The ``callback'' parameter is a pointer to a function that returns void. Its used when the slower ANSI C RNG must be +used so the calling application can still work. This is useful since the ANSI C RNG has a throughput of three +bytes a second. The callback pointer may be set to {\bf NULL} to avoid using it if you don't want to. The function +returns the number of bytes actually read from any RNG source. There is a function to help setup a PRNG as well: +\index{rng\_make\_prng()} +\begin{verbatim} +int rng_make_prng(int bits, int wprng, prng_state *prng, + void (*callback)(void)); +\end{verbatim} +This will try to setup the prng with a state of at least ``bits'' of entropy. The ``callback'' parameter works much like +the callback in ``rng\_get\_bytes()''. It is highly recommended that you use this function to setup your PRNGs unless you have a +platform where the RNG doesn't work well. Example usage of this function is given below. + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + ecc_key mykey; + prng_state prng; + int err; + + /* register yarrow */ + if (register_prng(&yarrow_desc) == -1) { + printf("Error registering Yarrow\n"); + return -1; + } + + /* setup the PRNG */ + if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { + printf("Error setting up PRNG, %s\n", error_to_string(err)); + return -1; + } + + /* make a 192-bit ECC key */ + if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) { + printf("Error making key: %s\n", error_to_string(err)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +\subsection{The Secure PRNG Interface} +It is possible to access the secure RNG through the PRNG interface and in turn use it within dependent functions such +as the PK API. This simplifies the cryptosystem on platforms where the secure RNG is fast. The secure PRNG never +requires to be started, that is you need not call the start, add\_entropy or ready functions. For example, consider +the previous example using this PRNG. + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + ecc_key mykey; + int err; + + /* register SPRNG */ + if (register_prng(&sprng_desc) == -1) { + printf("Error registering SPRNG\n"); + return -1; + } + + /* make a 192-bit ECC key */ + if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) { + printf("Error making key: %s\n", error_to_string(err)); + return -1; + } + return 0; +} +\end{verbatim} +\end{small} + +\chapter{RSA Public Key Cryptography} +\textbf{Note: } \textit{This chapter on PKCS \#1 RSA will replace the older chapter on RSA (The current chapter nine) in subsequent +releases of the library. Users are encouraged to stop using the LibTomCrypt style padding functions.} + +\section{PKCS \#1 Encryption} + +PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of +the library is concerned we are only dealing with th OAEP padding of the message. + +\subsection{OAEP Encoding} + +\begin{alltt} +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned char *out, unsigned long *outlen); +\end{alltt} + +This accepts ``msg'' as input of length ``msglen'' which will be OAEP padded. The ``lparam'' variable is an additional system specific +tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then +``lparam'' can be set to \textbf{NULL}. + +OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter +``modulus\_bitlen''. ``hash\_idx'' is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be +used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum + sized input message. ``prng\_idx'' and ``prng'' are the random number generator arguments required to randomize the padding process. +The padded message is stored in ``out'' along with the length in ``outlen''. + +If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for ``msg'' is +$m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. + +Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to +rsa\_exptmod() to encrypt it. + +\subsection{OAEP Decoding} + +\begin{alltt} +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen); +\end{alltt} + +This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. ``msg'' is the +output of pkcs\_1\_oaep\_encode() of length ``msglen''. ``lparam'' is the same system variable passed to the OAEP encoder. If it does not +match what was used during encoding this function will not decode the packet. ``modulus\_bitlen'' is the size of the RSA modulus in bits +and must match what was used during encoding. Similarly the ``hash\_idx'' index into the hash descriptor table must match what was used +during encoding. + +If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen''. + +\section{PKCS \#1 Digital Signatures} + +\subsection{PSS Encoding} +PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. + +\begin{alltt} +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); +\end{alltt} + +This function assumes the message to be PSS encoded has previously been hashed. The input hash ``msghash'' is of length +``msghashlen''. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. +``hash\_idx'' is the index into the hash descriptor table of the hash to use. ``prng\_idx'' and ``prng'' are the random +number generator information required for the salt. + +Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus. It limits the size of the salt. If $m$ is the length +of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. + +This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). + +\subsection{PSS Decoding} + +To decode a PSS encoded signature block you have to use the following. + +\begin{alltt} +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); +\end{alltt} +This will decode the PSS encoded message in ``sig'' of length ``siglen'' and compare it to values in ``msghash'' of length +``msghashlen''. If the block is a valid PSS block and the decoded hash equals the hash supplied ``res'' is set to non--zero. Otherwise, +it is set to zero. The rest of the parameters are as in the PSS encode call. + +It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work. + +\chapter{Password Based Cryptography} +\section{PKCS \#5} +In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 +is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented +for completeness. Algorithm Two is a bit more modern and more flexible to work with. + +\section{Algorithm One} +Algorithm One accepts as input a password, an 8--byte salt and an iteration counter. The iteration counter is meant to act as delay for +people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash +algorithm and produces an output no longer than the output of the hash. + +\begin{alltt} +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +\end{alltt} +Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. +The ``salt'' is a fixed size 8--byte array which should be random for each user and session. The ``iteration\_count'' is the delay desired +on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. + +The output of length upto ``outlen'' is stored in ``out''. If ``outlen'' is initially larger than the size of the hash functions output +it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in ``out''. + +\section{Algorithm Two} + +Algorithm Two is the recommended algorithm for this task. It allows variable length salts and can produce outputs larger than the +hash functions output. As such it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required +from a single password and invokation of this algorithm. + +\begin{alltt} +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +\end{alltt} +Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. +The ``salt'' is an array of size ``salt\_len''. It should be random for each user and session. The ``iteration\_count'' is the delay desired +on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. The output of length upto +``outlen'' is stored in ``out''. + +\begin{alltt} +/* demo to show how to make session state material from a password */ +#include <mycrypt.h> +int main(void) +\{ + unsigned char password[100], salt[100], + cipher_key[16], cipher_iv[16], + mac_key[16], outbuf[48]; + int err, hash_idx; + unsigned long outlen, password_len, salt_len; + + /* register hash and get it's idx .... */ + + /* get users password and make up a salt ... */ + + /* create the material (100 iterations in algorithm) */ + outlen = sizeof(outbuf); + if ((err = pkcs_5_alg2(password, password_len, salt, salt_len, + 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) \{ + /* error handle */ + \} + + /* now extract it */ + memcpy(cipher_key, outbuf, 16); + memcpy(cipher_iv, outbuf+16, 16); + memcpy(mac_key, outbuf+32, 16); + + /* use material (recall to store the salt in the output) */ +\} +\end{alltt} + +\chapter{RSA Routines} + +\textbf{Note: } \textit{This chapter has been marked for removal. In particular any function that uses the LibTomCrypt style +RSA padding (e.g. rsa\_pad() rsa\_signpad()) will be removed in the v0.96 release cycle. The functions like rsa\_make\_key() and +rsa\_exptmod() will stay but may be slightly modified. } + +\section{Background} + +RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown +factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are +not strictly equivalent. + +The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or ``Euler totient'' of the +multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to +$\mbox{lcm}(p - 1, q - 1)$. The public key consists of the composite $N$ and some integer $e$ such that +$\mbox{gcd}(e, \phi(N)) = 1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ +often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$. + +A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that +$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$. Since finding the inverse exponent $d$ +given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute +$C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$. Similarly the owner of the private key +can sign a message by ``decrypting'' it. Others can verify it by ``encrypting'' it. + +Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other. +Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad +the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial. +The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well +designed for fast exponentiation (requires 16 squarings and one multiplication). + +It is important to pad the input to RSA since it has particular mathematical structure. For instance +$M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature. Suppose $M_3 = M_1M_2$ is a message you want +to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result +together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign +the hash of documents only but also to pad the inputs with data to remove such structure. + +\section{Core Functions} + +For RSA routines a single ``rsa\_key'' structure is used. To make a new RSA key call: +\index{rsa\_make\_key()} +\begin{verbatim} +int rsa_make_key(prng_state *prng, + int wprng, int size, + long e, rsa_key *key); +\end{verbatim} + +Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired. +``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big +enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at +least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}). + +Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call +``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically +free the ram allocated itself. + +There are three types of RSA keys. The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first +two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures. By +default all new keys are of the ``optimized'' type. The non-optimized private type is provided for backwards compatibility +as well as to save space since the optimized key requires about four times as much memory. + +To do raw work with the RSA function call: +\index{rsa\_exptmod()} +\begin{verbatim} +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int which, rsa_key *key); +\end{verbatim} +This loads the bignum from ``in'' as a big endian word in the format PKCS specifies, raises it to either ``e'' or ``d'' and stores the result +in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e'' +(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing). + +Note that this function does not perform padding on the input (as per PKCS). So if you send in ``0000001'' you will +get ``01'' back (when you do the opposite operation). Make sure you pad properly which usually involves setting the msb to +a non-zero value. + +\section{Packet Routines} +To encrypt or decrypt a symmetric key using RSA the following functions are provided. The idea is that you make up +a random symmetric key and use that to encode your message. By RSA encrypting the symmetric key you can send it to a +recipient who can RSA decrypt it and symmetrically decrypt the message. +\begin{verbatim} +int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, + unsigned char *outkey, unsigned long *outlen, + prng_state *prng, int wprng, rsa_key *key); +\end{verbatim} +This function is used to RSA encrypt a symmetric to share with another user. The symmetric key and its length are +passed as ``inkey'' and ``inlen'' respectively. The symmetric key is limited to a range of 8 to 32 bytes +(\textit{64 to 256 bits}). The RSA encrypted packet is stored in ``outkey'' and will be of length ``outlen'' bytes. The +value of ``outlen'' must be originally set to the size of the output buffer. + +\begin{verbatim} +int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + rsa_key *key); +\end{verbatim} + +This function will decrypt an RSA packet to retrieve the original symmetric key encrypted with rsa\_encrypt\_key(). +Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your message +then use these functions to RSA sign the hash. +\begin{verbatim} +int rsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + rsa_key *key); + +int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, int *stat, rsa_key *key); +\end{verbatim} +For ``rsa\_sign\_hash'' the input is intended to be the hash of a message the user wants to sign. The output is the +RSA signed packet which ``rsa\_verify\_hash'' can verify. For the verification function ``sig'' is the RSA signature +and ``hash'' is the hash of the message. The integer ``stat'' is set to non-zero if the signature is valid or zero +otherwise. + +To import/export RSA keys as a memory buffer (e.g. to store them to disk) call: +\begin{verbatim} +int rsa_export(unsigned char *out, unsigned long *outlen, + int type, rsa_key *key); + +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); +\end{verbatim} + +The ``type'' parameter is {\bf PK\_PUBLIC}, {\bf PK\_PRIVATE} or {\bf PK\_PRIVATE\_OPTIMIZED} to export either a public or +private key. The latter type will export a key with the optimized parameters. To free the memory used by an RSA key call: +\index{rsa\_free()} +\begin{verbatim} +void rsa_free(rsa_key *key); +\end{verbatim} + +Note that if the key fails to ``rsa\_import()'' you do not have to free the memory allocated for it. + +\section{Remarks} +It is important that you match your RSA key size with the function you are performing. The internal padding for both +signatures and encryption triple the size of the plaintext. This means to encrypt or sign +a message of N bytes you must have a modulus of 1+3N bytes. Note that this doesn't affect the length of the plaintext +you pass into functions like rsa\_encrypt(). This restriction applies only to data that is passed through the +internal RSA routines directly directly. + +The following table gives the size requirements for various hashes. +\begin{center} +\begin{tabular}{|c|c|c|} + \hline Name & Size of Message Digest (bytes) & RSA Key Size (bits)\\ + \hline SHA-512 & 64 & 1544\\ + \hline SHA-384 & 48 & 1160 \\ + \hline SHA-256 & 32 & 776\\ + \hline TIGER-192 & 24 & 584\\ + \hline SHA-1 & 20 & 488\\ + \hline MD5 & 16 & 392\\ + \hline MD4 & 16 & 392\\ + \hline +\end{tabular} +\end{center} + +The symmetric ciphers will use at a maximum a 256-bit key which means at the least a 776-bit RSA key is +required to use all of the symmetric ciphers with the RSA routines. If you want to use any of the large size +message digests (SHA-512 or SHA-384) you will have to use a larger key. Or to be simple just make 2048-bit or larger +keys. None of the hashes will have problems with such key sizes. + +\chapter{Diffie-Hellman Key Exchange} + +\section{Background} + +Diffie-Hellman was the original public key system proposed. The system is based upon the group structure +of finite fields. For Diffie-Hellman a prime $p$ is chosen and a ``base'' $b$ such that $b^x\mbox{ }(\mbox{mod }p)$ +generates a large sub-group of prime order (for unique values of $x$). + +A secret key is an exponent $x$ and a public key is the value of $y \equiv g^x\mbox{ }(\mbox{mod }p)$. The term +``discrete logarithm'' denotes the action of finding $x$ given only $y$, $g$ and $p$. The key exchange part of +Diffie-Hellman arises from the fact that two users A and B with keys $(A_x, A_y)$ and $(B_x, B_y)$ can exchange +a shared key $K \equiv B_y^{A_x} \equiv A_y^{B_x} \equiv g^{A_xB_x}\mbox{ }(\mbox{mod }p)$. + +From this public encryption and signatures can be developed. The trivial way to encrypt (for example) using a public key +$y$ is to perform the key exchange offline. The sender invents a key $k$ and its public copy +$k' \equiv g^k\mbox{ }(\mbox{mod }p)$ and uses $K \equiv k'^{A_x}\mbox{ }(\mbox{mod }p)$ as a key to encrypt +the message with. Typically $K$ would be sent to a one-way hash and the message digested used as a key in a +symmetric cipher. + +It is important that the order of the sub-group that $g$ generates not only be large but also prime. There are +discrete logarithm algorithms that take $\sqrt r$ time given the order $r$. The discrete logarithm can be computed +modulo each prime factor of $r$ and the results combined using the Chinese Remainder Theorem. In the cases where +$r$ is ``B-Smooth'' (e.g. all small factors or powers of small prime factors) the solution is trivial to find. + +To thwart such attacks the primes and bases in the library have been designed and fixed. Given a prime $p$ the order of + the sub-group generated is a large prime namely ${p - 1} \over 2$. Such primes are known as ``strong primes'' and the +smaller prime (e.g. the order of the base) are known as Sophie-Germaine primes. + +\section{Core Functions} + +This library also provides core Diffie-Hellman functions so you can negotiate keys over insecure mediums. The routines +provided are relatively easy to use and only take two function calls to negotiate a shared key. There is a structure +called ``dh\_key'' which stores the Diffie-Hellman key in a format these routines can use. The first routine is to +make a Diffie-Hellman private key pair: +\index{dh\_make\_key()} +\begin{verbatim} +int dh_make_key(prng_state *prng, int wprng, + int keysize, dh_key *key); +\end{verbatim} +The ``keysize'' is the size of the modulus you want in bytes. Currently support sizes are 96 to 512 bytes which correspond +to key sizes of 768 to 4096 bits. The smaller the key the faster it is to use however it will be less secure. When +specifying a size not explicitly supported by the library it will round {\em up} to the next key size. If the size is +above 512 it will return an error. So if you pass ``keysize == 32'' it will use a 768 bit key but if you pass +``keysize == 20000'' it will return an error. The primes and generators used are built-into the library and were designed +to meet very specific goals. The primes are strong primes which means that if $p$ is the prime then +$p-1$ is equal to $2r$ where $r$ is a large prime. The bases are chosen to generate a group of order $r$ to prevent +leaking a bit of the key. This means the bases generate a very large prime order group which is good to make cryptanalysis +hard. + +The next two routines are for exporting/importing Diffie-Hellman keys in a binary format. This is useful for transport +over communication mediums. + +\index{dh\_export()} \index{dh\_import()} +\begin{verbatim} +int dh_export(unsigned char *out, unsigned long *outlen, + int type, dh_key *key); + +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); +\end{verbatim} + +These two functions work just like the ``rsa\_export()'' and ``rsa\_import()'' functions except these work with +Diffie-Hellman keys. Its important to note you do not have to free the ram for a ``dh\_key'' if an import fails. You can free a +``dh\_key'' using: +\begin{verbatim} +void dh_free(dh_key *key); +\end{verbatim} +After you have exported a copy of your public key (using {\bf PK\_PUBLIC} as ``type'') you can now create a shared secret +with the other user using: +\index{dh\_shared\_secret()} +\begin{verbatim} +int dh_shared_secret(dh_key *private_key, + dh_key *public_key, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +Where ``private\_key'' is the key you made and ``public\_key'' is the copy of the public key the other user sent you. The result goes +into ``out'' and the length into ``outlen''. If all went correctly the data in ``out'' should be identical for both parties. It is important to +note that the two keys have to be the same size in order for this to work. There is a function to get the size of a +key: +\index{dh\_get\_size()} +\begin{verbatim} +int dh_get_size(dh_key *key); +\end{verbatim} +This returns the size in bytes of the modulus chosen for that key. + +\subsection{Remarks on Usage} +Its important that you hash the shared key before trying to use it as a key for a symmetric cipher or something. An +example program that communicates over sockets, using MD5 and 1024-bit DH keys is\footnote{This function is a small example. It is suggested that proper packaging be used. For example, if the public key sent is truncated these routines will not detect that.}: +\newpage +\begin{small} +\begin{verbatim} +int establish_secure_socket(int sock, int mode, unsigned char *key, + prng_state *prng, int wprng) +{ + unsigned char buf[4096], buf2[4096]; + unsigned long x, len; + int res, err, inlen; + dh_key mykey, theirkey; + + /* make up our private key */ + if ((err = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK) { + return err; + } + + /* export our key as public */ + x = sizeof(buf); + if ((err = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) { + res = err; + goto done2; + } + + if (mode == 0) { + /* mode 0 so we send first */ + if (send(sock, buf, x, 0) != x) { + res = CRYPT_ERROR; + goto done2; + } + + /* get their key */ + if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) { + res = CRYPT_ERROR; + goto done2; + } + } else { + /* mode >0 so we send second */ + if ((inlen = recv(sock, buf2, sizeof(buf2), 0)) <= 0) { + res = CRYPT_ERROR; + goto done2; + } + + if (send(sock, buf, x, 0) != x) { + res = CRYPT_ERROR; + goto done2; + } + } + + if ((err = dh_import(buf2, inlen, &theirkey)) != CRYPT_OK) { + res = err; + goto done2; + } + + /* make shared secret */ + x = sizeof(buf); + if ((err = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) { + res = err; + goto done; + } + + /* hash it */ + len = 16; /* default is MD5 so "key" must be at least 16 bytes long */ + if ((err = hash_memory(find_hash("md5"), buf, x, key, &len)) != CRYPT_OK) { + res = err; + goto done; + } + + /* clean up and return */ + res = CRYPT_OK; +done: + dh_free(&theirkey); +done2: + dh_free(&mykey); + zeromem(buf, sizeof(buf)); + zeromem(buf2, sizeof(buf2)); + return res; +} +\end{verbatim} +\end{small} +\newpage +\subsection{Remarks on The Snippet} +When the above code snippet is done (assuming all went well) their will be a shared 128-bit key in the ``key'' array +passed to ``establish\_secure\_socket()''. + +\section{Other Diffie-Hellman Functions} +In order to test the Diffie-Hellman function internal workings (e.g. the primes and bases) their is a test function made +available: +\index{dh\_test()} +\begin{verbatim} +int dh_test(void); +\end{verbatim} + +This function returns {\bf CRYPT\_OK} if the bases and primes in the library are correct. There is one last helper +function: +\index{dh\_sizes()} +\begin{verbatim} +void dh_sizes(int *low, int *high); +\end{verbatim} +Which stores the smallest and largest key sizes support into the two variables. + +\section{DH Packet} +Similar to the RSA related functions there are functions to encrypt or decrypt symmetric keys using the DH public key +algorithms. +\begin{verbatim} +int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + dh_key *key); + +int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + dh_key *key); +\end{verbatim} +Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key +and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the +required data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large +as the symmetric key you are trying to share. + +Similar to the RSA system you can sign and verify a hash of a message. +\begin{verbatim} +int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key); + +int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key); +\end{verbatim} + +The ``dh\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a DH packet in ``out''. +The ``dh\_verify\_hash'' function verifies the DH signature in ``sig'' against the hash in ``hash''. It sets ``stat'' +to non-zero if the signature passes or zero if it fails. + +\chapter{Elliptic Curve Cryptography} + +\section{Background} +The library provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of all of the +Diffie-Hellman routines in the previous chapter. Elliptic curves (of certain forms) have the benefit that they are harder +to attack (no sub-exponential attacks exist unlike normal DH crypto) in fact the fastest attack requires the square root +of the order of the base point in time. That means if you use a base point of order $2^{192}$ (which would represent a +192-bit key) then the work factor is $2^{96}$ in order to find the secret key. + +The curves in this library are taken from the following website: +\begin{verbatim} +http://csrc.nist.gov/cryptval/dss.htm +\end{verbatim} + +They are all curves over the integers modulo a prime. The curves have the basic equation that is: +\begin{equation} +y^2 = x^3 - 3x + b\mbox{ }(\mbox{mod }p) +\end{equation} + +The variable $b$ is chosen such that the number of points is nearly maximal. In fact the order of the base points $\beta$ +provided are very close to $p$ that is $\vert \vert \phi(\beta) \vert \vert \approx \vert \vert p \vert \vert$. The curves +range in order from $\approx 2^{192}$ points to $\approx 2^{521}$. According to the source document any key size greater +than or equal to 256-bits is sufficient for long term security. + +\section{Core Functions} + +Like the DH routines there is a key structure ``ecc\_key'' used by the functions. There is a function to make a key: +\index{ecc\_make\_key()} +\begin{verbatim} +int ecc_make_key(prng_state *prng, int wprng, + int keysize, ecc_key *key); +\end{verbatim} + +The ``keysize'' is the size of the modulus in bytes desired. Currently directly supported values are 20, 24, 28, 32, 48 and 65 bytes which +correspond to key sizes of 160, 192, 224, 256, 384 and 521 bits respectively. If you pass a key size that is between any key size +it will round the keysize up to the next available one. The rest of the parameters work like they do in the ``dh\_make\_key()'' function. +To free the ram allocated by a key call: +\index{ecc\_free()} +\begin{verbatim} +void ecc_free(ecc_key *key); +\end{verbatim} + +To import and export a key there are: +\index{ecc\_export()} +\index{ecc\_import()} +\begin{verbatim} +int ecc_export(unsigned char *out, unsigned long *outlen, + int type, ecc_key *key); + +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +\end{verbatim} +These two work exactly like there DH counterparts. Finally when you share your public key you can make a shared secret +with: +\index{ecc\_shared\_secret()} +\begin{verbatim} +int ecc_shared_secret(ecc_key *private_key, + ecc_key *public_key, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +Which works exactly like the DH counterpart, the ``private\_key'' is your own key and ``public\_key'' is the key the other +user sent you. Note that this function stores both $x$ and $y$ co-ordinates of the shared +elliptic point. You should hash the output to get a shared key in a more compact and useful form (most of the entropy is +in $x$ anyways). Both keys have to be the same size for this to work, to help there is a function to get the size in bytes + of a key. +\index{ecc\_get\_size()} +\begin{verbatim} +int ecc_get_size(ecc_key *key); +\end{verbatim} + +To test the ECC routines and to get the minimum and maximum key sizes there are these two functions: +\index{ecc\_test()} +\begin{verbatim} +int ecc_test(void); +void ecc_sizes(int *low, int *high); +\end{verbatim} +Which both work like their DH counterparts. + +\section{ECC Packet} +Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key +algorithms. +\begin{verbatim} +int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + ecc_key *key); +\end{verbatim} + +Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key +and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required +data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large +as the symmetric key you are trying to share. + +There are also functions to sign and verify the hash of a message. +\begin{verbatim} +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); +\end{verbatim} + +The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''. +The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''. It sets ``stat'' +to non-zero if the signature passes or zero if it fails. + + +\section{ECC Keysizes} +With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work +and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of +the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and a ECC-160 key in effect +you have 160-bits of security (e.g. as if you signed with SHA-1). + +The library will not warn you if you make this mistake so it is important to check yourself before using the +signatures. + +\chapter{Digital Signature Algorithm} +\section{Introduction} +The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to +reduce the bandwidth of a signature. For example, to have ``80-bits of security'' with ElGamal you need a group of +order at least 1024-bits. With DSA you need a group of order at least 160-bits. By comparison the ElGamal signature +would require at least 256 bytes where as the DSA signature would require only at least 40 bytes. + +The API for the DSA is essentially the same as the other PK algorithms. Except in the case of DSA no encryption or +decryption routines are provided. + +\section{Key Generation} +To make a DSA key you must call the following function +\begin{verbatim} +int dsa_make_key(prng_state *prng, int wprng, + int group_size, int modulus_size, + dsa_key *key); +\end{verbatim} +The variable ``prng'' is an active PRNG state and ``wprng'' the index to the descriptor. ``group\_size'' and +``modulus\_size'' control the difficulty of forging a signature. Both parameters are in bytes. The larger the +``group\_size'' the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by +$15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows. + +\begin{center} +\begin{tabular}{|c|c|c|} +\hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\ +\hline 80 & 20 & 128 \\ +\hline 120 & 30 & 256 \\ +\hline 140 & 35 & 384 \\ +\hline 160 & 40 & 512 \\ +\hline +\end{tabular} +\end{center} + +When you are finished with a DSA key you can call the following function to free the memory used. +\begin{verbatim} +void dsa_free(dsa_key *key); +\end{verbatim} + +\section{Key Verification} +Each DSA key is composed of the following variables. + +\begin{enumerate} + \item $q$ a small prime of magnitude $256^{group\_size}$. + \item $p = qr + 1$ a large prime of magnitude $256^{modulus\_size}$ where $r$ is a random even integer. + \item $g = h^r \mbox{ (mod }p\mbox{)}$ a generator of order $q$ modulo $p$. $h$ can be any non-trivial random + value. For this library they start at $h = 2$ and step until $g$ is not $1$. + \item $x$ a random secret (the secret key) in the range $1 < x < q$ + \item $y = g^x \mbox{ (mod }p\mbox{)}$ the public key. +\end{enumerate} + +A DSA key is considered valid if it passes all of the following tests. + +\begin{enumerate} + \item $q$ must be prime. + \item $p$ must be prime. + \item $g$ cannot be one of $\lbrace -1, 0, 1 \rbrace$ (modulo $p$). + \item $g$ must be less than $p$. + \item $(p-1) \equiv 0 \mbox{ (mod }q\mbox{)}$. + \item $g^q \equiv 1 \mbox{ (mod }p\mbox{)}$. + \item $1 < y < p - 1$ + \item $y^q \equiv 1 \mbox{ (mod }p\mbox{)}$. +\end{enumerate} + +Tests one and two ensure that the values will at least form a field which is required for the signatures to +function. Tests three and four ensure that the generator $g$ is not set to a trivial value which would make signature +forgery easier. Test five ensures that $q$ divides the order of multiplicative sub-group of $\Z/p\Z$. Test six +ensures that the generator actually generates a prime order group. Tests seven and eight ensure that the public key +is within range and belongs to a group of prime order. Note that test eight does not prove that $g$ generated $y$ only +that $y$ belongs to a multiplicative sub-group of order $q$. + +The following function will perform these tests. + +\begin{verbatim} +int dsa_verify_key(dsa_key *key, int *stat); +\end{verbatim} + +This will test ``key'' and store the result in ``stat''. If the result is $stat = 0$ the DSA key failed one of the tests +and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned). + + + +\section{Signatures} +To generate a DSA signature call the following function + +\begin{verbatim} +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); +\end{verbatim} + +Which will sign the data in ``in'' of length ``inlen'' bytes. The signature is stored in ``out'' and the size +of the signature in ``outlen''. If the signature is longer than the size you initially specify in ``outlen'' nothing +is stored and the function returns an error code. The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion. + +To verify a hash created with that function use the following function + +\begin{verbatim} +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, dsa_key *key); +\end{verbatim} +Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''. +It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$. + +\section{Import and Export} + +To export a DSA key so that it can be transported use the following function +\begin{verbatim} +int dsa_export(unsigned char *out, unsigned long *outlen, + int type, + dsa_key *key); +\end{verbatim} +This will export the DSA ``key'' to the buffer ``out'' and set the length in ``outlen'' (which must have been previously +initialized to the maximum buffer size). The ``type`` variable may be either \textbf{PK\_PRIVATE} or \textbf{PK\_PUBLIC} +depending on whether you want to export a private or public copy of the DSA key. + +To import an exported DSA key use the following function + +\begin{verbatim} +int dsa_import(const unsigned char *in, unsigned long inlen, + dsa_key *key); +\end{verbatim} + +This will import the DSA key from the buffer ``in'' of length ``inlen'' to the ``key''. If the process fails the function +will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()). + +\chapter{Public Keyrings} +\section{Introduction} +In order to simplify the usage of the public key algorithms a set of keyring routines have been developed. They let the +developer manage asymmetric keys by providing load, save, export, import routines as well as encrypt, decrypt, sign, verify +routines in a unified API. That is all three types of PK systems can be used within the same keyring with the same API. + +To define types of keys there are four enumerations used globaly: +\begin{verbatim} +enum { + NON_KEY=0, + RSA_KEY, + DH_KEY, + ECC_KEY +}; +\end{verbatim} + +To make use of the system the developer has to know how link-lists work. The main structure that the keyring routines use +is the ``pk\_key'' defined as: +\begin{small} +\begin{verbatim} +typedef struct Pk_key { + int key_type, /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */ + system; /* RSA, ECC or DH ? */ + + char name[MAXLEN], /* various info's about this key */ + email[MAXLEN], + description[MAXLEN]; + + unsigned long ID; /* CRC32 of the name/email/description together */ + + _pk_key key; + + struct Pk_key *next; /* linked list chain */ +} pk_key; +\end{verbatim} +\end{small} + +The list is chained via the ``next'' member and terminated with the node of the list that has ``system'' equal to +{\bf NON\_KEY}. + +\section{The Keyring API} +To initialize a blank keyring the function ``kr\_init()'' is used. +\begin{verbatim} +int kr_init(pk_key **pk); +\end{verbatim} +You pass it a pointer to a pointer of type ``pk\_key'' where it will allocate ram for one node of the keyring and sets the +pointer. + +Now instead of calling the PK specific ``make\_key'' functions there is one function that can make all three types of keys. +\begin{verbatim} +int kr_make_key(pk_key *pk, prng_state *prng, int wprng, + int system, int keysize, const char *name, + const char *email, const char *description); +\end{verbatim} +The ``name'', ``email'' and ``description'' parameters are simply little pieces of information that you can tag along with a +key. They can each be either blank or any string less than 256 bytes. ``system'' is one of the enumeration elements, that +is {\bf RSA\_KEY}, {\bf DH\_KEY} or {\bf ECC\_KEY}. ``keysize'' is the size of the key you desire which is regulated by +the individual systems, for example, RSA keys are limited in keysize from 128 to 512 bytes. + +To find keys along a keyring there are two functions provided: +\begin{verbatim} +pk_key *kr_find(pk_key *pk, unsigned long ID); + +pk_key *kr_find_name(pk_key *pk, const char *name); +\end{verbatim} +The first searches by the 32-bit ID provided and the latter checks the name against the keyring. They both return a pointer +to the node in the ring of a match or {\bf NULL} if no match is found. + +To export or import a single node of a keyring the two functions are provided: +\begin{verbatim} +int kr_export(pk_key *pk, unsigned long ID, int key_type, + unsigned char *out, unsigned long *outlen); + +int kr_import(pk_key *pk, const unsigned char *in); +\end{verbatim} +The export function exports the key with an ID provided and of a specific type much like the normal PK export routines. The +``key\_type'' is one of {\bf PK\_PUBLIC} or {\bf PK\_PRIVATE}. In this function with RSA keys the type +{\bf PK\_PRIVATE\_OPTIMIZED} is the same as the {\bf PK\_PRIVATE} type. The import function will read in a packet and +add it to the keyring. + +To load and save whole keyrings from disk: +\begin{verbatim} +int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr); + +int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr); +\end{verbatim} +Both take file pointers to allow the user to pre-append data to the stream. The ``ctr'' parameter should be setup with +``ctr\_start'' or set to NULL. This parameter lets the user encrypt the keyring as its written to disk, if it is set +to NULL the data is written without being encrypted. The load function assumes the list has not been initialized yet +and will reset the pointer given to it. + +There are the four encrypt, decrypt, sign and verify functions as well +\begin{verbatim} +int kr_encrypt_key(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash); + +int kr_decrypt_key(pk_key *pk, const unsigned char *in, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +The kr\_encrypt\_key() routine is designed to encrypt a symmetric key with a specified users public key. The symmetric +key is then used with a block cipher to encode the message. The recipient can call kr\_decrypt\_key() to get the original +symmetric key back and decode the message. The hash specified must produce a message digest longer than symmetric key +provided. + +\begin{verbatim} +int kr_sign_hash(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng); + +int kr_verify_hash(pk_key *pk, const unsigned char *in, + const unsigned char *hash, unsigned long hashlen, + int *stat); +\end{verbatim} + +Similar to the two previous these are used to sign a message digest or verify one. This requires hashing the message +first then passing the output in. + +To delete keys and clear rings there are: +\begin{verbatim} +int kr_del(pk_key **_pk, unsigned long ID); +int kr_clear(pk_key **pk); +\end{verbatim} +``kr\_del'' will try to remove a key with a given ID from the ring and ``kr\_clear'' will completely empty a list and free +the memory associated with it. Below is small example using the keyring API: + +\begin{small} +\begin{verbatim} +#include <mycrypt.h> +int main(void) +{ + pk_key *kr; + unsigned char buf[4096], buf2[4096]; + unsigned long len; + int err; + + /* make a new list */ + if ((err = kr_init(&kr)) != CRYPT_OK) { + printf("kr_init: %s\n", error_to_string(err)); + exit(-1); + } + + /* add a key to it */ + register_prng(&sprng_desc); + if ((err = kr_make_key(kr, NULL, find_prng("sprng"), RSA_KEY, 128, + "TomBot", "[email protected]", "test key")) == CRYPT_OK) { + printf("kr_make_key: %s\n", error_to_string(err)); + exit(-1); + } + + /* export the first key */ + len = sizeof(buf); + if ((err = kr_export(kr, kr->ID, PK_PRIVATE, buf, &len)) != CRYPT_OK) { + printf("kr_export: %s\n", error_to_string(err)); + exit(-1); + } + + /* ... */ +} +\end{verbatim} +\end{small} + +\chapter{$GF(2^w)$ Math Routines} + +The library provides a set of polynomial-basis $GF(2^w)$ routines to help facilitate algorithms such as ECC over such +fields. Note that the current implementation of ECC in the library is strictly over the integers only. The routines +are simple enough to use for other purposes outside of ECC. + +At the heart of all of the GF routines is the data type ``gf\_int'. It is simply a type definition for an array of +$L$ 32-bit words. You can configure the maximum size $L$ of the ``gf\_int'' type by opening the file ``mycrypt.h'' and +changing ``LSIZE''. Note that if you set it to $n$ then you can only multiply upto two $n \over 2$ bit polynomials without +an overflow. The type ``gf\_intp'' is associated with a pointer to an ``unsigned long'' as required in the algorithms. + +There are no initialization routines for ``gf\_int'' variables and you can simply use them after declaration. There are five +low level functions: +\index{gf\_copy()} \index{gf\_zero()} \index{gf\_iszero()} \index{gf\_isone()} +\index{gf\_deg()} +\begin{verbatim} +void gf_copy(gf_intp a, gf_intp b); +void gf_zero(gf_intp a); +int gf_iszero(gf_intp a); +int gf_isone(gf_intp a); +int gf_deg(gf_intp a); +\end{verbatim} +There are all fairly self-explanatory. ``gf\_copy(a, b)'' copies the contents of ``a'' into ``b''. ``gf\_zero()'' simply +zeroes the entire polynomial. ``gf\_iszero()'' tests to see if the polynomial is all zero and ``gf\_isone()'' tests to see +if the polynomial is equal to the multiplicative identity. ``gf\_deg()'' returns the degree of the polynomial or $-1$ if its +a zero polynomial. + +There are five core math routines as well: +\index{gf\_shl()} \index{gf\_shr()} \index{gf\_add()} \index{gf\_mul()} \index{gf\_div()} +\begin{verbatim} +void gf_shl(gf_intp a, gf_intp b); +void gf_shr(gf_intp a, gf_intp b); +void gf_add(gf_intp a, gf_intp b, gf_intp c); +void gf_mul(gf_intp a, gf_intp b, gf_intp c); +void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r); +\end{verbatim} + +Which are all fairly obvious. ``gf\_shl(a,b)'' multiplies the polynomial ``a'' by $x$ and stores it in ``b''. +``gf\_shl(a,b)'' divides the polynomial ``a'' by $x$ and stores it in ``b''. ``gf\_add(a,b,c)'' adds the polynomial +``a'' to ``b'' and stores the sum in ``c''. Similarly for ``gf\_mul(a,b,c)''. The ``gf\_div(a,b,q,r)'' function divides +``a'' by ``b'' and stores the quotient in ``q'' and the remainder in ``r''. + +There are six number theoretic functions as well: +\index{gf\_mod()} \index{gf\_mulmod()} \index{gf\_invmod()} \index{gf\_gcd()} \index{gf\_is\_prime()} +\index{gf\_sqrt()} +\begin{verbatim} +void gf_mod(gf_intp a, gf_intp m, gf_intp b); +void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c); +void gf_invmod(gf_intp A, gf_intp M, gf_intp B); +void gf_sqrt(gf_intp a, gf_intp m, gf_intp b); +void gf_gcd(gf_intp A, gf_intp B, gf_intp c); +int gf_is_prime(gf_intp a); +\end{verbatim} + +Which all work similarly except for ``gf\_mulmod(a,b,m,c)'' which computes $c = ab\mbox{ }(\mbox{mod }m)$. The +``gf\_is\_prime()'' function returns one if the polynomial is primitive, otherwise it returns zero. + +Finally to read/store a ``gf\_int'' in a binary string use: +\index{gf\_size()} \index{gf\_toraw()} \index{gf\_readraw()} +\begin{verbatim} +int gf_size(gf_intp a); +void gf_toraw(gf_intp a, unsigned char *dst); +void gf_readraw(gf_intp a, unsigned char *str, int len); +\end{verbatim} +Where ``gf\_size()'' returns the size in bytes required for the data. ``gf\_toraw(a,b)'' stores the polynomial in ``b'' +in binary format (endian neutral). ``gf\_readraw(a,b,c)'' reads the binary string in ``b'' back. Note that the length +you pass it must be the same as returned by ``gf\_size()'' or it will not load correctly. + +\chapter{Miscellaneous} +\section{Base64 Encoding and Decoding} +The library provides functions to encode and decode a RFC1521 base64 coding scheme. This means that it can decode what it +encodes but the format used does not comply to any known standard. The characters used in the mappings are: +\begin{verbatim} +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ +\end{verbatim} +Those characters should are supported in virtually any 7-bit ASCII system which means they can be used for transport over +common e-mail, usenet and HTTP mediums. The format of an encoded stream is just a literal sequence of ASCII characters +where a group of four represent 24-bits of input. The first four chars of the encoders output is the length of the +original input. After the first four characters is the rest of the message. + +Often it is desirable to line wrap the output to fit nicely in an e-mail or usenet posting. The decoder allows you to +put any character (that is not in the above sequence) in between any character of the encoders output. You may not however, +break up the first four characters. + +To encode a binary string in base64 call: +\index{base64\_encode()} \index{base64\_decode()} +\begin{verbatim} +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +Where ``in'' is the binary string and ``out'' is where the ASCII output is placed. You must set the value of ``outlen'' prior +to calling this function and it sets the length of the base64 output in ``outlen'' when it is done. To decode a base64 +string call: +\begin{verbatim} +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +\end{verbatim} + +\section{The Multiple Precision Integer Library (MPI)} +The library comes with a copy of LibTomMath which is a multiple precision integer library written by the +author of LibTomCrypt. LibTomMath is a trivial to use ANSI C compatible large integer library which is free +for all uses and is distributed freely. + +At the heart of all the functions is the data type ``mp\_int'' (defined in tommath.h). This data type is what +will hold all large integers. In order to use an mp\_int one must initialize it first, for example: +\begin{verbatim} +#include <mycrypt.h> /* mycrypt.h includes mpi.h automatically */ +int main(void) +{ + mp_int bignum; + + /* initialize it */ + mp_init(&bignum); + + return 0; +} +\end{verbatim} +If you are unfamiliar with the syntax of C the \& symbol is used to pass the address of ``bignum'' to the function. All +LibTomMath functions require the address of the parameters. To free the memory of a mp\_int use (for example): +\begin{verbatim} +mp_clear(&bignum); +\end{verbatim} + +The functions also have the basic form of one of the following: +\begin{verbatim} +mp_XXX(mp_int *a); +mp_XXX(mp_int *a, mp_int *b, mp_int *c); +mp_XXX(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +\end{verbatim} + +Where they perform some operation and store the result in the mp\_int variable passed on the far right. +For example, to compute $c = a + b \mbox{ }(\mbox{mod }m)$ you would call: +\begin{verbatim} +mp_addmod(&a, &b, &m, &c); +\end{verbatim} + +\subsection{Binary Forms of ``mp\_int'' Variables} + +Often it is required to store a ``mp\_int'' in binary form for transport (e.g. exporting a key, packet +encryption, etc.). LibTomMath includes two functions to help when exporting numbers: +\begin{verbatim} +int mp_raw_size(mp_int *num); +mp_toraw(&num, buf); +\end{verbatim} + +The former function gives the size in bytes of the raw format and the latter function actually stores the raw data. All +``mp\_int'' numbers are stored in big endian form (like PKCS demands) with the first byte being the sign of the number. The +``rsa\_exptmod()'' function differs slightly since it will take the input in the form exactly as PKCS demands (without the +leading sign byte). All other functions include the sign byte (since its much simpler just to include it). The sign byte +must be zero for positive numbers and non-zero for negative numbers. For example, +the sequence: +\begin{verbatim} +00 FF 30 04 +\end{verbatim} +Represents the integer $255 \cdot 256^2 + 48 \cdot 256^1 + 4 \cdot 256^0$ or 16,723,972. + +To read a binary string back into a ``mp\_int'' call: +\begin{verbatim} +mp_read_raw(mp_int *num, unsigned char *str, int len); +\end{verbatim} +Where ``num'' is where to store it, ``str'' is the binary string (including the leading sign byte) and ``len'' is the +length of the binary string. + +\subsection{Primality Testing} +\index{Primality Testing} +The library includes primality testing and random prime functions as well. The primality tester will perform the test in +two phases. First it will perform trial division by the first few primes. Second it will perform eight rounds of the +Rabin-Miller primality testing algorithm. If the candidate passes both phases it is declared prime otherwise it is declared +composite. No prime number will fail the two phases but composites can. Each round of the Rabin-Miller algorithm reduces +the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than +$\left ( { 1 \over 4 } \right )^{8} = 2^{-16}$. In practice the probability of error is in fact much lower than that. + +When making random primes the trial division step is in fact an optimized implementation of ``Implementation of Fast RSA Key Generation on Smart Cards''\footnote{Chenghuai Lu, Andre L. M. dos Santos and Francisco R. Pimentel}. +In essence a table of machine-word sized residues are kept of a candidate modulo a set of primes. When the candiate +is rejected and ultimately incremented to test the next number the residues are updated without using multi-word precision +math operations. As a result the routine can scan ahead to the next number required for testing with very little work +involved. + +In the event that a composite did make it through it would most likely cause the the algorithm trying to use it to fail. For +instance, in RSA two primes $p$ and $q$ are required. The order of the multiplicative sub-group (modulo $pq$) is given +as $\phi(pq)$ or $(p - 1)(q - 1)$. The decryption exponent $d$ is found as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$. If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user +will not be able to sign or decrypt messages at all. Suppose $p$ was prime and $q$ was composite this is just a variation of +the multi-prime RSA. Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is +not equal to $(p - 1)(rs - 1)$. + +These are not technically part of the LibTomMath library but this is the best place to document them. +To test if a ``mp\_int'' is prime call: +\begin{verbatim} +int is_prime(mp_int *N, int *result); +\end{verbatim} +This puts a one in ``result'' if the number is probably prime, otherwise it places a zero in it. It is assumed that if +it returns an error that the value in ``result'' is undefined. To make +a random prime call: +\begin{verbatim} +int rand_prime(mp_int *N, unsigned long len, prng_state *prng, int wprng); +\end{verbatim} +Where ``len'' is the size of the prime in bytes ($2 \le len \le 256$). You can set ``len'' to the negative size you want +to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$. So if you want a 1024-bit prime of this sort pass +``len = -128'' to the function. Upon success it will return {\bf CRYPT\_OK} and ``N'' will contain an integer which +is very likely prime. + +\chapter{Programming Guidelines} + +\section{Secure Pseudo Random Number Generators} +Probably the singal most vulnerable point of any cryptosystem is the PRNG. Without one generating and protecting secrets +would be impossible. The requirement that one be setup correctly is vitally important and to address this point the library +does provide two RNG sources that will address the largest amount of end users as possible. The ``sprng'' PRNG provided +provides and easy to access source of entropy for any application on a *NIX or Windows computer. + +However, when the end user is not on one of these platforms the application developer must address the issue of finding +entropy. This manual is not designed to be a text on cryptography. I would just like to highlight that when you design +a cryptosystem make sure the first problem you solve is getting a fresh source of entropy. + +\section{Preventing Trivial Errors} +Two simple ways to prevent trivial errors is to prevent overflows and to check the return values. All of the functions +which output variable length strings will require you to pass the length of the destination. If the size of your output +buffer is smaller than the output it will report an error. Therefore, make sure the size you pass is correct! + +Also virtually all of the functions return an error code or {\bf CRYPT\_OK}. You should detect all errors as simple +typos or such can cause algorithms to fail to work as desired. + +\section{Registering Your Algorithms} +To avoid linking and other runtime errors it is important to register the ciphers, hashes and PRNGs you intend to use +before you try to use them. This includes any function which would use an algorithm indirectly through a descriptor table. + +A neat bonus to the registry system is that you can add external algorithms that are not part of the library without +having to hack the library. For example, suppose you have a hardware specific PRNG on your system. You could easily +write the few functions required plus a descriptor. After registering your PRNG all of the library functions that +need a PRNG can instantly take advantage of it. + +\section{Key Sizes} + +\subsection{Symmetric Ciphers} +For symmetric ciphers use as large as of a key as possible. For the most part ``bits are cheap'' so using a 256-bit key +is not a hard thing todo. + +\subsection{Assymetric Ciphers} +The following chart gives the work factor for solving a DH/RSA public key using the NFS. The work factor for a key of order +$n$ is estimated to be +\begin{equation} +e^{1.923 \cdot ln(n)^{1 \over 3} \cdot ln(ln(n))^{2 \over 3}} +\end{equation} + +Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required +is: +\begin{center} +\begin{tabular}{|c|c|} + \hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\ + \hline 512 & 63.92 \\ + \hline 768 & 76.50 \\ + \hline 1024 & 86.76 \\ + \hline 1536 & 103.37 \\ + \hline 2048 & 116.88 \\ + \hline 2560 & 128.47 \\ + \hline 3072 & 138.73 \\ + \hline 4096 & 156.49 \\ + \hline +\end{tabular} +\end{center} + +The work factor for ECC keys is much higher since the best attack is still fully exponentional. Given a key of magnitude +$n$ it requires $\sqrt n$ work. The following table sumarizes the work required: +\begin{center} +\begin{tabular}{|c|c|} + \hline ECC Key Size (bits) & Work Factor ($log_2$) \\ + \hline 160 & 80 \\ + \hline 192 & 96 \\ + \hline 224 & 112 \\ + \hline 256 & 128 \\ + \hline 384 & 192 \\ + \hline 521 & 260.5 \\ + \hline +\end{tabular} +\end{center} + +Using the above tables the following suggestions for key sizes seems appropriate: +\begin{center} +\begin{tabular}{|c|c|c|} + \hline Security Goal & RSA/DH Key Size (bits) & ECC Key Size (bits) \\ + \hline Short term (less than a year) & 1024 & 160 \\ + \hline Short term (less than five years) & 1536 & 192 \\ + \hline Long Term (less than ten years) & 2560 & 256 \\ + \hline +\end{tabular} +\end{center} + +\section{Thread Safety} +The library is not thread safe but several simple precautions can be taken to avoid any problems. The registry functions +such as register\_cipher() are not thread safe no matter what you do. Its best to call them from your programs initializtion +code before threads are initiated. + +The rest of the code uses state variables you must pass it such as hash\_state, hmac\_state, etc. This means that if each +thread has its own state variables then they will not affect each other. This is fairly simple with symmetric ciphers +and hashes. However, the keyring and PRNG support is something the threads will want to share. The simplest workaround +is create semaphores or mutexes around calls to those functions. + +Since C does not have standard semaphores this support is not native to Libtomcrypt. Even a C based semaphore is not entire +possible as some compilers may ignore the ``volatile'' keyword or have multiple processors. Provide your host application +is modular enough putting the locks in the right place should not bloat the code significantly and will solve all thread +safety issues within the library. + +\chapter{Configuring the Library} +\section{Introduction} +The library is fairly flexible about how it can be built, used and generally distributed. Additions are being made with +each new release that will make the library even more flexible. Most options are placed in the makefile and others +are in ``mycrypt\_cfg.h''. All are used when the library is built from scratch. + +For GCC platforms the file ``makefile'' is the makefile to be used. On MSVC platforms ``makefile.vc'' and on PS2 platforms +``makefile.ps2''. + +\section{mycrypt\_cfg.h} +The file ``mycrypt\_cfg.h'' is what lets you control what functionality you want to remove from the library. By default, +everything the library has to offer it built. + +\subsubsection{ARGTYPE} +This lets you control how the \_ARGCHK macro will behave. The macro is used to check pointers inside the functions against +NULL. There are three settings for ARGTYPE. When set to 0 it will have the default behaviour of printing a message to +stderr and raising a SIGABRT signal. This is provided so all platforms that use libtomcrypt can have an error that functions +similarly. When set to 1 it will simply pass on to the assert() macro. When set to 2 it will resolve to a empty macro +and no error checking will be performed. + +\subsubsection{Endianess} +There are five macros related to endianess issues. For little endian platforms define, ENDIAN\_LITTLE. For big endian +platforms define ENDIAN\_BIG. Similarly when the default word size of an ``unsigned long'' is 32-bits define ENDIAN\_32BITWORD +or define ENDIAN\_64BITWORD when its 64-bits. If you do not define any of them the library will automatically use ENDIAN\_NEUTRAL +which will work on all platforms. Currently the system will automatically detect GCC or MSVC on a windows platform as well +as GCC on a PS2 platform. + +\section{The Configure Script} +There are also options you can specify from the configure script or ``mycrypt\_config.h''. + +\subsubsection{X memory routines} +The makefiles must define three macros denoted as XMALLOC, XCALLOC and XFREE which resolve to the name of the respective +functions. This lets you substitute in your own memory routines. If you substitute in your own functions they must behave +like the standard C library functions in terms of what they expect as input and output. By default the library uses the +standard C routines. + +\subsubsection{X clock routines} +The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override +the default clock() used with a replacement. By default the standard C library clock() function is used. + +\subsubsection{NO\_FILE} +During the build if NO\_FILE is defined then any function in the library that uses file I/O will not call the file I/O +functions and instead simply return CRYPT\_ERROR. This should help resolve any linker errors stemming from a lack of +file I/O on embedded platforms. + +\subsubsection{CLEAN\_STACK} +When this functions is defined the functions that store key material on the stack will clean up afterwards. Assumes that +you have no memory paging with the stack. + +\subsubsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions} +There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly self-explanatory. +When they are defined the functionality is included otherwise it is not. There are some dependency issues which are +noted in the file. For instance, Yarrow requires CTR chaining mode, a block cipher and a hash function. + +\subsubsection{TWOFISH\_SMALL and TWOFISH\_TABLES} +Twofish is a 128-bit symmetric block cipher that is provided within the library. The cipher itself is flexible enough +to allow some tradeoffs in the implementation. When TWOFISH\_SMALL is defined the scheduled symmetric key for Twofish +requires only 200 bytes of memory. This is achieved by not pre-computing the substitution boxes. Having this +defined will also greatly slow down the cipher. When this macro is not defined Twofish will pre-compute the +tables at a cost of 4KB of memory. The cipher will be much faster as a result. + +When TWOFISH\_TABLES is defined the cipher will use pre-computed (and fixed in code) tables required to work. This is +useful when TWOFISH\_SMALL is defined as the table values are computed on the fly. When this is defined the code size +will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL is not the cipher will still work but +it will not speed up the encryption or decryption functions. + +\subsubsection{SMALL\_CODE} +When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants. +These variants are slower but can save quite a bit of code space. + +\end{document}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_argchk.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,21 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" +#include <signal.h> + +#if (ARGTYPE == 0) +void crypt_argchk(char *v, char *s, int d) +{ + fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); + (void)raise(SIGABRT); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_cipher_descriptor.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,18 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +struct _cipher_descriptor cipher_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_cipher_is_valid.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,19 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int cipher_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) { + return CRYPT_INVALID_CIPHER; + } + return CRYPT_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_cipher.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,24 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int find_cipher(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) { + return x; + } + } + return -1; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_cipher_any.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,32 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* idea from Wayne Scott */ +int find_cipher_any(const char *name, int blocklen, int keylen) +{ + int x; + + _ARGCHK(name != NULL); + + x = find_cipher(name); + if (x != -1) return x; + + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + continue; + } + if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { + return x; + } + } + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_cipher_id.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,22 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int find_cipher_id(unsigned char ID) +{ + int x; + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].ID == ID) { + return (cipher_descriptor[x].name == NULL) ? -1 : x; + } + } + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_hash.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,23 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int find_hash(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) { + return x; + } + } + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_hash_any.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* return first hash with at least [amount over] digestlen bytes of output */ +int find_hash_any(const char *name, int digestlen) +{ + int x, y, z; + _ARGCHK(name != NULL); + + x = find_hash(name); + if (x != -1) return x; + + y = MAXBLOCKSIZE+1; + z = -1; + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + continue; + } + if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) { + z = x; + y = hash_descriptor[x].hashsize; + } + } + return z; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_hash_id.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,22 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int find_hash_id(unsigned char ID) +{ + int x; + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].ID == ID) { + return (hash_descriptor[x].name == NULL) ? -1 : x; + } + } + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_find_prng.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,24 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int find_prng(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) { + return x; + } + } + return -1; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_hash_descriptor.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,17 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +struct _hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_hash_is_valid.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,19 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int hash_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { + return CRYPT_INVALID_HASH; + } + return CRYPT_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_prng_descriptor.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,18 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +struct _prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL } }; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_prng_is_valid.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,19 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int prng_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { + return CRYPT_INVALID_PRNG; + } + return CRYPT_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_register_cipher.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int register_cipher(const struct _cipher_descriptor *cipher) +{ + int x; + + _ARGCHK(cipher != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_register_hash.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int register_hash(const struct _hash_descriptor *hash) +{ + int x; + + _ARGCHK(hash != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_register_prng.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int register_prng(const struct _prng_descriptor *prng) +{ + int x; + + _ARGCHK(prng != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) == 0) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (prng_descriptor[x].name == NULL) { + memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_unregister_cipher.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,28 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int unregister_cipher(const struct _cipher_descriptor *cipher) +{ + int x; + + _ARGCHK(cipher != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)) == 0) { + cipher_descriptor[x].name = NULL; + cipher_descriptor[x].ID = 255; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_unregister_hash.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int unregister_hash(const struct _hash_descriptor *hash) +{ + int x; + + _ARGCHK(hash != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) { + hash_descriptor[x].name = NULL; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypt_unregister_prng.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int unregister_prng(const struct _prng_descriptor *prng) +{ + int x; + + _ARGCHK(prng != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) != 0) { + prng_descriptor[x].name = NULL; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ctr_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,25 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CTR + +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) +{ + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ctr != NULL); + + return ctr_encrypt(ct, pt, len, ctr); +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ctr_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,64 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CTR + +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +{ + int x, err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ctr->blocklen < 0 || ctr->blocklen > (int)sizeof(ctr->ctr) || + ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + /* is the pad empty? */ + if (ctr->padlen == ctr->blocklen) { + /* increment counter */ + if (ctr->mode == 0) { + /* little-endian */ + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } else { + /* big-endian */ + for (x = ctr->blocklen-1; x >= 0; x--) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } + + /* encrypt it */ + cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); + ctr->padlen = 0; + } + *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ctr_start.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef CTR + +int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen, + int num_rounds, symmetric_CTR *ctr) +{ + int x, err; + + _ARGCHK(count != NULL); + _ARGCHK(key != NULL); + _ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { + return err; + } + + /* copy ctr */ + ctr->blocklen = cipher_descriptor[cipher].block_length; + ctr->cipher = cipher; + ctr->padlen = 0; + ctr->mode = 0; + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = count[x]; + } + cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,231 @@ +/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */ +/* File de/encryption, using libtomcrypt */ +/* Written by Daniel Richards <[email protected]> */ +/* Help from Tom St Denis with various bits */ +/* This code is public domain, no rights reserved. */ +/* Encrypts by default, -d flag enables decryption */ +/* ie: ./encrypt blowfish story.txt story.ct */ +/* ./encrypt -d blowfish story.ct story.pt */ + +#include <mycrypt.h> + +int errno; + +int usage(char *name) +{ + int x; + + printf("Usage: %s [-d](ecrypt) cipher infile outfile\nCiphers:\n", name); + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + printf("%s\n",cipher_descriptor[x].name); + } + exit(1); +} + +void register_algs(void) +{ + int x; + +#ifdef RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef XTEA + register_cipher (&xtea_desc); +#endif +#ifdef RC5 + register_cipher (&rc5_desc); +#endif +#ifdef RC6 + register_cipher (&rc6_desc); +#endif +#ifdef SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef RC2 + register_cipher (&rc2_desc); +#endif +#ifdef DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef SKIPJACK + register_cipher (&skipjack_desc); +#endif + + if (register_hash(&sha256_desc) == -1) { + printf("Error registering SHA256\n"); + exit(-1); + } + + if (register_prng(&yarrow_desc) == -1) { + printf("Error registering yarrow PRNG\n"); + exit(-1); + } + + if (register_prng(&sprng_desc) == -1) { + printf("Error registering sprng PRNG\n"); + exit(-1); + } +} + +int main(int argc, char *argv[]) +{ + unsigned char plaintext[512],ciphertext[512]; + unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; + unsigned char inbuf[512]; /* i/o block size */ + unsigned long outlen, y, ivsize, x, decrypt; + symmetric_CTR ctr; + int cipher_idx, hash_idx, ks; + char *infile, *outfile, *cipher; + prng_state prng; + FILE *fdin, *fdout; + + /* register algs, so they can be printed */ + register_algs(); + + if (argc < 4) { + return usage(argv[0]); + } + + if (!strcmp(argv[1], "-d")) { + decrypt = 1; + cipher = argv[2]; + infile = argv[3]; + outfile = argv[4]; + } else { + decrypt = 0; + cipher = argv[1]; + infile = argv[2]; + outfile = argv[3]; + } + + /* file handles setup */ + fdin = fopen(infile,"rb"); + if (fdin == NULL) { + perror("Can't open input for reading"); + exit(-1); + } + + fdout = fopen(outfile,"wb"); + if (fdout == NULL) { + perror("Can't open output for writing"); + exit(-1); + } + + cipher_idx = find_cipher(cipher); + if (cipher_idx == -1) { + printf("Invalid cipher entered on command line.\n"); + exit(-1); + } + + hash_idx = find_hash("sha256"); + if (hash_idx == -1) { + printf("SHA256 not found...?\n"); + exit(-1); + } + + ivsize = cipher_descriptor[cipher_idx].block_length; + ks = hash_descriptor[hash_idx].hashsize; + if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { + printf("Invalid keysize???\n"); + exit(-1); + } + + printf("\nEnter key: "); + fgets((char *)tmpkey,sizeof(tmpkey), stdin); + outlen = sizeof(key); + if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { + printf("Error hashing key: %s\n", error_to_string(errno)); + exit(-1); + } + + if (decrypt) { + /* Need to read in IV */ + if (fread(IV,1,ivsize,fdin) != ivsize) { + printf("Error reading IV from input.\n"); + exit(-1); + } + + if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) { + printf("ctr_start error: %s\n",error_to_string(errno)); + exit(-1); + } + + /* IV done */ + do { + y = fread(inbuf,1,sizeof(inbuf),fdin); + + if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { + printf("ctr_decrypt error: %s\n", error_to_string(errno)); + exit(-1); + } + + if (fwrite(plaintext,1,y,fdout) != y) { + printf("Error writing to file.\n"); + exit(-1); + } + } while (y == sizeof(inbuf)); + fclose(fdin); + fclose(fdout); + + } else { /* encrypt */ + /* Setup yarrow for random bytes for IV */ + + if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { + printf("Error setting up PRNG, %s\n", error_to_string(errno)); + } + + /* You can use rng_get_bytes on platforms that support it */ + /* x = rng_get_bytes(IV,ivsize,NULL);*/ + x = yarrow_read(IV,ivsize,&prng); + if (x != ivsize) { + printf("Error reading PRNG for IV required.\n"); + exit(-1); + } + + if (fwrite(IV,1,ivsize,fdout) != ivsize) { + printf("Error writing IV to output.\n"); + exit(-1); + } + + if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) { + printf("ctr_start error: %s\n",error_to_string(errno)); + exit(-1); + } + + do { + y = fread(inbuf,1,sizeof(inbuf),fdin); + + if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) { + printf("ctr_encrypt error: %s\n", error_to_string(errno)); + exit(-1); + } + + if (fwrite(ciphertext,1,y,fdout) != y) { + printf("Error writing to output.\n"); + exit(-1); + } + } while (y == sizeof(inbuf)); + fclose(fdout); + fclose(fdin); + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/hashsum.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,106 @@ +/* + * Written by Daniel Richards <[email protected]> 6/7/2002 + * hash.c: This app uses libtomcrypt to hash either stdin or a file + * This file is Public Domain. No rights are reserved. + * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt' + * This example isn't really big enough to warrent splitting into + * more functions ;) +*/ + +#include <mycrypt_custom.h> + +int errno; + +void register_algs(); + +int main(int argc, char **argv) +{ + int idx, x, z; + unsigned long w; + unsigned char hash_buffer[MAXBLOCKSIZE]; + hash_state md; + + /* You need to register algorithms before using them */ + register_algs(); + if (argc < 2) { + printf("usage: ./hash algorithm file [file ...]\n"); + printf("Algorithms:\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + printf(" %s\n", hash_descriptor[x].name); + } + exit(EXIT_SUCCESS); + } + + idx = find_hash(argv[1]); + if (idx == -1) { + fprintf(stderr, "\nInvalid hash specified on command line.\n"); + return -1; + } + + if (argc == 2) { + hash_descriptor[idx].init(&md); + do { + x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin); + hash_descriptor[idx].process(&md, hash_buffer, x); + } while (x == sizeof(hash_buffer)); + hash_descriptor[idx].done(&md, hash_buffer); + for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { + printf("%02x",hash_buffer[x]); + } + printf(" (stdin)\n"); + } else { + for (z = 2; z < argc; z++) { + w = sizeof(hash_buffer); + if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { + printf("File hash error: %s\n", error_to_string(errno)); + } else { + for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { + printf("%02x",hash_buffer[x]); + } + printf(" %s\n", argv[z]); + } + } + } + return EXIT_SUCCESS; +} + +void register_algs(void) +{ +#ifdef TIGER + register_hash (&tiger_desc); +#endif +#ifdef MD2 + register_hash (&md2_desc); +#endif +#ifdef MD4 + register_hash (&md4_desc); +#endif +#ifdef MD5 + register_hash (&md5_desc); +#endif +#ifdef SHA1 + register_hash (&sha1_desc); +#endif +#ifdef SHA224 + register_hash (&sha224_desc); +#endif +#ifdef SHA256 + register_hash (&sha256_desc); +#endif +#ifdef SHA384 + register_hash (&sha384_desc); +#endif +#ifdef SHA512 + register_hash (&sha512_desc); +#endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef WHIRLPOOL + register_hash (&whirlpool_desc); +#endif + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/small.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,11 @@ +// small demo app that just includes a cipher/hash/prng + +#include <mycrypt.h> + +int main(void) +{ + register_cipher(&rijndael_desc); + register_prng(&yarrow_desc); + register_hash(&sha256_desc); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1982 @@ +/* This is the worst code you have ever seen written on purpose.... this code is just a big hack to test +out the functionality of the library */ + +#ifdef SONY_PS2 +#include <eetypes.h> +#include <eeregs.h> +#include "timer.h" +#endif + +#include <mycrypt.h> + +int errnum; + + +int +null_setup (const unsigned char *key, int keylen, int num_rounds, + symmetric_key * skey) +{ + return CRYPT_OK; +} + +void +null_ecb_encrypt (const unsigned char *pt, unsigned char *ct, + symmetric_key * key) +{ + memcpy (ct, pt, 8); +} + +void +null_ecb_decrypt (const unsigned char *ct, unsigned char *pt, + symmetric_key * key) +{ + memcpy (pt, ct, 8); +} + +int +null_test (void) +{ + return CRYPT_OK; +} + +int +null_keysize (int *desired_keysize) +{ + return CRYPT_OK; +} + +const struct _cipher_descriptor null_desc = { + "memcpy()", + 255, + 8, 8, 8, 1, + &null_setup, + &null_ecb_encrypt, + &null_ecb_decrypt, + &null_test, + &null_keysize +}; + + +prng_state prng; + +void +store_tests (void) +{ + unsigned char buf[8]; + unsigned long L; + ulong64 LL; + + printf ("LOAD32/STORE32 tests\n"); + L = 0x12345678UL; + STORE32L (L, &buf[0]); + L = 0; + LOAD32L (L, &buf[0]); + if (L != 0x12345678UL) { + printf ("LOAD/STORE32 Little don't work\n"); + exit (-1); + } + LL = CONST64 (0x01020304050607); + STORE64L (LL, &buf[0]); + LL = 0; + LOAD64L (LL, &buf[0]) + if (LL != CONST64 (0x01020304050607)) { + printf ("LOAD/STORE64 Little don't work\n"); + exit (-1); + } + + L = 0x12345678UL; + STORE32H (L, &buf[0]); + L = 0; + LOAD32H (L, &buf[0]); + if (L != 0x12345678UL) { + printf ("LOAD/STORE32 High don't work, %08lx\n", L); + exit (-1); + } + LL = CONST64 (0x01020304050607); + STORE64H (LL, &buf[0]); + LL = 0; + LOAD64H (LL, &buf[0]) + if (LL != CONST64 (0x01020304050607)) { + printf ("LOAD/STORE64 High don't work\n"); + exit (-1); + } +} + +void +cipher_tests (void) +{ + int x; + + printf ("Ciphers compiled in\n"); + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + printf + (" %12s (%2d) Key Size: %4d to %4d, Block Size: %3d, Default # of rounds: %2d\n", + cipher_descriptor[x].name, cipher_descriptor[x].ID, + cipher_descriptor[x].min_key_length * 8, + cipher_descriptor[x].max_key_length * 8, + cipher_descriptor[x].block_length * 8, + cipher_descriptor[x].default_rounds); + } + +} + +void +ecb_tests (void) +{ + int x; + + printf ("ECB tests\n"); + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + printf (" %12s: ", cipher_descriptor[x].name); + if ((errnum = cipher_descriptor[x].test ()) != CRYPT_OK) { + printf (" **failed** Reason: %s\n", error_to_string (errnum)); + exit (-1); + } else { + printf ("passed\n"); + } + } +} + +#ifdef CBC +void +cbc_tests (void) +{ + symmetric_CBC cbc; + int x, y; + unsigned char blk[32], ct[32], key[32], IV[32]; + const unsigned char test[] = + { 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + printf ("CBC tests\n"); + /* ---- CBC ENCODING ---- */ + /* make up a block and IV */ + for (x = 0; x < 32; x++) + blk[x] = IV[x] = x; + + /* now lets start a cbc session */ + if ((errnum = + cbc_start (find_cipher ("blowfish"), IV, key, 16, 0, + &cbc)) != CRYPT_OK) { + printf ("CBC Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets encode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = cbc_encrypt (blk + 8 * x, ct + 8 * x, &cbc)) != CRYPT_OK) { + printf ("CBC encrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + zeromem (blk, sizeof (blk)); + + /* ---- CBC DECODING ---- */ + /* make up a IV */ + for (x = 0; x < 32; x++) + IV[x] = x; + + /* now lets start a cbc session */ + if ((errnum = + cbc_start (find_cipher ("blowfish"), IV, key, 16, 0, + &cbc)) != CRYPT_OK) { + printf ("CBC Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets decode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = cbc_decrypt (ct + 8 * x, blk + 8 * x, &cbc)) != CRYPT_OK) { + printf ("CBC decrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + + /* print output */ + for (x = y = 0; x < 32; x++) + if (blk[x] != x) + y = 1; + printf (" %s\n", y ? "failed" : "passed"); + + /* lets actually check the bytes */ + memset (IV, 0, 8); + IV[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */ + memset (blk, 0, 32); + blk[8] = 0xFF; /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */ + cbc_start (find_cipher ("memcpy()"), IV, key, 8, 0, &cbc); + cbc_encrypt (blk, ct, &cbc); /* expect: FF 00 00 00 00 00 00 00 */ + cbc_encrypt (blk + 8, ct + 8, &cbc); /* expect: 00 00 00 00 00 00 00 00 */ + if (memcmp (ct, test, 16)) { + printf ("CBC failed logical testing.\n"); + for (x = 0; x < 16; x++) + printf ("%02x ", ct[x]); + printf ("\n"); + exit (-1); + } else { + printf ("CBC passed logical testing.\n"); + } +} +#else +void +cbc_tests (void) +{ + printf ("CBC not compiled in\n"); +} +#endif + +#ifdef OFB +void +ofb_tests (void) +{ + symmetric_OFB ofb; + int x, y; + unsigned char blk[32], ct[32], key[32], IV[32]; + + printf ("OFB tests\n"); + /* ---- ofb ENCODING ---- */ + /* make up a block and IV */ + for (x = 0; x < 32; x++) + blk[x] = IV[x] = x; + + /* now lets start a ofb session */ + if ((errnum = + ofb_start (find_cipher ("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) { + printf ("OFB Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets encode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = ofb_encrypt (blk + 8 * x, ct + 8 * x, 8, &ofb)) != CRYPT_OK) { + printf ("OFB encrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + zeromem (blk, sizeof (blk)); + + /* ---- ofb DECODING ---- */ + /* make up a IV */ + for (x = 0; x < 32; x++) + IV[x] = x; + + /* now lets start a ofb session */ + if ((errnum = + ofb_start (find_cipher ("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) { + printf ("OFB setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets decode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = ofb_decrypt (ct + 8 * x, blk + 8 * x, 8, &ofb)) != CRYPT_OK) { + printf ("OFB decrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + /* print output */ + for (x = y = 0; x < 32; x++) + if (blk[x] != x) + y = 1; + printf (" %s\n", y ? "failed" : "passed"); + if (y) + exit (-1); +} +#else +void +ofb_tests (void) +{ + printf ("OFB not compiled in\n"); +} +#endif + +#ifdef CFB +void +cfb_tests (void) +{ + symmetric_CFB cfb; + int x, y; + unsigned char blk[32], ct[32], key[32], IV[32]; + + printf ("CFB tests\n"); + /* ---- cfb ENCODING ---- */ + /* make up a block and IV */ + for (x = 0; x < 32; x++) + blk[x] = IV[x] = x; + + /* now lets start a cfb session */ + if ((errnum = + cfb_start (find_cipher ("blowfish"), IV, key, 16, 0, + &cfb)) != CRYPT_OK) { + printf ("CFB setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets encode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = cfb_encrypt (blk + 8 * x, ct + 8 * x, 8, &cfb)) != CRYPT_OK) { + printf ("CFB encrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + zeromem (blk, sizeof (blk)); + + /* ---- cfb DECODING ---- */ + /* make up ahash_descriptor[prng->yarrow.hash].hashsize IV */ + for (x = 0; x < 32; x++) + IV[x] = x; + + /* now lets start a cfb session */ + if ((errnum = + cfb_start (find_cipher ("blowfish"), IV, key, 16, 0, + &cfb)) != CRYPT_OK) { + printf ("CFB Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets decode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = cfb_decrypt (ct + 8 * x, blk + 8 * x, 8, &cfb)) != CRYPT_OK) { + printf ("CFB decrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + /* print output */ + for (x = y = 0; x < 32; x++) + if (blk[x] != x) + y = 1; + printf (" %s\n", y ? "failed" : "passed"); + if (y) + exit (-1); +} +#else +void +cfb_tests (void) +{ + printf ("CFB not compiled in\n"); +} +#endif + +#ifdef CTR +void +ctr_tests (void) +{ + symmetric_CTR ctr; + int x, y; + unsigned char blk[32], ct[32], key[32], count[32]; + const unsigned char test[] = + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 }; + + printf ("CTR tests\n"); + /* ---- CTR ENCODING ---- */ + /* make up a block and IV */ + for (x = 0; x < 32; x++) + blk[x] = count[x] = x; + + /* now lets start a ctr session */ + if ((errnum = + ctr_start (find_cipher ("xtea"), count, key, 16, 0, + &ctr)) != CRYPT_OK) { + printf ("CTR Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets encode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = ctr_encrypt (blk + 8 * x, ct + 8 * x, 8, &ctr)) != CRYPT_OK) { + printf ("CTR encrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + zeromem (blk, sizeof (blk)); + + /* ---- CTR DECODING ---- */ + /* make up a IV */ + for (x = 0; x < 32; x++) + count[x] = x; + + /* now lets start a cbc session */ + if ((errnum = + ctr_start (find_cipher ("xtea"), count, key, 16, 0, + &ctr)) != CRYPT_OK) { + printf ("CTR Setup: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* now lets decode 32 bytes */ + for (x = 0; x < 4; x++) { + if ((errnum = ctr_decrypt (ct + 8 * x, blk + 8 * x, 8, &ctr)) != CRYPT_OK) { + printf ("CTR decrypt: %s\n", error_to_string (errnum)); + exit (-1); + } + } + + /* print output */ + for (x = y = 0; x < 32; x++) + if (blk[x] != x) + y = 1; + printf (" %s\n", y ? "failed" : "passed"); + if (y) + exit (-1); + + /* lets actually check the bytes */ + memset (count, 0, 8); + count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */ + memset (blk, 0, 32); + blk[9] = 2; /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */ + ctr_start (find_cipher ("memcpy()"), count, key, 8, 0, &ctr); + ctr_encrypt (blk, ct, 8, &ctr); /* expect: FF 00 00 00 00 00 00 00 */ + ctr_encrypt (blk + 8, ct + 8, 8, &ctr); /* expect: 00 03 00 00 00 00 00 00 */ + if (memcmp (ct, test, 16)) { + printf ("CTR failed logical testing.\n"); + for (x = 0; x < 16; x++) + printf ("%02x ", ct[x]); + printf ("\n"); + } else { + printf ("CTR passed logical testing.\n"); + } + +} +#else +void +ctr_tests (void) +{ + printf ("CTR not compiled in\n"); +} +#endif + +void +hash_tests (void) +{ + int x; + printf ("Hash tests\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + printf (" %10s (%2d) ", hash_descriptor[x].name, hash_descriptor[x].ID); + if ((errnum = hash_descriptor[x].test ()) != CRYPT_OK) { + printf ("**failed** Reason: %s\n", error_to_string (errnum)); + exit(-1); + } else { + printf ("passed\n"); + } + } +} + +#ifdef MRSA +void +pad_test (void) +{ + unsigned char in[100], out[100]; + unsigned long x, y; + + /* make a dummy message */ + for (x = 0; x < 16; x++) + in[x] = (unsigned char) x; + + /* pad the message so that random filler is placed before and after it */ + y = 100; + if ((errnum = + rsa_pad (in, 16, out, &y, find_prng ("yarrow"), &prng)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* depad the message to get the original content */ + memset (in, 0, sizeof (in)); + x = 100; + if ((errnum = rsa_depad (out, y, in, &x)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* check outcome */ + printf ("rsa_pad: "); + if (x != 16) { + printf ("Failed. Wrong size.\n"); + exit (-1); + } + for (x = 0; x < 16; x++) + if (in[x] != x) { + printf ("Failed. Expected %02lx and got %02x.\n", x, in[x]); + exit (-1); + } + printf ("passed.\n"); +} +void +rsa_test (void) +{ + unsigned char in[520], out[520]; + unsigned long x, y, z, limit; + int stat; + rsa_key key; + clock_t t; + + /* ---- SINGLE ENCRYPT ---- */ + /* encrypt a short 8 byte string */ + if ((errnum = + rsa_make_key (&prng, find_prng ("yarrow"), 1024 / 8, 65537, + &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + for (x = 0; x < 8; x++) + in[x] = (unsigned char) (x + 1); + y = sizeof (in); + if ((errnum = rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* decrypt it */ + zeromem (in, sizeof (in)); + x = sizeof (out); + if ((errnum = rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* compare */ + printf ("RSA : "); + for (x = 0; x < 8; x++) + if (in[x] != (x + 1)) { + printf ("Failed. x==%02lx, in[%ld]==%02x\n", x, x, in[x]); + exit (-1); + } + printf ("passed.\n"); + + /* test the rsa_encrypt_key functions */ + for (x = 0; x < 16; x++) + in[x] = x; + y = sizeof (out); + if ((errnum = + rsa_encrypt_key (in, 16, out, &y, &prng, find_prng ("yarrow"), + &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + zeromem (in, sizeof (in)); + x = sizeof (in); + if ((errnum = rsa_decrypt_key (out, y, in, &x, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("RSA en/de crypt key routines: "); + if (x != 16) { + printf ("Failed (length)\n"); + exit (-1); + } + for (x = 0; x < 16; x++) + if (in[x] != x) { + printf ("Failed (contents)\n"); + exit (-1); + } + printf ("Passed\n"); + + /* test sign_hash functions */ + for (x = 0; x < 16; x++) + in[x] = x; + x = sizeof (in); + if ((errnum = rsa_sign_hash (in, 16, out, &x, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("RSA signed hash: %lu bytes\n", x); + if ((errnum = rsa_verify_hash (out, x, in, &stat, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("Verify hash: %s, ", stat ? "passed" : "failed"); + in[0] ^= 1; + if ((errnum = rsa_verify_hash (out, x, in, &stat, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("%s\n", (!stat) ? "passed" : "failed"); + if (stat) + exit (-1); + rsa_free (&key); + + /* make a RSA key */ +#ifdef SONY_PS2_NOPE + limit = 1024; +#else + limit = 2048; +#endif + + { + int tt; + + for (z = 1024; z <= limit; z += 512) { + t = XCLOCK (); + for (tt = 0; tt < 3; tt++) { + if ((errnum = rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* check modulus size */ + if (mp_unsigned_bin_size(&key.N) != (int)(z/8)) { + printf("\nRSA key supposed to be %lu bits but was %d bits\n", z, mp_count_bits(&key.N)); + exit(EXIT_FAILURE); + } + + if (tt < 2) { + rsa_free (&key); + } + } + t = XCLOCK () - t; + printf ("Took %.0f ms to make a %ld-bit RSA key.\n", 1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z); + + /* time encryption */ + t = XCLOCK (); + + for (tt = 0; tt < 20; tt++) { + y = sizeof (in); + if ((errnum = rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + } + t = XCLOCK () - t; + printf ("Took %.0f ms to encrypt with a %ld-bit RSA key.\n", + 1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z); + + /* time decryption */ + t = XCLOCK (); + for (tt = 0; tt < 20; tt++) { + x = sizeof (out); + if ((errnum = rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + } + t = XCLOCK () - t; + printf ("Took %.0f ms to decrypt with a %ld-bit RSA key.\n", + 1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z); + rsa_free (&key); + } + } +} +#else +void +pad_test (void) +{ + printf ("MRSA not compiled in\n"); +} + +void +rsa_test (void) +{ + printf ("MRSA not compiled in\n"); +} +#endif + +#ifdef BASE64 +void +base64_test (void) +{ + unsigned char buf[2][100]; + unsigned long x, y; + + printf ("Base64 tests\n"); + zeromem (buf, sizeof (buf)); + for (x = 0; x < 16; x++) + buf[0][x] = (unsigned char) x; + + x = 100; + if (base64_encode (buf[0], 16, buf[1], &x) != CRYPT_OK) { + printf (" error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf (" encoded 16 bytes to %ld bytes...[%s]\n", x, buf[1]); + memset (buf[0], 0, 100); + y = 100; + if (base64_decode (buf[1], x, buf[0], &y) != CRYPT_OK) { + printf (" error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf (" decoded %ld bytes to %ld bytes\n", x, y); + for (x = 0; x < 16; x++) + if (buf[0][x] != x) { + printf (" **failed**\n"); + exit (-1); + } + printf (" passed\n"); +} +#else +void +base64_test (void) +{ + printf ("Base64 not compiled in\n"); +} +#endif + +void +time_hash (void) +{ + clock_t t1; + int x, y; + unsigned long z; + unsigned char input[4096], out[MAXBLOCKSIZE]; + printf ("Hash Time Trials (4KB blocks):\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + t1 = XCLOCK (); + z = sizeof (out); + y = 0; + while (XCLOCK () - t1 < (5 * XCLOCKS_PER_SEC)) { + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + hash_memory (x, input, 4096, out, &z); + y += 32; + } + t1 = XCLOCK () - t1; + printf ("%-20s: Hash at %5.2f Mbit/sec\n", hash_descriptor[x].name, + ((8.0 * 4096.0) * + ((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) / + 1000000.0); + } +} + +void +time_ecb (void) +{ + clock_t t1, t2; + long x, y1, y2; + unsigned char pt[32], key[32]; + symmetric_key skey; + void (*func) (const unsigned char *, unsigned char *, symmetric_key *); + + printf ("ECB Time Trials for the Symmetric Ciphers:\n"); + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0, + &skey); + +#define DO1 func(pt,pt,&skey); +#define DO2 DO1 DO1 +#define DO4 DO2 DO2 +#define DO8 DO4 DO4 +#define DO16 DO8 DO8 +#define DO32 DO16 DO16 +#define DO64 DO32 DO32 +#define DO128 DO64 DO64 +#define DO256 DO128 DO128 + + func = cipher_descriptor[x].ecb_encrypt; + y1 = 0; + t1 = XCLOCK (); + while (XCLOCK () - t1 < 3 * XCLOCKS_PER_SEC) { + DO256; + y1 += 256; + } + t1 = XCLOCK () - t1; + + func = cipher_descriptor[x].ecb_decrypt; + y2 = 0; + t2 = XCLOCK (); + while (XCLOCK () - t2 < 3 * XCLOCKS_PER_SEC) { + DO256; + y2 += 256; + } + t2 = XCLOCK () - t2; + printf + ("%-20s: Encrypt at %5.2f Mbit/sec and Decrypt at %5.2f Mbit/sec\n", + cipher_descriptor[x].name, + ((8.0 * (double) cipher_descriptor[x].block_length) * + ((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0, + ((8.0 * (double) cipher_descriptor[x].block_length) * + ((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) / + 1000000.0); + +#undef DO256 +#undef DO128 +#undef DO64 +#undef DO32 +#undef DO16 +#undef DO8 +#undef DO4 +#undef DO2 +#undef DO1 + } +} + +#ifdef MDH +void +dh_tests (void) +{ + unsigned char buf[3][4096]; + unsigned long x, y, z; + int low, high, stat, stat2; + dh_key usera, userb; + clock_t t1; + + printf("Testing builting DH parameters...."); fflush(stdout); + if ((errnum = dh_test()) != CRYPT_OK) { + printf("DH Error: %s\n", error_to_string(errnum)); + exit(-1); + } + printf("Passed.\n"); + + dh_sizes (&low, &high); + printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8); + + /* make up two keys */ + if ((errnum = + dh_make_key (&prng, find_prng ("yarrow"), 96, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + if ((errnum = + dh_make_key (&prng, find_prng ("yarrow"), 96, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* make the shared secret */ + x = 4096; + if ((errnum = dh_shared_secret (&usera, &userb, buf[0], &x)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + y = 4096; + if ((errnum = dh_shared_secret (&userb, &usera, buf[1], &y)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + if (y != x) { + printf ("DH Shared keys are not same size.\n"); + exit (-1); + } + if (memcmp (buf[0], buf[1], x)) { + printf ("DH Shared keys not same contents.\n"); + exit (-1); + } + + /* now export userb */ + y = 4096; + if ((errnum = dh_export (buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + dh_free (&userb); + + /* import and make the shared secret again */ + if ((errnum = dh_import (buf[1], y, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + z = 4096; + if ((errnum = dh_shared_secret (&usera, &userb, buf[2], &z)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + printf ("DH routines: "); + if (z != x) { + printf ("failed. Size don't match?\n"); + exit (-1); + } + if (memcmp (buf[0], buf[2], x)) { + printf ("Failed. Content didn't match.\n"); + exit (-1); + } + printf ("Passed\n"); + dh_free (&usera); + dh_free (&userb); + +/* time stuff */ + { + static int sizes[] = { 96, 128, 160, 192, 224, 256, 320, 384, 512 }; + int ii, tt; + + for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) { + t1 = XCLOCK (); + for (tt = 0; tt < 25; tt++) { + dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera); + dh_free (&usera); + } + t1 = XCLOCK () - t1; + printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8, + 1000.0 * (((double) t1 / 25.0) / (double) XCLOCKS_PER_SEC)); + } + } + +/* test encrypt_key */ + dh_make_key (&prng, find_prng ("yarrow"), 128, &usera); + for (x = 0; x < 16; x++) + buf[0][x] = x; + y = sizeof (buf[1]); + if ((errnum = + dh_encrypt_key (buf[0], 16, buf[1], &y, &prng, find_prng ("yarrow"), + find_hash ("md5"), &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + zeromem (buf[0], sizeof (buf[0])); + x = sizeof (buf[0]); + if ((errnum = dh_decrypt_key (buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("DH en/de crypt key routines: "); + if (x != 16) { + printf ("Failed (length)\n"); + exit (-1); + } + for (x = 0; x < 16; x++) + if (buf[0][x] != x) { + printf ("Failed (contents)\n"); + exit (-1); + } + printf ("Passed (size %lu)\n", y); + +/* test sign_hash */ + for (x = 0; x < 16; x++) + buf[0][x] = x; + x = sizeof (buf[1]); + if ((errnum = + dh_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"), + &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + if ((errnum = dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + buf[0][0] ^= 1; + if ((errnum = dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("dh_sign/verify_hash: %s (%d,%d), %lu\n", + ((stat == 1) + && (stat2 == 0)) ? "passed" : "failed", stat, stat2, x); + dh_free (&usera); +} +#else +void +dh_tests (void) +{ + printf ("MDH not compiled in\n"); +} +#endif + +int callback_x = 0; +void +callback (void) +{ + printf ("%c\x08", "-\\|/"[++callback_x & 3]); +#ifndef SONY_PS2 + fflush (stdout); +#endif +} + +void +rng_tests (void) +{ + unsigned char buf[16]; + clock_t t1; + int x, y; + + printf ("RNG tests\n"); + t1 = XCLOCK (); + x = rng_get_bytes (buf, sizeof (buf), &callback); + t1 = XCLOCK () - t1; + printf (" %f bytes per second...", + (double) x / ((double) t1 / (double) XCLOCKS_PER_SEC)); + printf ("read %d bytes.\n ", x); + for (y = 0; y < x; y++) + printf ("%02x ", buf[y]); + printf ("\n"); + +#ifdef YARROW + if ((errnum = + rng_make_prng (128, find_prng ("yarrow"), &prng, + &callback)) != CRYPT_OK) { + printf (" starting yarrow error: %s\n", error_to_string (errnum)); + exit (-1); + } +#endif +} + +#ifdef MECC +void +ecc_tests (void) +{ + unsigned char buf[4][4096]; + unsigned long x, y, z; + int stat, stat2, low, high; + ecc_key usera, userb; + clock_t t1; + + if ((errnum = ecc_test ()) != CRYPT_OK) { + printf ("ecc Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + ecc_sizes (&low, &high); + printf ("ecc Keys from %d to %d supported.\n", low * 8, high * 8); + + /* make up two keys */ + if ((errnum = + ecc_make_key (&prng, find_prng ("yarrow"), 24, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + if ((errnum = + ecc_make_key (&prng, find_prng ("yarrow"), 24, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* make the shared secret */ + x = 4096; + if ((errnum = ecc_shared_secret (&usera, &userb, buf[0], &x)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + y = 4096; + if ((errnum = ecc_shared_secret (&userb, &usera, buf[1], &y)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + if (y != x) { + printf ("ecc Shared keys are not same size.\n"); + exit (-1); + } + + if (memcmp (buf[0], buf[1], x)) { + printf ("ecc Shared keys not same contents.\n"); + exit (-1); + } + + /* now export userb */ + y = 4096; + if ((errnum = ecc_export (buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + ecc_free (&userb); + printf ("ECC-192 export took %ld bytes\n", y); + + /* import and make the shared secret again */ + if ((errnum = ecc_import (buf[1], y, &userb)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + z = 4096; + if ((errnum = ecc_shared_secret (&usera, &userb, buf[2], &z)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + + printf ("ecc routines: "); + if (z != x) { + printf ("failed. Size don't match?\n"); + exit (-1); + } + if (memcmp (buf[0], buf[2], x)) { + printf ("Failed. Content didn't match.\n"); + exit (-1); + } + printf ("Passed\n"); + ecc_free (&usera); + ecc_free (&userb); + +/* time stuff */ + { + static int sizes[] = { 20, 24, 28, 32, 48, 65 }; + int ii, tt; + + for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) { + t1 = XCLOCK (); + for (tt = 0; tt < 10; tt++) { + if ((errnum = + ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii], + &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + ecc_free (&usera); + } + t1 = XCLOCK () - t1; + printf ("Make ECC-%d key took %f msec\n", sizes[ii] * 8, + 1000.0 * (((double) t1 / 10.0) / (double) XCLOCKS_PER_SEC)); + } + } + +/* test encrypt_key */ + ecc_make_key (&prng, find_prng ("yarrow"), 20, &usera); + for (x = 0; x < 32; x++) + buf[0][x] = x; + y = sizeof (buf[1]); + if ((errnum = + ecc_encrypt_key (buf[0], 32, buf[1], &y, &prng, find_prng ("yarrow"), + find_hash ("sha256"), &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + zeromem (buf[0], sizeof (buf[0])); + x = sizeof (buf[0]); + if ((errnum = ecc_decrypt_key (buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("ECC en/de crypt key routines: "); + if (x != 32) { + printf ("Failed (length)\n"); + exit (-1); + } + for (x = 0; x < 32; x++) + if (buf[0][x] != x) { + printf ("Failed (contents)\n"); + exit (-1); + } + printf ("Passed (size: %lu)\n", y); +/* test sign_hash */ + for (x = 0; x < 16; x++) + buf[0][x] = x; + x = sizeof (buf[1]); + if ((errnum = + ecc_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"), + &usera)) != CRYPT_OK) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf("Signature size: %lu\n", x); + if (ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + buf[0][0] ^= 1; + if (ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)) { + printf ("Error: %s\n", error_to_string (errnum)); + exit (-1); + } + printf ("ecc_sign/verify_hash: %s (%d,%d)\n", + ((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2); + ecc_free (&usera); +} +#else +void +ecc_tests (void) +{ + printf ("MECC not compiled in\n"); +} +#endif + +#ifdef GF +void +gf_tests (void) +{ + gf_int a, b, c, d; + int n; + unsigned char buf[1024]; + + printf ("GF tests\n"); + gf_zero (a); + gf_zero (b); + gf_zero (c); + gf_zero (d); + + /* a == 0x18000000b */ + a[1] = 1; + a[0] = 0x8000000bUL; + + /* b == 0x012345678 */ + b[0] = 0x012345678UL; + + /* find 1/b mod a */ + gf_invmod (b, a, c); + + /* find 1/1/b mod a */ + gf_invmod (c, a, d); + + /* display them */ + printf (" %08lx %08lx\n", c[0], d[0]); + + /* store as binary string */ + n = gf_size (a); + printf (" a takes %d bytes\n", n); + gf_toraw (a, buf); + gf_readraw (a, buf, n); + printf (" a == %08lx%08lx\n", a[1], a[0]); + + /* primality testing */ + gf_zero (a); + a[0] = 0x169; + printf (" GF prime: %s, ", gf_is_prime (a) ? "passed" : "failed"); + a[0] = 0x168; + printf (" %s\n", gf_is_prime (a) ? "failed" : "passed"); + + /* test sqrt code */ + gf_zero (a); + a[1] = 0x00000001; + a[0] = 0x8000000bUL; + gf_zero (b); + b[0] = 0x12345678UL; + + gf_sqrt (b, a, c); + gf_mulmod (c, c, a, b); + printf (" (%08lx)^2 = %08lx (mod %08lx%08lx) \n", c[0], b[0], a[1], a[0]); +} +#else +void +gf_tests (void) +{ + printf ("GF not compiled in\n"); +} +#endif + +#ifdef MPI +void +test_prime (void) +{ + char buf[1024]; + mp_int a; + int x; + + /* make a 1024 bit prime */ + mp_init (&a); + rand_prime (&a, 128*8, &prng, find_prng ("yarrow")); + + /* dump it */ + mp_todecimal (&a, buf); + printf ("1024-bit prime:\n"); + for (x = 0; x < (int) strlen (buf);) { + printf ("%c", buf[x]); + if (!(++x % 60)) + printf ("\\ \n"); + } + printf ("\n\n"); + + mp_clear (&a); +} +#else +void +test_prime (void) +{ + printf ("MPI not compiled in\n"); +} +#endif + +void +register_all_algs (void) +{ +#ifdef RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef XTEA + register_cipher (&xtea_desc); +#endif +#ifdef RC5 + register_cipher (&rc5_desc); +#endif +#ifdef RC6 + register_cipher (&rc6_desc); +#endif +#ifdef SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef RC2 + register_cipher (&rc2_desc); +#endif +#ifdef DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef SKIPJACK + register_cipher (&skipjack_desc); +#endif + register_cipher (&null_desc); + +#ifdef TIGER + register_hash (&tiger_desc); +#endif +#ifdef MD2 + register_hash (&md2_desc); +#endif +#ifdef MD4 + register_hash (&md4_desc); +#endif +#ifdef MD5 + register_hash (&md5_desc); +#endif +#ifdef SHA1 + register_hash (&sha1_desc); +#endif +#ifdef SHA256 + register_hash (&sha256_desc); +#endif +#ifdef SHA224 + register_hash (&sha224_desc); +#endif +#ifdef SHA384 + register_hash (&sha384_desc); +#endif +#ifdef SHA512 + register_hash (&sha512_desc); +#endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef WHIRLPOOL + register_hash (&whirlpool_desc); +#endif + +#ifdef YARROW + register_prng (&yarrow_desc); +#endif +#ifdef SPRNG + register_prng (&sprng_desc); +#endif +} + +#ifdef KR +void +kr_display (pk_key * kr) +{ + static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" }; + static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" }; + + while (kr->system != NON_KEY) { + printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID, + sys[kr->system], type[kr->key_type], kr->name, kr->email, + kr->description); + kr = kr->next; + } + printf ("\n"); +} + +void +kr_test_makekeys (pk_key ** kr) +{ + if ((errnum = kr_init (kr)) != CRYPT_OK) { + printf ("KR init error %s\n", error_to_string (errnum)); + exit (-1); + } + + /* make a DH key */ + printf ("KR: Making DH key...\n"); + if ((errnum = + kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey", + "[email protected]", "dhkey one")) != CRYPT_OK) { + printf ("Make key error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* make a ECC key */ + printf ("KR: Making ECC key...\n"); + if ((errnum = + kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey", + "[email protected]", "ecckey one")) != CRYPT_OK) { + printf ("Make key error: %s\n", error_to_string (errnum)); + exit (-1); + } + + /* make a RSA key */ + printf ("KR: Making RSA key...\n"); + if ((errnum = + kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey", + "[email protected]", "rsakey one")) != CRYPT_OK) { + printf ("Make key error: %s\n", error_to_string (errnum)); + exit (-1); + } + +} + +void +kr_test (void) +{ + pk_key *kr, *_kr; + unsigned char buf[8192], buf2[8192], buf3[8192]; + unsigned long len; + int i, j, stat; +#ifndef NO_FILE + FILE *f; +#endif + + kr_test_makekeys (&kr); + + printf ("The original list:\n"); + kr_display (kr); + + for (i = 0; i < 3; i++) { + len = sizeof (buf); + if ((errnum = kr_export (kr, kr->ID, kr->key_type, buf, &len)) != CRYPT_OK) { + printf ("Error exporting key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + printf ("Exported key was: %lu bytes\n", len); + if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) { + printf ("Error deleting key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) { + printf ("Error importing key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + } + + for (i = 0; i < 3; i++) { + len = sizeof (buf); + if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) { + printf ("Error exporting key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + printf ("Exported key was: %lu bytes\n", len); + if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) { + printf ("Error deleting key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) { + printf ("Error importing key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + } + + if ((errnum = kr_clear (&kr)) != CRYPT_OK) { + printf ("Error clearing ring: %s\n", error_to_string (errnum)); + exit (-1); + } + + +/* TEST output to file */ +#ifndef NO_FILE + + if ((errnum = kr_init (&kr)) != CRYPT_OK) { + printf ("KR init error %s\n", error_to_string (errnum)); + exit (-1); + } + kr_test_makekeys (&kr); + + /* save to file */ + f = fopen ("ring.dat", "wb"); + if ((errnum = kr_save (kr, f, NULL)) != CRYPT_OK) { + printf ("kr_save error %s\n", error_to_string (errnum)); + exit (-1); + } + fclose (f); + + /* delete and load */ + if ((errnum = kr_clear (&kr)) != CRYPT_OK) { + printf ("clear error: %s\n", error_to_string (errnum)); + exit (-1); + } + + f = fopen ("ring.dat", "rb"); + if ((errnum = kr_load (&kr, f, NULL)) != CRYPT_OK) { + printf ("kr_load error %s\n", error_to_string (errnum)); + exit (-1); + } + fclose (f); + remove ("ring.dat"); + printf ("After load and save...\n"); + kr_display (kr); + + if ((errnum = kr_clear (&kr)) != CRYPT_OK) { + printf ("clear error: %s\n", error_to_string (errnum)); + exit (-1); + } +#endif + +/* test the packet encryption/sign stuff */ + for (i = 0; i < 32; i++) + buf[i] = i; + kr_test_makekeys (&kr); + _kr = kr; + for (i = 0; i < 3; i++) { + printf ("Testing a key with system %d, type %d:\t", _kr->system, + _kr->key_type); + len = sizeof (buf2); + if ((errnum = + kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng, + find_prng ("yarrow"), + find_hash ("md5"))) != CRYPT_OK) { + printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + len = sizeof (buf3); + if ((errnum = kr_decrypt_key (kr, buf2, buf3, &len)) != CRYPT_OK) { + printf ("decrypt error, %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + if (len != 16 || memcmp (buf3, buf, 16)) { + printf ("kr_decrypt_key failed, %i, %lu\n", i, len); + exit (-1); + } + printf ("kr_encrypt_key passed, "); + + len = sizeof (buf2); + if ((errnum = + kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng, + find_prng ("yarrow"))) != CRYPT_OK) { + printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum)); + exit (-1); + } + printf ("kr_sign_hash: "); + if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) { + printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum)); + exit (-1); + } + printf ("%s, ", stat ? "passed" : "failed"); + buf[15] ^= 1; + if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) { + printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum)); + exit (-1); + } + printf ("%s\n", (!stat) ? "passed" : "failed"); + buf[15] ^= 1; + + len = sizeof (buf); + if ((errnum = + kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf, + &len)) != CRYPT_OK) { + printf ("kr_fingerprint failed, %i, %lu\n", i, len); + exit (-1); + } + printf ("Fingerprint: "); + for (j = 0; j < 20; j++) { + printf ("%02x", buf[j]); + if (j < 19) + printf (":"); + } + printf ("\n\n"); + + _kr = _kr->next; + } + +/* Test encrypting/decrypting to a public key */ +/* first dump the other two keys */ + kr_del (&kr, kr->ID); + kr_del (&kr, kr->ID); + kr_display (kr); + + /* now export it as public and private */ + len = sizeof (buf); + if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) { + printf ("Error exporting key %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + + /* check boundaries */ + memset (buf + len, 0, sizeof (buf) - len); + + len = sizeof (buf2); + if ((errnum = kr_export (kr, kr->ID, PK_PRIVATE, buf2, &len)) != CRYPT_OK) { + printf ("Error exporting key %s\n", error_to_string (errnum)); + exit (-1); + } + + /* check boundaries */ + memset (buf2 + len, 0, sizeof (buf2) - len); + + /* delete the key and import the public */ + kr_clear (&kr); + kr_init (&kr); + kr_display (kr); + if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) { + printf ("Error importing key %s\n", error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + + /* now encrypt a buffer */ + for (i = 0; i < 16; i++) + buf[i] = i; + len = sizeof (buf3); + if ((errnum = + kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng, + find_prng ("yarrow"), + find_hash ("md5"))) != CRYPT_OK) { + printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum)); + exit (-1); + } + + /* now delete the key and import the private one */ + kr_clear (&kr); + kr_init (&kr); + kr_display (kr); + if ((errnum = kr_import (kr, buf2, len)) != CRYPT_OK) { + printf ("Error importing key %s\n", error_to_string (errnum)); + exit (-1); + } + kr_display (kr); + + /* now decrypt */ + len = sizeof (buf2); + if ((errnum = kr_decrypt_key (kr, buf3, buf2, &len)) != CRYPT_OK) { + printf ("decrypt error, %s\n", error_to_string (errnum)); + exit (-1); + } + + printf ("KR encrypt to public, decrypt with private: "); + if (len == 16 && !memcmp (buf2, buf, 16)) { + printf ("passed\n"); + } else { + printf ("failed\n"); + } + + kr_clear (&kr); +} +#endif + +void +test_errs (void) +{ +#define ERR(x) printf("%25s => %s\n", #x, error_to_string(x)); + + ERR (CRYPT_OK); + ERR (CRYPT_ERROR); + + ERR (CRYPT_INVALID_KEYSIZE); + ERR (CRYPT_INVALID_ROUNDS); + ERR (CRYPT_FAIL_TESTVECTOR); + + ERR (CRYPT_BUFFER_OVERFLOW); + ERR (CRYPT_INVALID_PACKET); + + ERR (CRYPT_INVALID_PRNGSIZE); + ERR (CRYPT_ERROR_READPRNG); + + ERR (CRYPT_INVALID_CIPHER); + ERR (CRYPT_INVALID_HASH); + ERR (CRYPT_INVALID_PRNG); + + ERR (CRYPT_MEM); + + ERR (CRYPT_PK_TYPE_MISMATCH); + ERR (CRYPT_PK_NOT_PRIVATE); + + ERR (CRYPT_INVALID_ARG); + ERR (CRYPT_FILE_NOTFOUND); + + ERR (CRYPT_PK_INVALID_TYPE); + ERR (CRYPT_PK_INVALID_SYSTEM); + ERR (CRYPT_PK_DUP); + ERR (CRYPT_PK_NOT_FOUND); + ERR (CRYPT_PK_INVALID_SIZE); + + ERR (CRYPT_INVALID_PRIME_SIZE); +} + + +void dsa_tests(void) +{ + unsigned char msg[16], out[1024], out2[1024]; + unsigned long x, y; + int err, stat1, stat2; + dsa_key key, key2; + + /* make a random key */ + if ((err = dsa_make_key(&prng, find_prng("yarrow"), 20, 128, &key)) != CRYPT_OK) { + printf("Error making DSA key: %s\n", error_to_string(err)); + exit(-1); + } + printf("DSA Key Made\n"); + + /* verify it */ + if ((err = dsa_verify_key(&key, &stat1)) != CRYPT_OK) { + printf("Error verifying DSA key: %s\n", error_to_string(err)); + exit(-1); + } + printf("DSA key verification: %s\n", stat1 == 1 ? "passed" : "failed"); + if (stat1 == 0) exit(-1); + + /* sign the message */ + x = sizeof(out); + if ((err = dsa_sign_hash(msg, sizeof(msg), out, &x, &prng, find_prng("yarrow"), &key)) != CRYPT_OK) { + printf("Error signing with DSA key: %s\n", error_to_string(err)); + exit(-1); + } + printf("DSA 160/1024 signature is %lu bytes long\n", x); + + /* verify it once */ + if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key)) != CRYPT_OK) { + printf("Error verifying with DSA key 1: %s\n", error_to_string(err)); + exit(-1); + } + + /* Modify and verify again */ + msg[0] ^= 1; + if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key)) != CRYPT_OK) { + printf("Error verifying with DSA key 2: %s\n", error_to_string(err)); + exit(-1); + } + msg[0] ^= 1; + printf("DSA Verification: %d, %d, %s\n", stat1, stat2, (stat1 == 1 && stat2 == 0) ? "passed" : "failed"); + if (!(stat1 == 1 && stat2 == 0)) exit(-1); + + /* test exporting it */ + x = sizeof(out2); + if ((err = dsa_export(out2, &x, PK_PRIVATE, &key)) != CRYPT_OK) { + printf("Error export PK_PRIVATE DSA key: %s\n", error_to_string(err)); + exit(-1); + } + printf("Exported PK_PRIVATE DSA key in %lu bytes\n", x); + if ((err = dsa_import(out2, x, &key2)) != CRYPT_OK) { + printf("Error importing PK_PRIVATE DSA key: %s\n", error_to_string(err)); + exit(-1); + } + /* verify a signature with it */ + if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)) != CRYPT_OK) { + printf("Error verifying with DSA key 3: %s\n", error_to_string(err)); + exit(-1); + } + printf("PRIVATE Import Test: %s\n", stat1 == 1 ? "passed" : "failed"); + if (stat1 == 0) exit(-1); + dsa_free(&key2); + + /* export as public now */ + x = sizeof(out2); + if ((err = dsa_export(out2, &x, PK_PUBLIC, &key)) != CRYPT_OK) { + printf("Error export PK_PUBLIC DSA key: %s\n", error_to_string(err)); + exit(-1); + } + printf("Exported PK_PUBLIC DSA key in %lu bytes\n", x); + if ((err = dsa_import(out2, x, &key2)) != CRYPT_OK) { + printf("Error importing PK_PUBLIC DSA key: %s\n", error_to_string(err)); + exit(-1); + } + /* verify a signature with it */ + if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)) != CRYPT_OK) { + printf("Error verifying with DSA key 4: %s\n", error_to_string(err)); + exit(-1); + } + printf("PUBLIC Import Test: %s\n", stat1 == 1 ? "passed" : "failed"); + if (stat1 == 0) exit(-1); + + dsa_free(&key2); + dsa_free(&key); +} + +#ifdef PKCS_1 +void pkcs1_test(void) +{ + unsigned char buf[3][128]; + int err, res1, res2, res3, prng_idx, hash_idx; + unsigned long x, y, l1, l2, l3, i1, i2; + + /* get hash/prng */ + hash_idx = find_hash("sha1"); + prng_idx = find_prng("yarrow"); + + /* do many tests */ + for (x = 0; x < 10000; x++) { + zeromem(buf, sizeof(buf)); + + /* make a dummy message (of random length) */ + l3 = (rand() & 31) + 8; + for (y = 0; y < l3; y++) buf[0][y] = rand() & 255; + + /* encode it */ + l1 = sizeof(buf[1]); + if ((err = pkcs_1_oaep_encode(buf[0], l3, NULL, 0, 1024, hash_idx, prng_idx, &prng, buf[1], &l1)) != CRYPT_OK) { + printf("OAEP encode: %s\n", error_to_string(err)); + exit(-1); + } + + /* decode it */ + l2 = sizeof(buf[2]); + if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2)) != CRYPT_OK) { + printf("OAEP decode: %s\n", error_to_string(err)); + exit(-1); + } + + if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { + printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3); + printf("ORIGINAL:\n"); + for (x = 0; x < l3; x++) { + printf("%02x ", buf[0][x]); + } + printf("\nRESULT:\n"); + for (x = 0; x < l2; x++) { + printf("%02x ", buf[2][x]); + } + printf("\n\n"); + exit(-1); + } + + /* test PSS */ + l1 = sizeof(buf[1]); + if ((err = pkcs_1_pss_encode(buf[0], l3, l3>>2, hash_idx, prng_idx, &prng, 1024, buf[1], &l1)) != CRYPT_OK) { + printf("PSS encode: %s\n", error_to_string(err)); + exit(-1); + } + + if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res1)) != CRYPT_OK) { + printf("PSS decode1: %s\n", error_to_string(err)); + exit(-1); + } + + buf[0][i1 = abs(rand()) % l3] ^= 1; + if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res2)) != CRYPT_OK) { + printf("PSS decode2: %s\n", error_to_string(err)); + exit(-1); + } + + buf[0][i1] ^= 1; + buf[1][i2 = abs(rand()) % l1] ^= 1; + if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res3)) != CRYPT_OK) { + printf("PSS decode3: %s\n", error_to_string(err)); + exit(-1); + } + + if (!(res1 == 1 && res2 == 0 && res3 == 0)) { + printf("PSS failed: %d, %d, %d, %lu\n", res1, res2, res3, l3); + exit(-1); + } + } + printf("PKCS #1: Passed\n"); +} + +#endif /* PKCS_1 */ + +int +main (void) +{ +#ifdef SONY_PS2 + TIMER_Init (); +#endif + srand(time(NULL)); + + register_all_algs (); + + if ((errnum = yarrow_start (&prng)) != CRYPT_OK) { + printf ("yarrow_start: %s\n", error_to_string (errnum)); + } + if ((errnum = yarrow_add_entropy ((unsigned char *)"hello", 5, &prng)) != CRYPT_OK) { + printf ("yarrow_add_entropy: %s\n", error_to_string (errnum)); + } + if ((errnum = yarrow_ready (&prng)) != CRYPT_OK) { + printf ("yarrow_ready: %s\n", error_to_string (errnum)); + } + + printf (crypt_build_settings); + test_errs (); + +#ifdef HMAC + printf ("HMAC: %s\n", hmac_test () == CRYPT_OK ? "passed" : "failed"); + if (hmac_test() != CRYPT_OK) exit(EXIT_FAILURE); +#endif + +#ifdef OMAC + printf ("OMAC: %s\n", omac_test () == CRYPT_OK ? "passed" : "failed"); + if (omac_test() != CRYPT_OK) exit(EXIT_FAILURE); +#endif + +#ifdef PMAC + printf ("PMAC: %s\n", pmac_test () == CRYPT_OK ? "passed" : "failed"); + if (pmac_test() != CRYPT_OK) exit(EXIT_FAILURE); +#endif + +#ifdef EAX_MODE + printf ("EAX : %s\n", eax_test () == CRYPT_OK ? "passed" : "failed"); + if (eax_test() != CRYPT_OK) exit(EXIT_FAILURE); +#endif + +#ifdef OCB_MODE + printf ("OCB : %s\n", ocb_test () == CRYPT_OK ? "passed" : "failed"); + if (ocb_test() != CRYPT_OK) exit(EXIT_FAILURE); +#endif + + store_tests (); + cipher_tests (); + hash_tests (); + +#ifdef PKCS_1 + pkcs1_test(); +#endif + + ecb_tests (); + cbc_tests (); + ctr_tests (); + ofb_tests (); + cfb_tests (); + + rng_tests (); + test_prime(); + +#ifdef KR + kr_test (); +#endif + dsa_tests(); + rsa_test (); + pad_test (); + ecc_tests (); + dh_tests (); + + gf_tests (); + base64_test (); + + time_ecb (); + time_hash (); + +#ifdef SONY_PS2 + TIMER_Shutdown (); +#endif + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/tv_gen.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,492 @@ +#include <mycrypt.h> + +void reg_algs(void) +{ +#ifdef RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef XTEA + register_cipher (&xtea_desc); +#endif +#ifdef RC5 + register_cipher (&rc5_desc); +#endif +#ifdef RC6 + register_cipher (&rc6_desc); +#endif +#ifdef SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef RC2 + register_cipher (&rc2_desc); +#endif +#ifdef DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef SKIPJACK + register_cipher (&skipjack_desc); +#endif + +#ifdef TIGER + register_hash (&tiger_desc); +#endif +#ifdef MD2 + register_hash (&md2_desc); +#endif +#ifdef MD4 + register_hash (&md4_desc); +#endif +#ifdef MD5 + register_hash (&md5_desc); +#endif +#ifdef SHA1 + register_hash (&sha1_desc); +#endif +#ifdef SHA224 + register_hash (&sha224_desc); +#endif +#ifdef SHA256 + register_hash (&sha256_desc); +#endif +#ifdef SHA384 + register_hash (&sha384_desc); +#endif +#ifdef SHA512 + register_hash (&sha512_desc); +#endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef WHIRLPOOL + register_hash (&whirlpool_desc); +#endif +} + +void hash_gen(void) +{ + unsigned char md[MAXBLOCKSIZE], buf[MAXBLOCKSIZE*2+2]; + unsigned long outlen, x, y, z; + FILE *out; + + out = fopen("hash_tv.txt", "w"); + + fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n"); + for (x = 0; hash_descriptor[x].name != NULL; x++) { + fprintf(out, "Hash: %s\n", hash_descriptor[x].name); + + for (y = 0; y <= (hash_descriptor[x].blocksize * 2); y++) { + for (z = 0; z < y; z++) { + buf[z] = (unsigned char)(z & 255); + } + outlen = sizeof(md); + hash_memory(x, buf, y, md, &outlen); + fprintf(out, "%3lu: ", y); + for (z = 0; z < outlen; z++) { + fprintf(out, "%02X", md[z]); + } + fprintf(out, "\n"); + } + fprintf(out, "\n"); + } + fclose(out); +} + +void cipher_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE]; + unsigned long x, y, z, w; + int kl, lastkl; + FILE *out; + symmetric_key skey; + + out = fopen("cipher_tv.txt", "w"); + + fprintf(out, +"Cipher Test Vectors\n\nThese are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style.\n" +"The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key)\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + fprintf(out, "Cipher: %s\n", cipher_descriptor[x].name); + + /* three modes, smallest, medium, large keys */ + lastkl = 10000; + for (y = 0; y < 3; y++) { + switch (y) { + case 0: kl = cipher_descriptor[x].min_key_length; break; + case 1: kl = (cipher_descriptor[x].min_key_length + cipher_descriptor[x].max_key_length)/2; break; + case 2: kl = cipher_descriptor[x].max_key_length; break; + } + cipher_descriptor[x].keysize(&kl); + if (kl == lastkl) break; + lastkl = kl; + fprintf(out, "Key Size: %d bytes\n", kl); + + for (z = 0; (int)z < kl; z++) { + key[z] = (unsigned char)z; + } + cipher_descriptor[x].setup(key, kl, 0, &skey); + + for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { + pt[z] = (unsigned char)z; + } + for (w = 0; w < 50; w++) { + cipher_descriptor[x].ecb_encrypt(pt, pt, &skey); + fprintf(out, "%2lu: ", w); + for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { + fprintf(out, "%02X", pt[z]); + } + fprintf(out, "\n"); + + /* reschedule a new key */ + for (z = 0; z < (unsigned long)kl; z++) { + key[z] = pt[z % cipher_descriptor[x].block_length]; + } + cipher_descriptor[x].setup(key, kl, 0, &skey); + } + fprintf(out, "\n"); + } + fprintf(out, "\n"); + } + fclose(out); +} + +void hmac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; + int x, y, z, kl, err; + FILE *out; + unsigned long len; + + out = fopen("hmac_tv.txt", "w"); + + fprintf(out, +"HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is\n" +"of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of\n" +"step N.\n\n"); + + for (x = 0; hash_descriptor[x].name != NULL; x++) { + fprintf(out, "HMAC-%s\n", hash_descriptor[x].name); + + /* initial key */ + for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) { + key[y] = (y&255); + } + + for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = hmac_memory(x, key, hash_descriptor[x].hashsize, input, y, output, &len)) != CRYPT_OK) { + printf("Error hmacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int) len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + memcpy(key, output, hash_descriptor[x].hashsize); + } + fprintf(out, "\n"); + } + fclose(out); +} + +void omac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; + int err, x, y, z, kl; + FILE *out; + unsigned long len; + + out = fopen("omac_tv.txt", "w"); + + fprintf(out, +"OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is\n" +"of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of\n" +"step N (repeated as required to fill the array).\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* initial key/block */ + for (y = 0; y < kl; y++) { + key[y] = (y & 255); + } + + for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = omac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { + printf("Error omacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = output[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void pmac_gen(void) +{ + unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; + int err, x, y, z, kl; + FILE *out; + unsigned long len; + + out = fopen("pmac_tv.txt", "w"); + + fprintf(out, +"PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is\n" +"of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of\n" +"step N (repeated as required to fill the array).\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* initial key/block */ + for (y = 0; y < kl; y++) { + key[y] = (y & 255); + } + + for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { + for (z = 0; z < y; z++) { + input[z] = (unsigned char)(z & 255); + } + len = sizeof(output); + if ((err = pmac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { + printf("Error omacing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", output[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = output[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void eax_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("eax_tv.txt", "w"); + fprintf(out, "EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently.\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "EAX-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + nonce[z] = (unsigned char)(z & 255); + header[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = eax_encrypt_authenticate_memory(x, key, kl, nonce, y1, header, y1, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { + printf("Error EAX'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void ocb_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("ocb_tv.txt", "w"); + fprintf(out, "OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout.\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 64 or 128 bit block sizes */ + if (kl != 8 && kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + /* fixed nonce */ + for (z = 0; z < cipher_descriptor[x].block_length; z++) { + nonce[z] = z; + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { + printf("Error OCB'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void base64_gen(void) +{ + FILE *out; + unsigned char dst[256], src[32]; + unsigned long x, y, len; + + out = fopen("base64_tv.txt", "w"); + fprintf(out, "Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1\n\n"); + for (x = 0; x <= 32; x++) { + for (y = 0; y < x; y++) { + src[y] = y; + } + len = sizeof(dst); + base64_encode(src, x, dst, &len); + fprintf(out, "%2lu: %s\n", x, dst); + } + fclose(out); +} + +int main(void) +{ + reg_algs(); + printf("Generating hash vectors..."); fflush(stdout); hash_gen(); printf("done\n"); + printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n"); + printf("Generating HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n"); + printf("Generating OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n"); + printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n"); + printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n"); + printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n"); + printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n"); + return 0; +} + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/x86_prof.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,358 @@ +#include <mycrypt.h> + +#define KTIMES 25 +#define TIMES 100000 + +struct list { + int id; + unsigned long spd1, spd2, avg; +} results[100]; + +int no_results; + +int sorter(const void *a, const void *b) +{ + const struct list *A, *B; + A = a; + B = b; + if (A->avg < B->avg) return -1; + if (A->avg > B->avg) return 1; + return 0; +} + +void tally_results(int type) +{ + int x; + + // qsort the results + qsort(results, no_results, sizeof(struct list), &sorter); + + printf("\n"); + if (type == 0) { + for (x = 0; x < no_results; x++) { + printf("%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1); + } + } else if (type == 1) { + for (x = 0; x < no_results; x++) { + printf + ("%-20s: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, results[x].spd1, results[x].spd2); + } + } else { + for (x = 0; x < no_results; x++) { + printf + ("%-20s: Process at %5lu\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000); + } + } +} + + + + +/* RDTSC from Scott Duplichan */ +static ulong64 rdtsc (void) + { + #if defined __GNUC__ + #ifdef __i386__ + ulong64 a; + __asm__ __volatile__ ("rdtsc ":"=A" (a)); + return a; + #else /* gcc-IA64 version */ + unsigned long result; + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + while (__builtin_expect ((int) result == -1, 0)) + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + return result; + #endif + + // Microsoft and Intel Windows compilers + #elif defined _M_IX86 + __asm rdtsc + #elif defined _M_AMD64 + return __rdtsc (); + #elif defined _M_IA64 + #if defined __INTEL_COMPILER + #include <ia64intrin.h> + #endif + return __getReg (3116); + #else + #error need rdtsc function for this build + #endif + } + +ulong64 timer, skew = 0; +prng_state prng; + +void t_start(void) +{ + timer = rdtsc(); +} + +ulong64 t_read(void) +{ + return rdtsc() - timer; +} + +void init_timer(void) +{ + ulong64 c1, c2, t1, t2, t3; + unsigned long y1; + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES*100; y1++) { + t_start(); + t1 = t_read(); + t3 = t_read(); + t2 = t_read() - t1; + + c1 = (c1 > t1) ? t1 : c1; + c2 = (c2 > t2) ? t2 : c2; + } + skew = c2 - c1; + printf("Clock Skew: %lu\n", (unsigned long)skew); +} + +void reg_algs(void) +{ +#ifdef RIJNDAEL + register_cipher (&aes_desc); +#endif +#ifdef BLOWFISH + register_cipher (&blowfish_desc); +#endif +#ifdef XTEA + register_cipher (&xtea_desc); +#endif +#ifdef RC5 + register_cipher (&rc5_desc); +#endif +#ifdef RC6 + register_cipher (&rc6_desc); +#endif +#ifdef SAFERP + register_cipher (&saferp_desc); +#endif +#ifdef TWOFISH + register_cipher (&twofish_desc); +#endif +#ifdef SAFER + register_cipher (&safer_k64_desc); + register_cipher (&safer_sk64_desc); + register_cipher (&safer_k128_desc); + register_cipher (&safer_sk128_desc); +#endif +#ifdef RC2 + register_cipher (&rc2_desc); +#endif +#ifdef DES + register_cipher (&des_desc); + register_cipher (&des3_desc); +#endif +#ifdef CAST5 + register_cipher (&cast5_desc); +#endif +#ifdef NOEKEON + register_cipher (&noekeon_desc); +#endif +#ifdef SKIPJACK + register_cipher (&skipjack_desc); +#endif + +#ifdef TIGER + register_hash (&tiger_desc); +#endif +#ifdef MD2 + register_hash (&md2_desc); +#endif +#ifdef MD4 + register_hash (&md4_desc); +#endif +#ifdef MD5 + register_hash (&md5_desc); +#endif +#ifdef SHA1 + register_hash (&sha1_desc); +#endif +#ifdef SHA224 + register_hash (&sha224_desc); +#endif +#ifdef SHA256 + register_hash (&sha256_desc); +#endif +#ifdef SHA384 + register_hash (&sha384_desc); +#endif +#ifdef SHA512 + register_hash (&sha512_desc); +#endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef RIPEMD160 + register_hash (&rmd160_desc); +#endif +#ifdef WHIRLPOOL + register_hash (&whirlpool_desc); +#endif + +register_prng(&yarrow_desc); +rng_make_prng(128, find_prng("yarrow"), &prng, NULL); +} + +int time_keysched(void) +{ + unsigned long x, i, y1; + ulong64 t1, c1; + symmetric_key skey; + int kl; + int (*func) (const unsigned char *, int , int , symmetric_key *); + unsigned char key[MAXBLOCKSIZE]; + + printf ("\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { +#define DO1(k) func(k, kl, 0, &skey); + + func = cipher_descriptor[x].setup; + kl = cipher_descriptor[x].min_key_length; + c1 = (ulong64)-1; + for (y1 = 0; y1 < KTIMES; y1++) { + yarrow_read(key, kl, &prng); + t_start(); + DO1(key); + t1 = t_read(); + c1 = (t1 > c1) ? c1 : t1; + } + t1 = c1 - skew; + results[no_results].spd1 = results[no_results].avg = t1; + results[no_results++].id = x; + printf("."); fflush(stdout); + +#undef DO1 + } + tally_results(0); + + return 0; +} + +int time_cipher(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_key skey; + void (*func) (const unsigned char *, unsigned char *, symmetric_key *); + unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE]; + + + printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0, + &skey); + +#define DO1 func(pt,pt,&skey); +#define DO2 DO1 DO1 + + func = cipher_descriptor[x].ecb_encrypt; + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + + + func = cipher_descriptor[x].ecb_decrypt; + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + + results[no_results].id = x; + results[no_results].spd1 = a1/cipher_descriptor[x].block_length; + results[no_results].spd2 = a2/cipher_descriptor[x].block_length;; + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + printf("."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} + +int time_hash(void) +{ + unsigned long x, y1, len; + ulong64 t1, t2, c1, c2; + hash_state md; + int (*func)(hash_state *, const unsigned char *, unsigned long); + unsigned char pt[MAXBLOCKSIZE]; + + + printf ("\n\nHASH Time Trials for:\n"); + no_results = 0; + for (x = 0; hash_descriptor[x].name != NULL; x++) { + hash_descriptor[x].init(&md); + +#define DO1 func(&md,pt,len); +#define DO2 DO1 DO1 + + func = hash_descriptor[x].process; + len = hash_descriptor[x].blocksize; + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < TIMES; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read() - t1; + c1 = (t1 > c1) ? c1 : t1; + c2 = (t2 > c2) ? c2 : t2; + } + t1 = c2 - c1 - skew; + t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize); + results[no_results].id = x; + results[no_results].spd1 = results[no_results].avg = t1; + ++no_results; + printf("."); fflush(stdout); +#undef DO2 +#undef DO1 + } + tally_results(2); + + return 0; +} + +int main(void) +{ + reg_algs(); + + printf("Timings for ciphers and hashes. Times are listed as cycles per byte processed.\n\n"); + +// init_timer(); + time_cipher(); + time_keysched(); + time_hash(); + + return EXIT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/des.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1813 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* DES code submitted by Dobes Vandermeer */ +#include "mycrypt.h" + +#ifdef DES + +#define EN0 0 +#define DE1 1 + +const struct _cipher_descriptor des_desc = +{ + "des", + 13, + 8, 8, 8, 16, + &des_setup, + &des_ecb_encrypt, + &des_ecb_decrypt, + &des_test, + &des_keysize +}; + +const struct _cipher_descriptor des3_desc = +{ + "3des", + 14, + 24, 24, 8, 16, + &des3_setup, + &des3_ecb_encrypt, + &des3_ecb_decrypt, + &des3_test, + &des3_keysize +}; + +static const ulong32 bytebit[8] = +{ + 0200, 0100, 040, 020, 010, 04, 02, 01 +}; + +static const ulong32 bigbyte[24] = +{ + 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, + 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, + 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, + 0x800UL, 0x400UL, 0x200UL, 0x100UL, + 0x80UL, 0x40UL, 0x20UL, 0x10UL, + 0x8UL, 0x4UL, 0x2UL, 0x1L +}; + +/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; + +static const unsigned char totrot[16] = { + 1, 2, 4, 6, + 8, 10, 12, 14, + 15, 17, 19, 21, + 23, 25, 27, 28 +}; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 +}; + + +static const ulong32 SP1[64] = +{ + 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, + 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, + 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, + 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, + 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, + 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, + 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, + 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, + 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, + 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, + 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, + 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, + 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, + 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL +}; + +static const ulong32 SP2[64] = +{ + 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, + 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, + 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, + 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, + 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, + 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, + 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, + 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, + 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, + 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, + 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, + 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, + 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, + 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, + 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, + 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL +}; + +static const ulong32 SP3[64] = +{ + 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, + 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, + 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, + 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, + 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, + 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, + 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, + 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, + 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, + 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, + 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, + 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, + 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, + 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, + 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, + 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL +}; + +static const ulong32 SP4[64] = +{ + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, + 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, + 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, + 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, + 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, + 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, + 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, + 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, + 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL +}; + +static const ulong32 SP5[64] = +{ + 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, + 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, + 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, + 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, + 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, + 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, + 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, + 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, + 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, + 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, + 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, + 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, + 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, + 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, + 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, + 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL +}; + +static const ulong32 SP6[64] = +{ + 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, + 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, + 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, + 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, + 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, + 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, + 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, + 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, + 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, + 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, + 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, + 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, + 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, + 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL +}; + +static const ulong32 SP7[64] = +{ + 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, + 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, + 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, + 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, + 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, + 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, + 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, + 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, + 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, + 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, + 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, + 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, + 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, + 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, + 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, + 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL +}; + +static const ulong32 SP8[64] = +{ + 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, + 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, + 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, + 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, + 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, + 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, + 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, + 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, + 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, + 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, + 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, + 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, + 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, + 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, + 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, + 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL +}; + +#ifndef SMALL_CODE + +static const ulong64 des_ip[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), + CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), + CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), + CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), + CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), + CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), + CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), + CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), + CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), + CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), + CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), + CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), + CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), + CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), + CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), + CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), + CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), + CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), + CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), + CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), + CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), + CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), + CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), + CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), + CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), + CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), + CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), + CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), + CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), + CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), + CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), + CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), + CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), + CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), + CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), + CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), + CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), + CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), + CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), + CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), + CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), + CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), + CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), + CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), + CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), + CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), + CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), + CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), + CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), + CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), + CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), + CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), + CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), + CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), + CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), + CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), + CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), + CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), + CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), + CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), + CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), + CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), + CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), + CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), + CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), + CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), + CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), + CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), + CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), + CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), + CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), + CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), + CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), + CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), + CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), + CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), + CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), + CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), + CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), + CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), + CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), + CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), + CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), + CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), + CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), + CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), + CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), + CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), + CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), + CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), + CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), + CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), + CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), + CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), + CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), + CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), + CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), + CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), + CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), + CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), + CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), + CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), + CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), + CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), + CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), + CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), + CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), + CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), + CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), + CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), + CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), + CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), + CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), + CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), + CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), + CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), + CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), + CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), + CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), + CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), + CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), + CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), + CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), + CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), + CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), + CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), + CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), + CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), + CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), + CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), + CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), + CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), + CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), + CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), + CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), + CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), + CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), + CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), + CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), + CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), + CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), + CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), + CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), + CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), + CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), + CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), + CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), + CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), + CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), + CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), + CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), + CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), + CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), + CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), + CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), + CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), + CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), + CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), + CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), + CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), + CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), + CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), + CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), + CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), + CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), + CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), + CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), + CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), + CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), + CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), + CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), + CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), + CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), + CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), + CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), + CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), + CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), + CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), + CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), + CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), + CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), + CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), + CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), + CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), + CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), + CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), + CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), + CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), + CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), + CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), + CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), + CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), + CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), + CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), + CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), + CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), + CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), + CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), + CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), + CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), + CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), + CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), + CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), + CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), + CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), + CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), + CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), + CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), + CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), + CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), + CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), + CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), + CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), + CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), + CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), + CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), + CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), + CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), + CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), + CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), + CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), + CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), + CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), + CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), + CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), + CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), + CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), + CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), + CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), + CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), + CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), + CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), + CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), + CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), + CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), + CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), + CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), + CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), + CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), + CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), + CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), + CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), + CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), + CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), + CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), + CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), + CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), + CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), + CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), + CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), + CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), + CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), + CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), + CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), + CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), + CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), + CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), + CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), + CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), + CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), + CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), + CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), + CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), + CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), + CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), + CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), + CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), + CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), + CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), + CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), + CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), + CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), + CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), + CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), + CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), + CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), + CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), + CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), + CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), + CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), + CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), + CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), + CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), + CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), + CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), + CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), + CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), + CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), + CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), + CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), + CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), + CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), + CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), + CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), + CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), + CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), + CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), + CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), + CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), + CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), + CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), + CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), + CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), + CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), + CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), + CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), + CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), + CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), + CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), + CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), + CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), + CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), + CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), + CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), + CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), + CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), + CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), + CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), + CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), + CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), + CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), + CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), + CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), + CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), + CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), + CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), + CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), + CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), + CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), + CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), + CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), + CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), + CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), + CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), + CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), + CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), + CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), + CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), + CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), + CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), + CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), + CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), + CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), + CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), + CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), + CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), + CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), + CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), + CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), + CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), + CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), + CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), + CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), + CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), + CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), + CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), + CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), + CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), + CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), + CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), + CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), + CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), + CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), + CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), + CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), + CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), + CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), + CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), + CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), + CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), + CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), + CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), + CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), + CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), + CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), + CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), + CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), + CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), + CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), + CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), + CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), + CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), + CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), + CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), + CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), + CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), + CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), + CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), + CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), + CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), + CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), + CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), + CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), + CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), + CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), + CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), + CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), + CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), + CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), + CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), + CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), + CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), + CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), + CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), + CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), + CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), + CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), + CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), + CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), + CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), + CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), + CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), + CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), + CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), + CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), + CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), + CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), + CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), + CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), + CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), + CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), + CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), + CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), + CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), + CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), + CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), + CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), + CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), + CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), + CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), + CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), + CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), + CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), + CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), + CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), + CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), + CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), + CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), + CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), + CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), + CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), + CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), + CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), + CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), + CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), + CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), + CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), + CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), + CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), + CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), + CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), + CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), + CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), + CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), + CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), + CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), + CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), + CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), + CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), + CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), + CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), + CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), + CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), + CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), + CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), + CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), + CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), + CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), + CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), + CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), + CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), + CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), + CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), + CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), + CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), + CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), + CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), + CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), + CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), + CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), + CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), + CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), + CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), + CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), + CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), + CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), + CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), + CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), + CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), + CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), + CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), + CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), + CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), + CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), + CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), + CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), + CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), + CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), + CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), + CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), + CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), + CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), + CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), + CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), + CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020) + }}; + +static const ulong64 des_fp[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), + CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), + CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), + CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), + CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), + CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), + CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), + CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), + CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), + CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), + CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), + CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), + CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), + CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), + CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), + CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), + CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), + CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), + CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), + CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), + CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), + CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), + CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), + CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), + CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), + CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), + CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), + CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), + CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), + CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), + CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), + CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), + CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), + CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), + CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), + CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), + CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), + CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), + CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), + CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), + CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), + CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), + CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), + CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), + CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), + CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), + CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), + CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), + CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), + CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), + CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), + CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), + CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), + CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), + CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), + CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), + CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), + CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), + CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), + CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), + CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), + CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), + CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), + CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), + CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), + CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), + CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), + CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), + CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), + CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), + CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), + CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), + CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), + CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), + CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), + CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), + CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), + CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), + CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), + CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), + CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), + CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), + CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), + CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), + CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), + CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), + CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), + CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), + CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), + CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), + CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), + CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), + CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), + CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), + CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), + CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), + CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), + CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), + CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), + CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), + CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), + CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), + CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), + CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), + CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), + CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), + CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), + CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), + CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), + CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), + CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), + CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), + CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), + CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), + CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), + CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), + CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), + CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), + CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), + CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), + CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), + CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), + CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), + CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), + CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), + CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), + CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), + CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), + CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), + CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), + CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), + CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), + CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), + CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), + CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), + CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), + CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), + CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), + CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), + CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), + CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), + CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), + CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), + CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), + CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), + CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), + CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), + CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), + CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), + CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), + CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), + CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), + CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), + CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), + CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), + CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), + CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), + CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), + CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), + CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), + CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), + CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), + CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), + CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), + CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), + CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), + CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), + CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), + CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), + CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), + CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), + CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), + CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), + CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), + CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), + CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), + CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), + CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), + CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), + CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), + CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), + CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), + CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), + CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), + CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), + CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), + CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), + CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), + CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), + CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), + CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), + CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), + CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), + CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), + CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), + CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), + CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), + CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), + CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), + CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), + CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), + CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), + CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), + CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), + CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), + CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), + CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), + CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), + CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), + CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), + CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), + CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), + CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), + CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), + CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), + CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), + CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), + CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), + CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), + CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), + CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), + CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), + CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), + CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), + CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), + CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), + CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), + CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), + CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), + CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), + CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), + CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), + CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), + CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), + CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), + CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), + CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), + CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), + CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), + CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), + CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), + CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), + CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), + CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), + CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), + CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), + CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), + CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), + CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), + CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), + CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), + CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), + CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), + CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), + CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), + CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), + CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), + CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), + CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), + CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), + CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), + CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), + CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), + CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), + CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), + CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), + CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), + CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), + CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), + CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), + CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), + CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), + CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), + CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), + CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), + CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), + CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), + CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), + CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), + CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), + CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), + CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), + CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), + CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), + CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), + CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), + CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), + CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), + CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), + CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), + CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), + CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), + CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), + CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), + CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), + CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), + CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), + CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), + CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), + CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), + CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), + CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), + CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), + CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), + CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), + CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), + CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), + CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), + CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), + CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), + CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), + CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), + CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), + CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), + CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), + CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), + CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), + CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), + CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), + CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), + CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), + CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), + CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), + CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), + CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), + CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), + CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), + CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), + CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), + CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), + CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), + CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), + CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), + CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), + CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), + CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), + CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), + CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), + CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), + CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), + CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), + CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), + CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), + CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), + CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), + CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), + CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), + CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), + CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), + CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), + CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), + CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), + CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), + CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), + CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), + CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), + CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), + CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), + CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), + CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), + CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), + CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), + CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), + CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), + CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), + CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), + CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), + CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), + CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), + CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), + CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), + CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), + CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), + CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), + CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), + CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), + CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), + CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), + CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), + CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), + CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), + CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), + CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), + CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), + CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), + CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), + CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), + CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), + CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), + CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), + CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), + CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), + CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), + CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), + CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), + CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), + CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), + CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), + CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), + CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), + CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), + CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), + CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), + CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), + CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), + CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), + CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), + CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), + CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), + CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), + CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), + CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), + CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), + CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), + CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), + CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), + CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), + CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), + CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), + CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), + CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), + CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), + CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), + CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), + CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), + CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), + CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), + CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), + CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), + CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), + CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), + CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), + CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), + CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), + CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), + CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), + CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), + CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), + CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), + CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), + CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), + CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), + CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), + CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), + CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), + CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), + CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), + CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), + CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), + CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), + CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), + CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), + CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), + CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), + CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), + CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), + CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), + CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), + CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), + CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), + CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), + CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), + CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), + CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), + CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), + CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), + CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), + CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), + CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), + CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), + CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), + CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), + CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), + CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), + CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), + CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), + CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), + CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), + CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), + CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), + CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), + CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), + CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), + CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), + CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), + CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), + CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), + CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), + CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), + CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), + CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), + CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), + CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), + CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), + CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), + CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), + CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), + CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), + CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), + CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), + CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), + CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), + CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), + CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), + CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040) + }}; + +#endif + + +static void cookey(const ulong32 *raw1, ulong32 *keyout); + +#ifdef CLEAN_STACK +void _deskey(const unsigned char *key, short edf, ulong32 *keyout) +#else +void deskey(const unsigned char *key, short edf, ulong32 *keyout) +#endif +{ + ulong32 i, j, l, m, n, kn[32]; + unsigned char pc1m[56], pcr[56]; + + for (j=0; j < 56; j++) { + l = (ulong32)pc1[j]; + m = l & 7; + pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); + } + + for (i=0; i < 16; i++) { + if (edf == DE1) { + m = (15 - i) << 1; + } else { + m = i << 1; + } + n = m + 1; + kn[m] = kn[n] = 0L; + for (j=0; j < 28; j++) { + l = j + (ulong32)totrot[i]; + if (l < 28) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (/*j = 28*/; j < 56; j++) { + l = j + (ulong32)totrot[i]; + if (l < 56) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (j=0; j < 24; j++) { + if ((int)pcr[(int)pc2[j]] != 0) { + kn[m] |= bigbyte[j]; + } + if ((int)pcr[(int)pc2[j+24]] != 0) { + kn[n] |= bigbyte[j]; + } + } + } + + cookey(kn, keyout); +} + +#ifdef CLEAN_STACK +void deskey(const unsigned char *key, short edf, ulong32 *keyout) +{ + _deskey(key, edf, keyout); + burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112); +} +#endif + +#ifdef CLEAN_STACK +static void _cookey(const ulong32 *raw1, ulong32 *keyout) +#else +static void cookey(const ulong32 *raw1, ulong32 *keyout) +#endif +{ + ulong32 *cook; + const ulong32 *raw0; + ulong32 dough[32]; + int i; + + cook = dough; + for(i=0; i < 16; i++, raw1++) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + memcpy(keyout, dough, sizeof dough); +} + +#ifdef CLEAN_STACK +static void cookey(const ulong32 *raw1, ulong32 *keyout) +{ + _cookey(raw1, keyout); + burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int)); +} +#endif + +#ifndef CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +#else +static void _desfunc(ulong32 *block, const ulong32 *keys) +#endif +{ + ulong32 work, right, leftt; + int round; + + leftt = block[0]; + right = block[1]; + +#ifdef SMALL_CODE + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + + right = ROL(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + + leftt ^= work; + right ^= work; + leftt = ROL(leftt, 1); +#else + { + ulong64 tmp; + tmp = des_ip[0][byte(leftt, 0)] ^ + des_ip[1][byte(leftt, 1)] ^ + des_ip[2][byte(leftt, 2)] ^ + des_ip[3][byte(leftt, 3)] ^ + des_ip[4][byte(right, 0)] ^ + des_ip[5][byte(right, 1)] ^ + des_ip[6][byte(right, 2)] ^ + des_ip[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + for (round = 0; round < 8; round++) { + work = ROR(right, 4) ^ *keys++; + leftt ^= SP7[work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + leftt ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + + work = ROR(leftt, 4) ^ *keys++; + right ^= SP7[ work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + right ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + } + +#ifdef SMALL_CODE + right = ROR(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ROR(leftt, 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + // -- + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); +#else + { + ulong64 tmp; + tmp = des_fp[0][byte(leftt, 0)] ^ + des_fp[1][byte(leftt, 1)] ^ + des_fp[2][byte(leftt, 2)] ^ + des_fp[3][byte(leftt, 3)] ^ + des_fp[4][byte(right, 0)] ^ + des_fp[5][byte(right, 1)] ^ + des_fp[6][byte(right, 2)] ^ + des_fp[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + block[0] = right; + block[1] = leftt; +} + +#ifdef CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +{ + _desfunc(block, keys); + burn_stack(sizeof(ulong32) * 4 + sizeof(int)); +} +#endif + +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des.ek); + deskey(key, DE1, skey->des.dk); + + return CRYPT_OK; +} + +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if( num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 24) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des3.ek[0]); + deskey(key+8, DE1, skey->des3.ek[1]); + deskey(key+16, EN0, skey->des3.ek[2]); + + deskey(key, DE1, skey->des3.dk[2]); + deskey(key+8, EN0, skey->des3.dk[1]); + deskey(key+16, DE1, skey->des3.dk[0]); + + return CRYPT_OK; +} + +void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, key->des.ek); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); +} + +void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, key->des.dk); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); +} + +void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + ulong32 work[2]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, key->des3.ek[0]); + desfunc(work, key->des3.ek[1]); + desfunc(work, key->des3.ek[2]); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); +} + +void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, key->des3.dk[0]); + desfunc(work, key->des3.dk[1]); + desfunc(work, key->des3.dk[2]); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); +} + +int des_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct des_test_case { + int num, mode; // mode 1 = encrypt + unsigned char key[8], txt[8], out[8]; + } cases[] = { + { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, + { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + + { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, + { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, + { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, + { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, + { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, + { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, + { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, + { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, + {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } } + + /*** more test cases you could add if you are not convinced (the above test cases aren't really too good): + + key plaintext ciphertext + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 + 3000000000000000 1000000000000001 958E6E627A05557B + 1111111111111111 1111111111111111 F40379AB9E0EC533 + 0123456789ABCDEF 1111111111111111 17668DFC7292532D + 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 + 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B + 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 + 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A + 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A + 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 + 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B + 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 + 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A + 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F + 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 + 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 + 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A + 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 + 025816164629B007 480D39006EE762F2 A1F9915541020B56 + 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 + 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC + 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A + 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 + 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 + 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 + 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 + E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 + 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 + FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE + 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D + FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 + + http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt + ***/ + }; + int i, y; + unsigned char tmp[8]; + symmetric_key des; + + for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) + { + if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) { + return err; + } + if (cases[i].mode != 0) { + des_ecb_encrypt(cases[i].txt, tmp, &des); + } else { + des_ecb_decrypt(cases[i].txt, tmp, &des); + } + + if (memcmp(cases[i].out, tmp, sizeof(tmp)) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[y] = 0; + for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); + for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); + for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; +} + + return CRYPT_OK; + #endif +} + +int des3_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char key[24], pt[8], ct[8], tmp[8]; + symmetric_key skey; + int x, err; + + if ((err = des_test()) != CRYPT_OK) { + return err; + } + + for (x = 0; x < 8; x++) { + pt[x] = x; + } + + for (x = 0; x < 24; x++) { + key[x] = x; + } + + if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) { + return err; + } + + des3_ecb_encrypt(pt, ct, &skey); + des3_ecb_decrypt(ct, tmp, &skey); + + if (memcmp(pt, tmp, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int des_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if(*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 8; + return CRYPT_OK; +} + +int des3_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if(*desired_keysize < 24) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 24; + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dh.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,452 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDH + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +static const struct { + int size; + char *name, *base, *prime; +} sets[] = { +#ifdef DH768 +{ + 96, + "DH-768", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////m3wvV" +}, +#endif +#ifdef DH1024 +{ + 128, + "DH-1024", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////m3C47" +}, +#endif +#ifdef DH1280 +{ + 160, + "DH-1280", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////m4kSN" +}, +#endif +#ifdef DH1536 +{ + 192, + "DH-1536", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////m5uqd" +}, +#endif +#ifdef DH1792 +{ + 224, + "DH-1792", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////mT/sd" +}, +#endif +#ifdef DH2048 +{ + 256, + "DH-2048", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////////////////m8MPh" +}, +#endif +#ifdef DH2560 +{ + 320, + "DH-2560", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////mKFpF" +}, +#endif +#ifdef DH3072 +{ + 384, + "DH-3072", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////m32nN" +}, +#endif +#ifdef DH4096 +{ + 512, + "DH-4096", + "4", + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////m8pOF" +}, +#endif +{ + 0, + NULL, + NULL, + NULL +} +}; + +static int is_valid_idx(int n) +{ + int x; + + for (x = 0; sets[x].size; x++); + if ((n < 0) || (n >= x)) { + return 0; + } + return 1; +} + +int dh_test(void) +{ + mp_int p, g, tmp; + int x, err, primality; + + if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != MP_OKAY) { goto error; } + + for (x = 0; sets[x].size != 0; x++) { +#if 0 + printf("dh_test():testing size %d-bits\n", sets[x].size * 8); +#endif + if ((err = mp_read_radix(&g,(char *)sets[x].base, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&p,(char *)sets[x].prime, 64)) != MP_OKAY) { goto error; } + + /* ensure p is prime */ + if ((err = is_prime(&p, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + if ((err = mp_sub_d(&p, 1, &tmp)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(&tmp, &tmp)) != MP_OKAY) { goto error; } + + /* ensure (p-1)/2 is prime */ + if ((err = is_prime(&tmp, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + /* now see if g^((p-1)/2) mod p is in fact 1 */ + if ((err = mp_exptmod(&g, &tmp, &p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1)) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + } + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp, &g, &p, NULL); + return err; +} + +void dh_sizes(int *low, int *high) +{ + int x; + _ARGCHK(low != NULL); + _ARGCHK(high != NULL); + *low = INT_MAX; + *high = 0; + for (x = 0; sets[x].size != 0; x++) { + if (*low > sets[x].size) *low = sets[x].size; + if (*high < sets[x].size) *high = sets[x].size; + } +} + +int dh_get_size(dh_key *key) +{ + _ARGCHK(key != NULL); + if (is_valid_idx(key->idx) == 1) { + return sets[key->idx].size; + } else { + return INT_MAX; /* large value that would cause dh_make_key() to fail */ + } +} + +int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) +{ + unsigned char buf[512]; + unsigned long x; + mp_int p, g; + int err; + + _ARGCHK(key != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* find key size */ + for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); +#ifdef FAST_PK + keysize = MIN(sets[x].size, 32); +#else + keysize = sets[x].size; +#endif + + if (sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + key->idx = x; + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { + return CRYPT_ERROR_READPRNG; + } + + /* init parameters */ + if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + + /* load the x value */ + if ((err = mp_read_unsigned_bin(&key->x, buf, keysize)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&g, &key->x, &p, &key->y)) != MP_OKAY) { goto error; } + key->type = PK_PRIVATE; + + if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; } + + /* free up ram */ + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); + mp_clear_multi(&key->x, &key->y, NULL); +done: + mp_clear_multi(&p, &g, NULL); + zeromem(buf, sizeof(buf)); + return err; +} + +void dh_free(dh_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->x, &key->y, NULL); +} + +int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key) +{ + unsigned long y, z; + int err; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 2)) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* header */ + y = PACKET_SIZE; + + /* header */ + out[y++] = type; + out[y++] = (unsigned char)(sets[key->idx].size / 8); + + /* export y */ + OUTPUT_BIGNUM(&key->y, out, y, z); + + if (type == PK_PRIVATE) { + /* export x */ + OUTPUT_BIGNUM(&key->x, out, y, z); + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY); + + /* store len */ + *outlen = y; + return CRYPT_OK; +} + +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key) +{ + unsigned long x, y, s; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* make sure valid length */ + if ((2+PACKET_SIZE) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type byte */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init */ + if ((err = mp_init_multi(&key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* advance past packet header */ + y = PACKET_SIZE; + + /* key type, e.g. private, public */ + key->type = (int)in[y++]; + + /* key size in bytes */ + s = (unsigned long)in[y++] * 8; + + for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); + if (sets[x].size == 0) { + err = CRYPT_INVALID_KEYSIZE; + goto error; + } + key->idx = (int)x; + + /* type check both values */ + if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* is the key idx valid? */ + if (is_valid_idx(key->idx) != 1) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* load public value g^x mod p*/ + INPUT_BIGNUM(&key->y, in, x, y, inlen); + + if (key->type == PK_PRIVATE) { + INPUT_BIGNUM(&key->x, in, x, y, inlen); + } + + /* eliminate private key if public */ + if (key->type == PK_PUBLIC) { + mp_clear(&key->x); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->y, &key->x, NULL); + return err; +} + +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + mp_int tmp, p; + unsigned long x; + int err; + + _ARGCHK(private_key != NULL); + _ARGCHK(public_key != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* types valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* same idx? */ + if (private_key->idx != public_key->idx) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* compute y^x mod p */ + if ((err = mp_init_multi(&tmp, &p, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + if ((err = mp_read_radix(&p, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&public_key->y, &private_key->x, &p, &tmp)) != MP_OKAY) { goto error; } + + /* enough space for output? */ + x = (unsigned long)mp_unsigned_bin_size(&tmp); + if (*outlen < x) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { goto error; } + *outlen = x; + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&p, &tmp, NULL); + return err; +} + +#include "dh_sys.c" + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dh_sys.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,399 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + dh_key *key) +{ + unsigned char pub_expt[768], dh_shared[768], skey[MAXBLOCKSIZE]; + dh_key pubkey; + unsigned long x, y, z, hashsize, pubkeysize; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(out != NULL); + _ARGCHK(len != NULL); + _ARGCHK(key != NULL); + + /* check that wprng/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (keylen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = sizeof(pub_expt); + if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + + /* now check if the out buffer is big enough */ + if (*len < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + keylen)) { + dh_free(&pubkey); + return CRYPT_BUFFER_OVERFLOW; + } + + /* make random key */ + hashsize = hash_descriptor[hash].hashsize; + + x = (unsigned long)sizeof(dh_shared); + if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + dh_free(&pubkey); + + z = sizeof(skey); + if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY); + + /* output header */ + y = PACKET_SIZE; + + /* size of hash name and the name itself */ + out[y++] = hash_descriptor[hash].ID; + + /* length of DH pubkey and the key itself */ + STORE32L(pubkeysize, out+y); + y += 4; + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = pub_expt[x]; + } + + /* Store the encrypted key */ + STORE32L(keylen, out+y); + y += 4; + + for (x = 0; x < keylen; x++, y++) { + out[y] = skey[x] ^ inkey[x]; + } + *len = y; + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(pub_expt, sizeof(pub_expt)); + zeromem(dh_shared, sizeof(dh_shared)); + zeromem(skey, sizeof(skey)); +#endif + + return CRYPT_OK; +} + +int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + dh_key *key) +{ + unsigned char shared_secret[768], skey[MAXBLOCKSIZE]; + unsigned long x, y, z,hashsize, keysize; + int hash, err; + dh_key pubkey; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check if initial header should fit */ + if (inlen < PACKET_SIZE+1+4+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+1+4+4; + } + + /* is header correct? */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* now lets get the hash name */ + y = PACKET_SIZE; + hash = find_hash_id(in[y++]); + if (hash == -1) { + return CRYPT_INVALID_HASH; + } + + /* common values */ + hashsize = hash_descriptor[hash].hashsize; + + /* get public key */ + LOAD32L(x, in+y); + + /* now check if the imported key will fit */ + if (inlen < x) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= x; + } + + y += 4; + if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* make shared key */ + x = (unsigned long)sizeof(shared_secret); + if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + dh_free(&pubkey); + + z = sizeof(skey); + if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* load in the encrypted key */ + LOAD32L(keysize, in+y); + + /* will the outkey fit as part of the input */ + if (inlen < keysize) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= keysize; + } + + if (keysize > *keylen) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + y += 4; + + *keylen = keysize; + + for (x = 0; x < keysize; x++, y++) { + outkey[x] = skey[x] ^ in[y]; + } + + err = CRYPT_OK; +done: +#ifdef CLEAN_STACK + zeromem(shared_secret, sizeof(shared_secret)); + zeromem(skey, sizeof(skey)); +#endif + return err; +} + +/* perform an ElGamal Signature of a hash + * + * The math works as follows. x is the private key, M is the message to sign + + 1. pick a random k + 2. compute a = g^k mod p + 3. compute b = (M - xa)/k mod p + 4. Send (a,b) + + Now to verify with y=g^x mod p, a and b + + 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k) + = g^(xa + (M - xa)) + = g^M [all mod p] + + 2. Compare against g^M mod p [based on input hash]. + 3. If result of #2 == result of #1 then signature valid +*/ +int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key) +{ + mp_int a, b, k, m, g, p, p1, tmp; + unsigned char buf[520]; + unsigned long x, y; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* check parameters */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* is the IDX valid ? */ + if (is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + /* make up a random value k, + * since the order of the group is prime + * we need not check if gcd(k, r) is 1 + */ + if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != + (unsigned long)(sets[key->idx].size)) { + return CRYPT_ERROR_READPRNG; + } + + /* init bignums */ + if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* load k and m */ + if ((err = mp_read_unsigned_bin(&m, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } +#ifdef FAST_PK + if ((err = mp_read_unsigned_bin(&k, buf, MIN(32,sets[key->idx].size))) != MP_OKAY) { goto error; } +#else + if ((err = mp_read_unsigned_bin(&k, buf, sets[key->idx].size)) != MP_OKAY) { goto error; } +#endif + + /* load g, p and p1 */ + if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_sub_d(&p, 1, &p1)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(&p1, &p1)) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */ + + /* now get a = g^k mod p */ + if ((err = mp_exptmod(&g, &k, &p, &a)) != MP_OKAY) { goto error; } + + /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */ + if ((err = mp_invmod(&k, &p1, &k)) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */ + if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = xa */ + if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = M - xa */ + if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY) { goto error; } /* b = (M - xa)/k */ + + /* check for overflow */ + if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* store header */ + y = PACKET_SIZE; + + /* now store them both (a,b) */ + x = (unsigned long)mp_unsigned_bin_size(&a); + STORE32L(x, out+y); y += 4; + if ((err = mp_to_unsigned_bin(&a, out+y)) != MP_OKAY) { goto error; } + y += x; + + x = (unsigned long)mp_unsigned_bin_size(&b); + STORE32L(x, out+y); y += 4; + if ((err = mp_to_unsigned_bin(&b, out+y)) != MP_OKAY) { goto error; } + y += x; + + /* check if size too big */ + if (*outlen < y) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED); + *outlen = y; + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL); + return err; +} + + +/* verify the signature in sig of the given hash */ +int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key) +{ + mp_int a, b, p, g, m, tmp; + unsigned long x, y; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* check initial input length */ + if (siglen < PACKET_SIZE+4+4) { + return CRYPT_INVALID_PACKET; + } + + /* header ok? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get hash out of packet */ + y = PACKET_SIZE; + + /* init all bignums */ + if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* load a and b */ + INPUT_BIGNUM(&a, sig, x, y, siglen); + INPUT_BIGNUM(&b, sig, x, y, siglen); + + /* load p and g */ + if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error1; } + if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error1; } + + /* load m */ + if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error1; } + + /* find g^m mod p */ + if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY) { goto error1; } /* m = g^m mod p */ + + /* find y^a * a^b */ + if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY) { goto error1; } /* tmp = y^a mod p */ + if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY) { goto error1; } /* a = a^b mod p */ + if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY) { goto error1; } /* a = y^a * a^b mod p */ + + /* y^a * a^b == g^m ??? */ + if (mp_cmp(&a, &m) == 0) { + *stat = 1; + } + + /* clean up */ + err = CRYPT_OK; + goto done; +error1: + err = mpi_to_ltc_error(err); +error: +done: + mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL); + return err; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_export.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,62 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) +{ + unsigned long y, z; + int err; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 1 + 2)) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (type != PK_PUBLIC && type != PK_PRIVATE) { + return CRYPT_INVALID_ARG; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY); + y = PACKET_SIZE; + + /* store g, p, q, qord */ + out[y++] = type; + out[y++] = (key->qord>>8)&255; + out[y++] = key->qord & 255; + + OUTPUT_BIGNUM(&key->g,out,y,z); + OUTPUT_BIGNUM(&key->p,out,y,z); + OUTPUT_BIGNUM(&key->q,out,y,z); + + /* public exponent */ + OUTPUT_BIGNUM(&key->y,out,y,z); + + if (type == PK_PRIVATE) { + OUTPUT_BIGNUM(&key->x,out,y,z); + } + + *outlen = y; + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_free.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,21 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +void dsa_free(dsa_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_import.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,59 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + unsigned long x, y; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if ((1+2+PACKET_SIZE) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + y = PACKET_SIZE; + + /* init key */ + if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* read type/qord */ + key->type = in[y++]; + key->qord = ((unsigned)in[y]<<8)|((unsigned)in[y+1]); + y += 2; + + /* input publics */ + INPUT_BIGNUM(&key->g,in,x,y, inlen); + INPUT_BIGNUM(&key->p,in,x,y, inlen); + INPUT_BIGNUM(&key->q,in,x,y, inlen); + INPUT_BIGNUM(&key->y,in,x,y, inlen); + if (key->type == PK_PRIVATE) { + INPUT_BIGNUM(&key->x,in,x,y, inlen); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); + return err; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_make_key.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,117 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) +{ + mp_int tmp, tmp2; + int err, res; + unsigned char buf[512]; + + _ARGCHK(key != NULL); + + /* check prng */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (group_size >= 1024 || group_size <= 15 || + group_size >= modulus_size || (modulus_size - group_size) >= (int)sizeof(buf)) { + return CRYPT_INVALID_ARG; + } + + /* init mp_ints */ + if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* make our prime q */ + if ((err = rand_prime(&key->q, group_size*8, prng, wprng)) != CRYPT_OK) { goto error2; } + + /* double q */ + if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY) { goto error; } + + /* now make a random string and multply it against q */ + if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { + err = CRYPT_ERROR_READPRNG; + goto error2; + } + + /* force magnitude */ + buf[0] = 1; + + /* force even */ + buf[modulus_size - group_size] &= ~1; + + if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size+1)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; } + + /* now loop until p is prime */ + for (;;) { + if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto error2; } + if (res == MP_YES) break; + + /* add 2q to p and 2 to tmp2 */ + if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY) { goto error; } + } + + /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ + mp_set(&key->g, 1); + + do { + if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY) { goto error; } + } while (mp_cmp_d(&tmp, 1) == MP_EQ); + + /* at this point tmp generates a group of order q mod p */ + mp_exch(&tmp, &key->g); + + /* so now we have our DH structure, generator g, order q, modulus p + Now we need a random exponent [mod q] and it's power g^x mod p + */ + do { + if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { + err = CRYPT_ERROR_READPRNG; + goto error2; + } + if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY) { goto error; } + } while (mp_cmp_d(&key->x, 1) != MP_GT); + if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY) { goto error; } + + key->type = PK_PRIVATE; + key->qord = group_size; + + /* shrink the ram required */ + if ((err = mp_shrink(&key->g)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; } + + err = CRYPT_OK; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + goto done; +error : err = mpi_to_ltc_error(err); +error2: mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +done : mp_clear_multi(&tmp, &tmp2, NULL); + return err; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_sign_hash.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,125 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key) +{ + mp_int k, kinv, tmp, r, s; + unsigned char buf[512]; + int err, y; + unsigned long len; + + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check group order size */ + if (key->qord >= (int)sizeof(buf)) { + return CRYPT_INVALID_ARG; + } + + /* Init our temps */ + if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; } + +retry: + + do { + /* gen random k */ + if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { + err = CRYPT_ERROR_READPRNG; + goto done; + } + + /* read k */ + if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY) { goto error; } + + /* k > 1 ? */ + if (mp_cmp_d(&k, 1) != MP_GT) { goto retry; } + + /* test gcd */ + if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY) { goto error; } + } while (mp_cmp_d(&tmp, 1) != MP_EQ); + + /* now find 1/k mod q */ + if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; } + + /* now find r = g^k mod p mod q */ + if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; } + + if (mp_iszero(&r) == MP_YES) { goto retry; } + + /* now find s = (in + xr)/k mod q */ + if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; } + if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; } + + if (mp_iszero(&s) == MP_YES) { goto retry; } + + /* now store em both */ + + /* first check that we have enough room */ + if (*outlen < (unsigned long)(PACKET_SIZE + 4 + mp_unsigned_bin_size(&s) + mp_unsigned_bin_size(&r))) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* packet header */ + packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_SIGNED); + y = PACKET_SIZE; + + /* store length of r */ + len = mp_unsigned_bin_size(&r); + out[y++] = (len>>8)&255; + out[y++] = len&255; + + /* store r */ + if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY) { goto error; } + y += len; + + /* store length of s */ + len = mp_unsigned_bin_size(&s); + out[y++] = (len>>8)&255; + out[y++] = len&255; + + /* store s */ + if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY) { goto error; } + y += len; + + /* reset size */ + *outlen = y; + + err = CRYPT_OK; + goto done; + +error : err = mpi_to_ltc_error(err); +done : mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_verify_hash.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, dsa_key *key) +{ + mp_int r, s, w, v, u1, u2; + unsigned long x, y; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + if (siglen < PACKET_SIZE+2+2) { + return CRYPT_INVALID_PACKET; + } + + /* is the message format correct? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DSA, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* skip over header */ + y = PACKET_SIZE; + + /* init our variables */ + if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* read in r followed by s */ + x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]); + y += 2; + if (y + x > siglen) { + err = CRYPT_INVALID_PACKET; + goto done; + } + if ((err = mp_read_unsigned_bin(&r, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + y += x; + + /* load s */ + x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]); + y += 2; + if (y + x > siglen) { + err = CRYPT_INVALID_PACKET; + goto done; + } + if ((err = mp_read_unsigned_bin(&s, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + + /* w = 1/s mod q */ + if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, inlen)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(&r, &v) == MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; + goto done; + +error : err = mpi_to_ltc_error(err); +done : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL); + return err; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsa_verify_key.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MDSA + +int dsa_verify_key(dsa_key *key, int *stat) +{ + mp_int tmp, tmp2; + int res, err; + + _ARGCHK(key != NULL); + _ARGCHK(stat != NULL); + + *stat = 0; + + /* first make sure key->q and key->p are prime */ + if ((err = is_prime(&key->q, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + + if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + /* now make sure that g is not -1, 0 or 1 and <p */ + if (mp_cmp_d(&key->g, 0) == MP_EQ || mp_cmp_d(&key->g, 1) == MP_EQ) { + return CRYPT_OK; + } + if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != MP_OKAY) { goto error; } + if ((err = mp_sub_d(&key->p, 1, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp(&tmp, &key->g) == MP_EQ || mp_cmp(&key->g, &key->p) != MP_LT) { + err = CRYPT_OK; + goto done; + } + + /* 1 < y < p-1 */ + if (!(mp_cmp_d(&key->y, 1) == MP_GT && mp_cmp(&key->y, &tmp) == MP_LT)) { + err = CRYPT_OK; + goto done; + } + + /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ + if ((err = mp_div(&tmp, &key->q, &tmp, &tmp2)) != MP_OKAY) { goto error; } + if (mp_iszero(&tmp2) != MP_YES) { + err = CRYPT_OK; + goto done; + } + + if ((err = mp_exptmod(&key->g, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1) != MP_EQ) { + err = CRYPT_OK; + goto done; + } + + /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ + if ((err = mp_exptmod(&key->y, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1) != MP_EQ) { + err = CRYPT_OK; + goto done; + } + + /* at this point we are out of tests ;-( */ + err = CRYPT_OK; + *stat = 1; + goto done; +error: err = mpi_to_ltc_error(err); +done : mp_clear_multi(&tmp, &tmp2, NULL); + return err; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_addheader.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,25 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +/* add header (metadata) to the stream */ +int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length) +{ + _ARGCHK(eax != NULL); + _ARGCHK(header != NULL); + return omac_process(&eax->headeromac, header, length); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length) +{ + int err; + + _ARGCHK(eax != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + /* omac ciphertext */ + if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) { + return err; + } + + /* decrypt */ + return ctr_decrypt(ct, pt, length, &eax->ctr); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_decrypt_verify_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,60 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *res) +{ + int err; + eax_state eax; + unsigned char buf[MAXBLOCKSIZE]; + unsigned long buflen; + + _ARGCHK(res != NULL); + + /* default to zero */ + *res = 0; + + if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + return err; + } + + if ((err = eax_decrypt(&eax, ct, pt, ctlen)) != CRYPT_OK) { + return err; + } + + buflen = MIN(sizeof(buf), taglen); + if ((err = eax_done(&eax, buf, &buflen)) != CRYPT_OK) { + return err; + } + + /* compare tags */ + if (buflen >= taglen && memcmp(buf, tag, taglen) == 0) { + *res = 1; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_done.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,56 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen) +{ + int err; + unsigned char headermac[MAXBLOCKSIZE], ctmac[MAXBLOCKSIZE]; + unsigned long x, len; + + _ARGCHK(eax != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(taglen != NULL); + + /* finish ctomac */ + len = sizeof(ctmac); + if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) { + return err; + } + + /* finish headeromac */ + + /* note we specifically don't reset len so the two lens are minimal */ + + if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) { + return err; + } + + /* compute N xor H xor C */ + for (x = 0; x < len && x < *taglen; x++) { + tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x]; + } + *taglen = x; + +#ifdef CLEAN_STACK + zeromem(ctmac, sizeof(ctmac)); + zeromem(headermac, sizeof(headermac)); + zeromem(eax, sizeof(*eax)); +#endif + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length) +{ + int err; + + _ARGCHK(eax != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + /* encrypt */ + if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) { + return err; + } + + /* omac ciphertext */ + return omac_process(&eax->ctomac, ct, length); +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_encrypt_authenticate_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen) +{ + int err; + eax_state eax; + + if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + return err; + } + + if ((err = eax_encrypt(&eax, pt, ct, ptlen)) != CRYPT_OK) { + return err; + } + + if ((err = eax_done(&eax, tag, taglen)) != CRYPT_OK) { + return err; + } + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_init.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,106 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen) +{ + unsigned char buf[MAXBLOCKSIZE]; + int err, blklen; + omac_state omac; + unsigned long len; + + + _ARGCHK(eax != NULL); + _ARGCHK(key != NULL); + _ARGCHK(nonce != NULL); + if (headerlen > 0) { + _ARGCHK(header != NULL); + } + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + blklen = cipher_descriptor[cipher].block_length; + + /* N = OMAC_0K(nonce) */ + zeromem(buf, sizeof(buf)); + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + + /* omac the [0]_n */ + if ((err = omac_process(&omac, buf, blklen)) != CRYPT_OK) { + return err; + } + /* omac the nonce */ + if ((err = omac_process(&omac, nonce, noncelen)) != CRYPT_OK) { + return err; + } + /* store result */ + len = sizeof(eax->N); + if ((err = omac_done(&omac, eax->N, &len)) != CRYPT_OK) { + return err; + } + + /* H = OMAC_1K(header) */ + zeromem(buf, sizeof(buf)); + buf[blklen - 1] = 1; + + if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + + /* omac the [1]_n */ + if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) { + return err; + } + /* omac the header */ + if (headerlen != 0) { + if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) { + return err; + } + } + + /* note we don't finish the headeromac, this allows us to add more header later */ + + /* setup the CTR mode */ + if ((err = ctr_start(cipher, eax->N, key, keylen, 0, &eax->ctr)) != CRYPT_OK) { + return err; + } + /* use big-endian counter */ + eax->ctr.mode = 1; + + /* setup the OMAC for the ciphertext */ + if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + + /* omac [2]_n */ + zeromem(buf, sizeof(buf)); + buf[blklen-1] = 2; + if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + zeromem(&omac, sizeof(omac)); +#endif + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eax_test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,271 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* EAX Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef EAX_MODE + +int eax_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + int keylen, + noncelen, + headerlen, + msglen; + + unsigned char key[MAXBLOCKSIZE], + nonce[MAXBLOCKSIZE], + header[MAXBLOCKSIZE], + plaintext[MAXBLOCKSIZE], + ciphertext[MAXBLOCKSIZE], + tag[MAXBLOCKSIZE]; + } tests[] = { + +/* NULL message */ +{ + 16, 0, 0, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0 }, + /* header */ + { 0 }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5, + 0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff } +}, + +/* test with nonce */ +{ + 16, 16, 0, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* header */ + { 0 }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb, + 0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec } +}, + +/* test with header [no nonce] */ +{ + 16, 0, 16, 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0 }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* plaintext */ + { 0 }, + /* ciphertext */ + { 0 }, + /* tag */ + { 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0, + 0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff } +}, + +/* test with header + nonce + plaintext */ +{ + 16, 16, 16, 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* plaintext */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* ciphertext */ + { 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b, + 0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78, + 0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f, + 0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc }, + /* tag */ + { 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e, + 0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 } +}, + +/* test with header + nonce + plaintext [not even sizes!] */ +{ + 16, 15, 14, 29, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e }, + /* header */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d }, + /* plaintext */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c }, + /* ciphertext */ + { 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59, + 0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8, + 0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c, + 0x8a, 0x24, 0xdb, 0x86, 0x8b }, + /* tag */ + { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2, + 0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda } +}, + +/* Vectors from Brian Gladman */ + +{ + 16, 16, 8, 0, + /* key */ + { 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f, + 0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 }, + /* nonce */ + { 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07, + 0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 }, + /* header */ + { 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b }, + /* PT */ + { 0x00 }, + /* CT */ + { 0x00 }, + /* tag */ + { 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b, + 0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 } +}, + +{ + 16, 16, 8, 2, + /* key */ + { 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b, + 0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 }, + /* nonce */ + { 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84, + 0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd }, + /* header */ + { 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa }, + /* PT */ + { 0xf7, 0xfb }, + /* CT */ + { 0x19, 0xdd }, + /* tag */ + { 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda, + 0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 } +}, + +{ + 16, 16, 8, 5, + /* key */ + { 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7, + 0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 }, + /* nonce */ + { 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84, + 0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e }, + /* header */ + { 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 }, + /* PT */ + { 0x1a, 0x47, 0xcb, 0x49, 0x33 }, + /* CT */ + { 0xd8, 0x51, 0xd5, 0xba, 0xe0 }, + /* Tag */ + { 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19, + 0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 } +} + +}; + int err, x, idx, res; + unsigned long len; + unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen, + tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, + tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) { + return err; + } + if (memcmp(outct, tests[x].ciphertext, tests[x].msglen) || memcmp(outtag, tests[x].tag, len)) { +#if 0 + unsigned long y; + printf("\n\nFailure: \nCT:\n"); + for (y = 0; y < (unsigned long)tests[x].msglen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* test decrypt */ + if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen, + tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, + outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) { + return err; + } + if ((res != 1) || memcmp(outct, tests[x].plaintext, tests[x].msglen)) { +#if 0 + unsigned long y; + printf("\n\nFailure (res == %d): \nPT:\n", res); + for (y = 0; y < (unsigned long)tests[x].msglen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\n\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* EAX_MODE */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ecb_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,31 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef ECB + +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); + return CRYPT_OK; +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ecb_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef ECB + +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ecb_start.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef ECB + +int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(key != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + ecb->cipher = cipher; + ecb->blocklen = cipher_descriptor[cipher].block_length; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ecc.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,937 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ + +#include "mycrypt.h" + +#ifdef MECC + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +static const struct { + int size; + char *name, *prime, *B, *order, *Gx, *Gy; +} sets[] = { +#ifdef ECC160 +{ + 20, + "ECC-160", + /* prime */ + "G00000000000000000000000007", + /* B */ + "1oUV2vOaSlWbxr6", + /* order */ + "G0000000000004sCQUtDxaqDUN5", + /* Gx */ + "jpqOf1BHus6Yd/pyhyVpP", + /* Gy */ + "D/wykuuIFfr+vPyx7kQEPu8MixO", +}, +#endif +#ifdef ECC192 +{ + 24, + "ECC-192", + /* prime */ + "/////////////////////l//////////", + + /* B */ + "P2456UMSWESFf+chSYGmIVwutkp1Hhcn", + + /* order */ + "////////////////cTxuDXHhoR6qqYWn", + + /* Gx */ + "68se3h0maFPylo3hGw680FJ/2ls2/n0I", + + /* Gy */ + "1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH" +}, +#endif +#ifdef ECC224 +{ + 28, + "ECC-224", + + /* prime */ + "400000000000000000000000000000000000BV", + + /* B */ + "21HkWGL2CxJIp", + + /* order */ + "4000000000000000000Kxnixk9t8MLzMiV264/", + + /* Gx */ + "jpqOf1BHus6Yd/pyhyVpP", + + /* Gy */ + "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck", +}, +#endif +#ifdef ECC256 +{ + 32, + "ECC-256", + /* Prime */ + "F////y000010000000000000000////////////////", + + /* B */ + "5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B", + + /* Order */ + "F////y00000//////////+yvlgjfnUUXFEvoiByOoLH", + + /* Gx */ + "6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM", + + /* Gy */ + "4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r" +}, +#endif +#ifdef ECC384 +{ + 48, + "ECC-384", + /* prime */ + "//////////////////////////////////////////x/////00000000003/" + "////", + + /* B */ + "ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ" + "x2hl", + + /* Order */ + "////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC" + "nIbp", + + /* Gx and Gy */ + "geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo" + "TWgt", + + "DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG" + "wWvV" +}, +#endif +#ifdef ECC521 +{ + 65, + "ECC-521", + /* prime */ + "V///////////////////////////////////////////////////////////" + "///////////////////////////", + + /* B */ + "56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l" + "JknlmSrSz+8FImqyUz57zHhK3y0", + + /* Order */ + "V//////////////////////////////////////////+b66XuE/BvPhVym1I" + "FS9fT0xjScuYPn7hhjljnwHE6G9", + + /* Gx and Gy */ + "CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19" + "wB/gDupIBF1XMf2c/b+VZ72vRrc", + + "HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0" + "J+j1s4rF726edB2G8Y+b7QVqMPG", +}, +#endif +{ + 0, + NULL, NULL, NULL, NULL, NULL, NULL +} +}; + +#if 0 + +/* you plug in a prime and B value and it finds a pseudo-random base point */ +void ecc_find_base(void) +{ + static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951"; + static char *order = "26959946667150639794667015087019637467111563745054605861463538557247"; + static char *b = "9538957348957353489587"; + mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y; + char buf[4096]; + int i; + + mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); + mp_read_radix(&p, prime, 10); + mp_read_radix(&r, order, 10); + mp_read_radix(&B, b, 10); + + /* get (p+1)/4 */ + mp_add_d(&p, 1, &pp); + mp_div_2(&pp, &pp); + mp_div_2(&pp, &pp); + + buf[0] = 0; + do { + printf("."); fflush(stdout); + /* make a random value of x */ + for (i = 0; i < 16; i++) buf[i+1] = rand() & 255; + mp_read_raw(&x, buf, 17); + mp_copy(&x, &tx); + + /* now compute x^3 - 3x + b */ + mp_expt_d(&x, 3, &tmp1); + mp_mul_d(&x, 3, &tmp2); + mp_sub(&tmp1, &tmp2, &tmp1); + mp_add(&tmp1, &B, &tmp1); + mp_mod(&tmp1, &p, &tmp1); + + /* now compute sqrt via x^((p+1)/4) */ + mp_exptmod(&tmp1, &pp, &p, &tmp2); + mp_copy(&tmp2, &ty); + + /* now square it */ + mp_sqrmod(&tmp2, &p, &tmp2); + + /* tmp2 should equal tmp1 */ + } while (mp_cmp(&tmp1, &tmp2)); + + /* now output values in way that libtomcrypt wants */ + mp_todecimal(&p, buf); + printf("\n\np==%s\n", buf); + mp_tohex(&B, buf); + printf("b==%s\n", buf); + mp_todecimal(&r, buf); + printf("r==%s\n", buf); + mp_tohex(&tx, buf); + printf("Gx==%s\n", buf); + mp_tohex(&ty, buf); + printf("Gy==%s\n", buf); + + mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); +} + +#endif + + + + +static int is_valid_idx(int n) +{ + int x; + + for (x = 0; sets[x].size != 0; x++); + if ((n < 0) || (n >= x)) { + return 0; + } + return 1; +} + +static ecc_point *new_point(void) +{ + ecc_point *p; + p = XMALLOC(sizeof(ecc_point)); + if (p == NULL) { + return NULL; + } + if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) { + XFREE(p); + return NULL; + } + return p; +} + +static void del_point(ecc_point *p) +{ + /* prevents free'ing null arguments */ + if (p != NULL) { + mp_clear_multi(&p->x, &p->y, NULL); + XFREE(p); + } +} + +/* double a point R = 2P, R can be P*/ +static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) +{ + mp_int s, tmp, tmpx; + int err; + + if ((err = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* s = (3Xp^2 + a) / (2Yp) */ + if ((err = mp_mul_2(&P->y, &tmp)) != MP_OKAY) { goto error; } /* tmp = 2*y */ + if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ + if ((err = mp_sqr(&P->x, &s)) != MP_OKAY) { goto error; } /* s = x^2 */ + if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) */ + if ((err = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */ + if (mp_cmp_d(&s, 0) == MP_LT) { /* if s < 0 add modulus */ + if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } + } + if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */ + if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + + /* Xr = s^2 - 2Xp */ + if ((err = mp_sqr(&s, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = s^2 */ + if ((err = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY) { goto error; } /* tmpx = tmpx mod modulus */ + if ((err = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */ + if ((err = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */ + + /* Yr = -Yp + s(Xp - Xr) */ + if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = x - tmpx */ + if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ + if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */ + if ((err = mp_copy(&tmpx, &R->x)) != MP_OKAY) { goto error; } /* x = tmpx */ + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmpx, &tmp, &s, NULL); + return err; +} + +/* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */ +static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu) +{ + mp_int s, tmp, tmpx; + int err; + + if ((err = mp_init(&tmp)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* is P==Q or P==-Q? */ + if (((err = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((err = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) { + mp_clear(&tmp); + return mpi_to_ltc_error(err); + } + + if (mp_cmp(&P->x, &Q->x) == MP_EQ) + if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) { + mp_clear(&tmp); + return dbl_point(P, R, modulus, mu); + } + + if ((err = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) { + mp_clear(&tmp); + return mpi_to_ltc_error(err); + } + + /* get s = (Yp - Yq)/(Xp-Xq) mod p */ + if ((err = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */ + if (mp_cmp_d(&tmp, 0) == MP_LT) { /* if tmp<0 add modulus */ + if ((err = mp_add(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } + } + if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ + if ((err = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */ + if (mp_cmp_d(&s, 0) == MP_LT) { /* if s<0 add modulus */ + if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } + } + if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */ + if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + + /* Xr = s^2 - Xp - Xq */ + if ((err = mp_sqr(&s, &tmp)) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */ + if ((err = mp_reduce(&tmp, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - Px */ + if ((err = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */ + + /* Yr = -Yp + s(Xp - Xr) */ + if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */ + if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ + if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */ + if ((err = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */ + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&s, &tmpx, &tmp, NULL); + return err; +} + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/* perform R = kG where k == integer and G == ecc_point */ +static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) +{ + ecc_point *tG, *M[8]; + int i, j, err; + mp_int mu; + mp_digit buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + /* init barrett reduction */ + if ((err = mp_init(&mu)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) { + mp_clear(&mu); + return mpi_to_ltc_error(err); + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + del_point(M[j]); + } + mp_clear(&mu); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G */ + if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY) { goto error; } + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; } + + /* now find (8+k)G for k=1..7 */ + for (j = 9; j < 16; j++) { + if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK) { goto done; } + } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = k->used - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = k->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the multiplicand */ + i = (buf >> (DIGIT_BIT - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + if ((err = mp_copy(&M[bitbuf-8]->x, &R->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&M[bitbuf-8]->y, &R->y)) != MP_OKAY) { goto error; } + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + } + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ + if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK) { goto done; } + } + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then double/add */ + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1){ + /* first add, so copy */ + if ((err = mp_copy(&tG->x, &R->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&tG->y, &R->y)) != MP_OKAY) { goto error; } + first = 0; + } else { + /* then add */ + if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK) { goto done; } + } + } + } + } + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + del_point(tG); + for (i = 0; i < 8; i++) { + del_point(M[i]); + } + mp_clear(&mu); + return err; +} + +#undef WINSIZE + +int ecc_test(void) +{ + mp_int modulus, order; + ecc_point *G, *GG; + int i, err, primality; + + if ((err = mp_init_multi(&modulus, &order, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + G = new_point(); + GG = new_point(); + if (G == NULL || GG == NULL) { + mp_clear_multi(&modulus, &order, NULL); + del_point(G); + del_point(GG); + return CRYPT_MEM; + } + + for (i = 0; sets[i].size; i++) { + #if 0 + printf("Testing %d\n", sets[i].size); + #endif + if ((err = mp_read_radix(&modulus, (char *)sets[i].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&order, (char *)sets[i].order, 64)) != MP_OKAY) { goto error; } + + /* is prime actually prime? */ + if ((err = is_prime(&modulus, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + /* is order prime ? */ + if ((err = is_prime(&order, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + if ((err = mp_read_radix(&G->x, (char *)sets[i].Gx, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&G->y, (char *)sets[i].Gy, 64)) != MP_OKAY) { goto error; } + + /* then we should have G == (order + 1)G */ + if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY) { goto error; } + if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK) { goto done; } + if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + } + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + del_point(GG); + del_point(G); + mp_clear_multi(&order, &modulus, NULL); + return err; +} + +void ecc_sizes(int *low, int *high) +{ + int i; + _ARGCHK(low != NULL); + _ARGCHK(high != NULL); + + *low = INT_MAX; + *high = 0; + for (i = 0; sets[i].size != 0; i++) { + if (sets[i].size < *low) { + *low = sets[i].size; + } + if (sets[i].size > *high) { + *high = sets[i].size; + } + } +} + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) +{ + int x, err; + ecc_point *base; + mp_int prime; + unsigned char buf[128]; + + _ARGCHK(key != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* find key size */ + for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); + keysize = sets[x].size; + + if (sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + key->idx = x; + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { + return CRYPT_ERROR_READPRNG; + } + + /* setup the key variables */ + if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + base = new_point(); + if (base == NULL) { + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL); + return CRYPT_MEM; + } + + /* read in the specs for this key */ + if ((err = mp_read_radix(&prime, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; } + + /* make the public key */ + if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK) { goto done; } + key->type = PK_PRIVATE; + + /* shrink key */ + if ((err = mp_shrink(&key->k)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY) { goto error; } + + /* free up ram */ + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + del_point(base); + mp_clear(&prime); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +void ecc_free(ecc_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); +} + +static int compress_y_point(ecc_point *pt, int idx, int *result) +{ + mp_int tmp, tmp2, p; + int err; + + _ARGCHK(pt != NULL); + _ARGCHK(result != NULL); + + if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* get x^3 - 3x + b */ + if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */ + if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */ + if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ + if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ + if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */ + if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */ + if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ + + /* now find square root */ + if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ + if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ + if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ + + /* if tmp equals the y point give a 0, otherwise 1 */ + if (mp_cmp(&tmp, &pt->y) == 0) { + *result = 0; + } else { + *result = 1; + } + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&p, &tmp, &tmp2, NULL); + return err; +} + +static int expand_y_point(ecc_point *pt, int idx, int result) +{ + mp_int tmp, tmp2, p; + int err; + + _ARGCHK(pt != NULL); + + if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) { + return CRYPT_MEM; + } + + /* get x^3 - 3x + b */ + if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */ + if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */ + if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ + if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ + if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */ + if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */ + if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ + + /* now find square root */ + if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ + if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ + if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ + + /* if result==0, then y==tmp, otherwise y==p-tmp */ + if (result == 0) { + if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY)) { goto error; } + } else { + if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY)) { goto error; } + } + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&p, &tmp, &tmp2, NULL); + return err; +} + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + unsigned long y, z; + int cp, err; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 3)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* type valid? */ + if (key->type != PK_PRIVATE && type == PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* output type and magic byte */ + y = PACKET_SIZE; + out[y++] = (unsigned char)type; + out[y++] = (unsigned char)sets[key->idx].size; + + /* output x coordinate */ + OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z); + + /* compress y and output it */ + if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) { + return err; + } + out[y++] = (unsigned char)cp; + + if (type == PK_PRIVATE) { + OUTPUT_BIGNUM(&key->k, out, y, z); + } + + /* store header */ + packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY); + *outlen = y; + + return CRYPT_OK; +} + +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + unsigned long x, y, s; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if ((3+PACKET_SIZE) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + y = PACKET_SIZE; + key->type = (int)in[y++]; + s = (unsigned long)in[y++]; + + for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); + if (sets[x].size == 0) { + err = CRYPT_INVALID_KEYSIZE; + goto error; + } + key->idx = (int)x; + + /* type check both values */ + if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* is the key idx valid? */ + if (is_valid_idx(key->idx) != 1) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* load x coordinate */ + INPUT_BIGNUM(&key->pubkey.x, in, x, y, inlen); + + /* load y */ + x = (unsigned long)in[y++]; + if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) { + goto error; + } + + if (key->type == PK_PRIVATE) { + /* load private key */ + INPUT_BIGNUM(&key->k, in, x, y, inlen); + } + + /* eliminate private key if public */ + if (key->type == PK_PUBLIC) { + mp_clear(&key->k); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); + return err; +} + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y; + ecc_point *result; + mp_int prime; + int err; + + _ARGCHK(private_key != NULL); + _ARGCHK(public_key != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* type valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (private_key->idx != public_key->idx) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* make new point */ + result = new_point(); + if (result == NULL) { + return CRYPT_MEM; + } + + if ((err = mp_init(&prime)) != MP_OKAY) { + del_point(result); + return mpi_to_ltc_error(err); + } + + if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; } + + x = (unsigned long)mp_unsigned_bin_size(&result->x); + y = (unsigned long)mp_unsigned_bin_size(&result->y); + + if (*outlen < (x+y)) { + err = CRYPT_BUFFER_OVERFLOW; + goto done1; + } + *outlen = x+y; + if ((err = mp_to_unsigned_bin(&result->x, out)) != MP_OKAY) { goto error; } + if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY) { goto error; } + + err = CRYPT_OK; + goto done1; +error: + err = mpi_to_ltc_error(err); +done1: + mp_clear(&prime); + del_point(result); + return err; +} + +int ecc_get_size(ecc_key *key) +{ + _ARGCHK(key != NULL); + if (is_valid_idx(key->idx)) + return sets[key->idx].size; + else + return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ +} + +#include "ecc_sys.c" + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ecc_sys.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,432 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + ecc_key *key) +{ + unsigned char pub_expt[256], ecc_shared[256], skey[MAXBLOCKSIZE]; + ecc_key pubkey; + unsigned long x, y, z, hashsize, pubkeysize; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(out != NULL); + _ARGCHK(len != NULL); + _ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (keylen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = (unsigned long)sizeof(pub_expt); + if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + + /* now check if the out buffer is big enough */ + if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) { + ecc_free(&pubkey); + return CRYPT_BUFFER_OVERFLOW; + } + + /* make random key */ + hashsize = hash_descriptor[hash].hashsize; + x = (unsigned long)sizeof(ecc_shared); + if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + ecc_free(&pubkey); + z = (unsigned long)sizeof(skey); + if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); + + /* output header */ + y = PACKET_SIZE; + + /* size of hash name and the name itself */ + out[y++] = hash_descriptor[hash].ID; + + /* length of ECC pubkey and the key itself */ + STORE32L(pubkeysize, out+y); + y += 4; + + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = pub_expt[x]; + } + + STORE32L(keylen, out+y); + y += 4; + + /* Encrypt/Store the encrypted key */ + for (x = 0; x < keylen; x++, y++) { + out[y] = skey[x] ^ inkey[x]; + } + *len = y; + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(pub_expt, sizeof(pub_expt)); + zeromem(ecc_shared, sizeof(ecc_shared)); + zeromem(skey, sizeof(skey)); +#endif + return CRYPT_OK; +} + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + ecc_key *key) +{ + unsigned char shared_secret[256], skey[MAXBLOCKSIZE]; + unsigned long x, y, z, hashsize, keysize; + int hash, err; + ecc_key pubkey; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* correct length ? */ + if (inlen < PACKET_SIZE+1+4+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+1+4+4; + } + + /* is header correct? */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* now lets get the hash name */ + y = PACKET_SIZE; + hash = find_hash_id(in[y++]); + if (hash == -1) { + return CRYPT_INVALID_HASH; + } + + /* common values */ + hashsize = hash_descriptor[hash].hashsize; + + /* get public key */ + LOAD32L(x, in+y); + if (inlen < x) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= x; + } + y += 4; + if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* make shared key */ + x = (unsigned long)sizeof(shared_secret); + if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + ecc_free(&pubkey); + + z = (unsigned long)sizeof(skey); + if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + return err; + } + + LOAD32L(keysize, in+y); + if (inlen < keysize) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= keysize; + } + y += 4; + + if (*keylen < keysize) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* Decrypt the key */ + for (x = 0; x < keysize; x++, y++) { + outkey[x] = skey[x] ^ in[y]; + } + + *keylen = keysize; + + err = CRYPT_OK; +done: +#ifdef CLEAN_STACK + zeromem(shared_secret, sizeof(shared_secret)); + zeromem(skey, sizeof(skey)); +#endif + return err; +} + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key) +{ + ecc_key pubkey; + mp_int b, p; + unsigned char epubkey[256], er[256]; + unsigned long x, y, pubkeysize, rsize; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* is this a private key? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* is the IDX valid ? */ + if (is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* make up a key and export the public copy */ + if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = (unsigned long)sizeof(epubkey); + if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + + /* get the hash and load it as a bignum into 'b' */ + /* init the bignums */ + if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { + ecc_free(&pubkey); + return mpi_to_ltc_error(err); + } + if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } + + /* find b = (m - x)/k */ + if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */ + if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */ + if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */ + + /* export it */ + rsize = (unsigned long)mp_unsigned_bin_size(&b); + if (rsize > (unsigned long)sizeof(er)) { + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; } + + /* now lets check the outlen before we write */ + if (*outlen < (12 + rsize + pubkeysize)) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* lets output */ + y = PACKET_SIZE; + + /* size of public key */ + STORE32L(pubkeysize, out+y); + y += 4; + + /* copy the public key */ + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = epubkey[x]; + } + + /* size of 'r' */ + STORE32L(rsize, out+y); + y += 4; + + /* copy r */ + for (x = 0; x < rsize; x++, y++) { + out[y] = er[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED); + + /* clear memory */ + *outlen = y; + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&b, &p, NULL); + ecc_free(&pubkey); +#ifdef CLEAN_STACK + zeromem(er, sizeof(er)); + zeromem(epubkey, sizeof(epubkey)); +#endif + return err; +} + +/* verify that mG = (bA + Y) + * + * The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the + * public key Y = xG can verify it. + * + * b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it] + * A = kG therefore bA == ((m-x)/k)kG == (m-x)G + * + * Adding Y = xG to the bA gives us (m-x)G + xG == mG + * + * The user given only xG, kG and b cannot determine k or x which means they can't find the private key. + * + */ +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, ecc_key *key) +{ + ecc_point *mG; + ecc_key pubkey; + mp_int b, p, m, mu; + unsigned long x, y; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + if (siglen < PACKET_SIZE+4+4) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= PACKET_SIZE+4+4; + } + + /* is the message format correct? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get hash name */ + y = PACKET_SIZE; + + /* get size of public key */ + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + y += 4; + + /* load the public key */ + if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* load size of 'b' */ + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + y += 4; + + /* init values */ + if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) { + ecc_free(&pubkey); + return mpi_to_ltc_error(err); + } + + mG = new_point(); + if (mG == NULL) { + mp_clear_multi(&b, &m, &p, &mu, NULL); + ecc_free(&pubkey); + return CRYPT_MEM; + } + + /* load b */ + if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY) { goto error; } + y += x; + + /* get m in binary a bignum */ + if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)inlen)) != MP_OKAY) { goto error; } + + /* load prime */ + if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + + /* calculate barrett stuff */ + mp_set(&mu, 1); + mp_lshd(&mu, 2 * USED(&p)); + if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY) { goto error; } + + /* get bA */ + if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK) { goto done; } + + /* get bA + Y */ + if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } + + /* get mG */ + if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } + if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK) { goto done; } + + /* compare mG to bA + Y */ + if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) { + *stat = 1; + } + + /* clear up and return */ + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + del_point(mG); + ecc_free(&pubkey); + mp_clear_multi(&p, &m, &b, &mu, NULL); + return err; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/ch1-01.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,18 @@ +/* + * Name : ch1-01.c + * Purpose : Demonstration of a basic libtomcrypt program + * Author : Tom St Denis + * + * History : v0.79 Initial release + */ + +/* ch1-01-1 */ +/* Include the default headers and libtomcrypt headers */ +#include <mycrypt.h> + +int main(void) +{ + return 0; +} +/* ch1-01-1 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/ch1-02.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,25 @@ +/* + * Name : ch1-02.c + * Purpose : Demonstration of error handling + * Author : Tom St Denis + * + * History : v0.79 Initial release + */ + +/* ch1-01-1 */ +#include <mycrypt.h> + +int main(void) +{ + int errno; + + if ((errno = some_func(...)) != CRYPT_OK) { + printf("Error: %s\n", error_to_string(errno)); + return EXIT_FAILURE; + } + + return 0; +} +/*ch1-01-1 */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/ch1-03.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* + * Name : ch1-03.c + * Purpose : Demonstration of variable length outputs + * Author : Tom St Denis + * + * History : v0.79 Initial release + */ + + /* ch1-01-1 */ + #include <mycrypt.h> + + int main(void) + { + unsigned long length; + unsigned char buffer[512]; + int errno; + + length = sizeof(buffer); + if ((errno = some_func(..., buffer, &length)) != CRYPT_OK) { + printf("Error: %s\n", error_to_string(errno)); + return EXIT_FAILURE; + } + printf("Size of output is %lu bytes\n", length); + return 0; +} +/* ch1-01-1 */ + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/ch2-01.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,35 @@ +/* + * Name : ch2-01.c + * Purpose : Demonstration of reading the RNG + * Author : Tom St Denis + * + * History : v0.81 Initial release + */ + + /* ch2-02-2 */ + #include <mycrypt.h> + + int main(void) + { + unsigned char buf[16]; + unsigned long len; + int ix; + + /* read the RNG */ + len = rng_get_bytes(buf, sizeof(buf), NULL); + + /* verify return */ + if (len != sizeof(buf)) { + printf("Error: Only read %lu bytes.\n", len); + } else { + printf("Read %lu bytes\n", len); + for (ix = 0; ix < sizeof(buf); ix++) { + printf("%02x ", buf[ix]); + } + printf("\n"); + } + + return EXIT_SUCCESS; +} +/* ch2-02-2 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gf.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,305 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* polynomial basis GF(2^w) routines */ +#include "mycrypt.h" + +#ifdef GF + +#define FORLOOP for (i = 0; i < LSIZE; i++) + +/* c = a + b */ +void gf_add(gf_intp a, gf_intp b, gf_intp c) +{ + int i; + FORLOOP c[i] = a[i]^b[i]; +} + +/* b = a */ +void gf_copy(gf_intp a, gf_intp b) +{ + int i; + FORLOOP b[i] = a[i]; +} + +/* a = 0 */ +void gf_zero(gf_intp a) +{ + int i; + FORLOOP a[i] = 0; +} + +/* is a zero? */ +int gf_iszero(gf_intp a) +{ + int i; + FORLOOP if (a[i]) { + return 0; + } + return 1; +} + +/* is a one? */ +int gf_isone(gf_intp a) +{ + int i; + for (i = 1; i < LSIZE; i++) { + if (a[i]) { + return 0; + } + } + return a[0] == 1; +} + +/* b = a << 1*/ +void gf_shl(gf_intp a, gf_intp b) +{ + int i; + gf_int tmp; + + gf_copy(a, tmp); + for (i = LSIZE-1; i > 0; i--) + b[i] = ((tmp[i]<<1)|((tmp[i-1]&0xFFFFFFFFUL)>>31))&0xFFFFFFFFUL; + b[0] = (tmp[0] << 1)&0xFFFFFFFFUL; + gf_zero(tmp); +} + +/* b = a >> 1 */ +void gf_shr(gf_intp a, gf_intp b) +{ + int i; + gf_int tmp; + + gf_copy(a, tmp); + for (i = 0; i < LSIZE-1; i++) + b[i] = (((tmp[i]&0xFFFFFFFFUL)>>1)|(tmp[i+1]<<31))&0xFFFFFFFFUL; + b[LSIZE-1] = (tmp[LSIZE-1]&0xFFFFFFFFUL)>>1; + gf_zero(tmp); +} + +/* returns -1 if its zero, otherwise degree of a */ +int gf_deg(gf_intp a) +{ + int i, ii; + unsigned long t; + + ii = -1; + for (i = LSIZE-1; i >= 0; i--) + if (a[i]) { + for (t = a[i], ii = 0; t; t >>= 1, ++ii); + break; + } + if (i == -1) i = 0; + return (i<<5)+ii; +} + +/* c = ab */ +void gf_mul(gf_intp a, gf_intp b, gf_intp c) +{ + gf_int ta, tb; + int i, n; + + gf_copy(a, ta); + gf_copy(b, tb); + gf_zero(c); + n = gf_deg(ta)+1; + for (i = 0; i < n; i++) { + if (ta[i>>5]&(1<<(i&31))) + gf_add(c, tb, c); + gf_shl(tb, tb); + } + gf_zero(ta); + gf_zero(tb); +} + +/* q = a/b, r = a%b */ +void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r) +{ + gf_int ta, tb, shifts[LSIZE*32]; + int i, magb, mag; + + mag = gf_deg(a); + magb = gf_deg(b); + + /* special cases */ + if (magb > mag) { + gf_copy(a, r); + gf_zero(q); + return; + } + if (magb == -1) { + return; + } + + /* copy locally */ + gf_copy(a, ta); + gf_copy(b, tb); + gf_zero(q); + + /* make shifted versions of "b" */ + gf_copy(tb, shifts[0]); + for (i = 1; i <= (mag-magb); i++) + gf_shl(shifts[i-1], shifts[i]); + + while (mag >= magb) { + i = (mag - magb); + q[i>>5] |= (1<<(i&31)); + gf_add(ta, shifts[i], ta); + mag = gf_deg(ta); + } + gf_copy(ta, r); + gf_zero(ta); + gf_zero(tb); + zeromem(shifts, sizeof(shifts)); +} + +/* b = a mod m */ +void gf_mod(gf_intp a, gf_intp m, gf_intp b) +{ + gf_int tmp; + gf_div(a,m,tmp,b); + gf_zero(tmp); +} + +/* c = ab (mod m) */ +void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c) +{ + gf_int tmp; + gf_mul(a, b, tmp); + gf_mod(tmp, m, c); + gf_zero(tmp); +} + +/* B = 1/A mod M */ +void gf_invmod(gf_intp A, gf_intp M, gf_intp B) +{ + gf_int m, n, p0, p1, p2, r, q, tmp; + + /* put all variables in known setup state */ + gf_zero(p0); + gf_zero(p2); + gf_copy(M, m); + gf_copy(A, n); + p0[0] = 1; + gf_div(m, n, p1, r); + gf_copy(p1, q); + + /* loop until r == 0 */ + while (!gf_iszero(r)) { + gf_copy(n, m); + gf_copy(r, n); + gf_div(m, n, q, r); + gf_mul(q, p1, tmp); + gf_add(tmp, p0, p2); + gf_copy(p1, p0); + gf_copy(p2, p1); + } + gf_copy(p0, B); + gf_zero(p0); +} + +/* find a square root modulo a prime. Note the number of + * elements is 2^k - 1, so we must square k-2 times to get the + * square root.. + */ +void gf_sqrt(gf_intp a, gf_intp M, gf_intp b) +{ + int k; + k = gf_deg(M)-2; + gf_copy(a, b); + while (k--) + gf_mulmod(b, b, M, b); +} + +/* c = gcd(A,B) */ +void gf_gcd(gf_intp A, gf_intp B, gf_intp c) +{ + gf_int a, b, r; + int n; + + gf_add(A, B, r); + n = gf_deg(r); + if (gf_deg(A) > n) { + gf_copy(A, a); + gf_copy(B, b); + } else { + gf_copy(A, b); + gf_copy(B, a); + } + + do { + gf_mod(a, b, r); + gf_copy(b, a); + gf_copy(r, b); + } while (!gf_iszero(r)); + gf_copy(a, c); + gf_zero(a); + gf_zero(b); +} + +/* returns non-zero if 'a' is irreducible */ +int gf_is_prime(gf_intp a) +{ + gf_int u, tmp; + int m, n; + + gf_zero(u); + u[0] = 2; /* u(x) = x */ + m = gf_deg(a); + for (n = 0; n < (m/2); n++) { + gf_mulmod(u, u, a, u); /* u(x) = u(x)^2 mod a(x) */ + gf_copy(u, tmp); + tmp[0] ^= 2; /* tmp(x) = u(x) - x */ + gf_gcd(tmp, a, tmp); /* tmp(x) = gcd(a(x), u(x) - x) */ + if (!gf_isone(tmp)) { + return 0; + } + } + return 1; +} + +/* returns bytes required to store a gf_int */ +int gf_size(gf_intp a) +{ + int n; + + n = gf_deg(a); + if (n == -1) { + return 4; + } + n = n + (32 - (n&31)); + return n/8; +} + +/* store a gf_int */ +void gf_toraw(gf_intp a, unsigned char *dst) +{ + int x, n; + n = gf_size(a)/4; + for (x = 0; x < n; x++) { + STORE32L(a[x], dst); + dst += 4; + } +} + +/* read a gf_int (len == in bytes) */ +void gf_readraw(gf_intp a, unsigned char *str, int len) +{ + int x; + gf_zero(a); + for (x = 0; x < len/4; x++) { + LOAD32L(a[x], str); + str += 4; + } +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hash_file.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + FILE *in; + int err; + _ARGCHK(fname != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + err = hash_filehandle(hash, in, dst, outlen); + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + return err; +#endif +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hash_filehandle.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + hash_state md; + unsigned char buf[512]; + size_t x; + int err; + + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(in != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = hash_descriptor[hash].hashsize; + + hash_descriptor[hash].init(&md); + do { + x = fread(buf, 1, sizeof(buf), in); + hash_descriptor[hash].process(&md, buf, x); + } while (x == sizeof(buf)); + hash_descriptor[hash].done(&md, dst); + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +#endif +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hash_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen) +{ + hash_state md; + int err; + + _ARGCHK(data != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = hash_descriptor[hash].hashsize; + + hash_descriptor[hash].init(&md); + hash_descriptor[hash].process(&md, data, len); + hash_descriptor[hash].done(&md, dst); + return CRYPT_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_done.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen) +{ + unsigned char buf[MAXBLOCKSIZE]; + unsigned char isha[MAXBLOCKSIZE]; + unsigned long hashsize, i; + int hash, err; + + _ARGCHK(hmac != NULL); + _ARGCHK(hashOut != NULL); + + hash = hmac->hash; + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* get the hash message digest size */ + hashsize = hash_descriptor[hash].hashsize; + + // Get the hash of the first HMAC vector plus the data + if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { + return err; + } + + // Create the second HMAC vector vector for step (3) + for(i=0; i < HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x5C; + } + + // Now calculate the "outer" hash for step (5), (6), and (7) + hash_descriptor[hash].init(&hmac->md); + hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE); + hash_descriptor[hash].process(&hmac->md, isha, hashsize); + hash_descriptor[hash].done(&hmac->md, buf); + + // copy to output + for (i = 0; i < hashsize && i < *outlen; i++) { + hashOut[i] = buf[i]; + } + *outlen = i; + +#ifdef CLEAN_STACK + zeromem(isha, sizeof(buf)); + zeromem(buf, sizeof(isha)); + zeromem(hmac, sizeof(*hmac)); +#endif + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_file.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/* hmac_file added by Tom St Denis */ +int hmac_file(int hash, const char *fname, + const unsigned char *key, unsigned long keylen, + unsigned char *dst, unsigned long *dstlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + hmac_state hmac; + FILE *in; + unsigned char buf[512]; + size_t x; + int err; + + _ARGCHK(fname != NULL); + _ARGCHK(key != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(dstlen != NULL); + + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + /* process the file contents */ + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) { + /* we don't trap this error since we're already returning an error! */ + fclose(in); + return err; + } + } while (x == sizeof(buf)); + + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + /* get final hmac */ + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + /* clear memory */ + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +#endif +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_init.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) +{ + unsigned char buf[MAXBLOCKSIZE]; + unsigned long hashsize; + unsigned long i, z; + int err; + + _ARGCHK(hmac != NULL); + _ARGCHK(key != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* valid key length? */ + if (keylen == 0) { + return CRYPT_INVALID_KEYSIZE; + } + + hmac->hash = hash; + + // (1) make sure we have a large enough key + hashsize = hash_descriptor[hash].hashsize; + if(keylen > HMAC_BLOCKSIZE) { + z = (unsigned long)sizeof(hmac->key); + if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { + return err; + } + if(hashsize < HMAC_BLOCKSIZE) { + zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize)); + } + keylen = hashsize; + } else { + memcpy(hmac->key, key, (size_t)keylen); + if(keylen < HMAC_BLOCKSIZE) { + zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen)); + } + } + + // Create the initial vector for step (3) + for(i=0; i < HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x36; + } + + // Pre-pend that to the hash data + hash_descriptor[hash].init(&hmac->md); + hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE); + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,67 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, + const unsigned char *data, unsigned long len, + unsigned char *dst, unsigned long *dstlen) +{ + hmac_state hmac; + int err; + + _ARGCHK(key != NULL); + _ARGCHK(data != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(dstlen != NULL); + + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_process(&hmac, data, len)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_process.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,48 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len) +{ + int err; + _ARGCHK(hmac != NULL); + _ARGCHK(buf != NULL); + if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { + return err; + } + return hash_descriptor[hmac->hash].process(&hmac->md, buf, len); +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hmac_test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,325 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submited by Dobes Vandermeer ([email protected]) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/* + + TEST CASES SOURCE: + +Network Working Group P. Cheng +Request for Comments: 2202 IBM +Category: Informational R. Glenn + NIST + September 1997 + + Test Cases for HMAC-MD5 and HMAC-SHA-1 +*/ + + +int hmac_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char digest[MAXBLOCKSIZE]; + int i; + + static const struct hmac_test_case { + int num; + char *algo; + unsigned char key[128]; + unsigned long keylen; + unsigned char data[128]; + unsigned long datalen; + unsigned char digest[MAXBLOCKSIZE]; + } cases[] = { + /* + 3. Test Cases for HMAC-SHA-1 + + test_case = 1 + key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b + key_len = 20 + data = "Hi Ther 20 + digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 + digest-96 = 0x4c1a03424b55e07fe7f27be1 + */ + { 5, "sha1", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c}, 20, + "Test With Truncation", 20, + {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} }, + + /* + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash Key First" + data_len = 54 + digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 + */ + { 6, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, + 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, + 0xed, 0x40, 0x21, 0x12} }, + + /* + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 + */ + { 7, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, + 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} }, + + /* + 2. Test Cases for HMAC-MD5 + + test_case = 1 + key = 0x0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + key_len = 16 + data = "Hi There" + data_len = 8 + digest = 0x92 94 72 7a + 36 38 bb 1c + 13 f4 8e f8 + 15 8b fc 9d + */ + { 1, "md5", + {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16, + "Hi There", 8, + {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} }, + /* + test_case = 2 + key = "Jefe" + key_len = 4 + data = "what do ya want for nothing?" + data_len = 28 + digest = 0x750c783e6ab0b503eaa86e310a5db738 + */ + { 2, "md5", + "Jefe", 4, + "what do ya want for nothing?", 28, + {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} }, + + /* + test_case = 3 + key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + key_len 16 + data = 0xdd repeated 50 times + data_len = 50 + digest = 0x56be34521d144c88dbb8c733f0e8b3f6 + */ + { 3, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16, + {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50, + {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} }, + /* + + test_case = 4 + key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 + key_len 25 + data = 0xcd repeated 50 times + data_len = 50 + digest = 0x697eaf0aca3a3aea3a75164746ffaa79 + */ + { 4, "md5", + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19}, 25, + {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50, + {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} }, + + + /* + + test_case = 5 + key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c + key_len = 16 + data = "Test With Truncation" + data_len = 20 + digest = 0x56461ef2342edc00f9bab995690efd4c + digest-96 0x56461ef2342edc00f9bab995 + */ + { 5, "md5", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16, + "Test With Truncation", 20, + {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} }, + + /* + + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash +Key First" + data_len = 54 + digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd + */ + { 6, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} }, + + /* + + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0x6f630fad67cda0ee1fb1f562db3aa53e + */ + { 7, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} } + }; + + unsigned long outlen; + int err; + int tested=0,failed=0; + for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + int hash = find_hash(cases[i].algo); + if (hash == -1) continue; + ++tested; + outlen = sizeof(digest); + if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) { +#if 0 + printf("HMAC-%s test #%d\n", cases[i].algo, cases[i].num); +#endif + return err; + } + + if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) { +#if 0 + unsigned int j; + printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num); + printf( "Result: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", digest[j]); + } + printf("\nCorrect: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", cases[i].digest[j]); + } + printf("\n"); +#endif + failed++; + //return CRYPT_ERROR; + } else { + /* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */ + } + } + + if (failed != 0) { + return CRYPT_FAIL_TESTVECTOR; + } else if (tested == 0) { + return CRYPT_NOP; + } else { + return CRYPT_OK; + } + #endif +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/is_prime.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MPI + +/* figures out if a number is prime (MR test) */ +int is_prime(mp_int *N, int *result) +{ + int err; + _ARGCHK(N != NULL); + _ARGCHK(result != NULL); + if ((err = mp_prime_is_prime(N, mp_prime_rabin_miller_trials(mp_count_bits(N)), result)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/keyring.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,862 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Provides keyring functionality for libtomcrypt, Tom St Denis */ +#include <mycrypt.h> + +#ifdef KR + +static const unsigned char key_magic[4] = { 0x12, 0x34, 0x56, 0x78 }; +static const unsigned char file_magic[4] = { 0x9A, 0xBC, 0xDE, 0xF0 }; +static const unsigned char sign_magic[4] = { 0x87, 0x56, 0x43, 0x21 }; +static const unsigned char enc_magic[4] = { 0x0F, 0xED, 0xCB, 0xA9 }; + +static const unsigned long crc_table[256] = { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +}; + +#define DO1(buf) crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len) +{ + //_ARGCHK(buf != NULL && len == 0); + crc = crc ^ 0xffffffffL; + while (len >= 8) { + DO8 (buf); + len -= 8; + } + + if (len > 0) { + do { + DO1 (buf); + } while (--len > 0); + } + return crc ^ 0xffffffffUL; +} + +int kr_init(pk_key **pk) +{ + _ARGCHK(pk != NULL); + + *pk = XCALLOC(1, sizeof(pk_key)); + if (*pk == NULL) { + return CRYPT_MEM; + } + (*pk)->system = NON_KEY; + return CRYPT_OK; +} + +unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description) +{ + unsigned long crc; + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + crc = crc32(0UL, NULL, 0UL); + crc = crc32(crc, name, (unsigned long)MIN(MAXLEN, strlen((char *)name))); + crc = crc32(crc, email, (unsigned long)MIN(MAXLEN, strlen((char *)email))); + return crc32(crc, description, (unsigned long)MIN(MAXLEN, strlen((char *)description))); +} + +pk_key *kr_find(pk_key *pk, unsigned long ID) +{ + _ARGCHK(pk != NULL); + + while (pk != NULL) { + if (pk->system != NON_KEY && pk->ID == ID) { + return pk; + } + pk = pk->next; + } + return NULL; +} + +pk_key *kr_find_name(pk_key *pk, const char *name) +{ + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + + while (pk != NULL) { + if (pk->system != NON_KEY && strncmp((char *)pk->name, (char *)name, sizeof(pk->name)-1) == 0) { + return pk; + } + pk = pk->next; + } + return NULL; +} + + +int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name, + const unsigned char *email, const unsigned char *description, const _pk_key *key) +{ + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + _ARGCHK(key != NULL); + + /* check parameters */ + if (key_type != PK_PRIVATE && key_type != PK_PRIVATE_OPTIMIZED && key_type != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + if (sys != RSA_KEY && sys != DH_KEY && sys != ECC_KEY) { + return CRYPT_PK_INVALID_SYSTEM; + } + + /* see if its a dupe */ + if (kr_find(pk, kr_crc(name, email, description)) != NULL) { + return CRYPT_PK_DUP; + } + + /* find spot in key ring */ + while (pk->system != NON_KEY) { + if (pk->next == NULL) { + return CRYPT_ERROR; + } + pk = pk->next; + } + + /* now we have a spot make a next spot */ + pk->next = XCALLOC(1, sizeof(pk_key)); + if (pk->next == NULL) { + return CRYPT_MEM; + } + pk->next->system = NON_KEY; + + /* now add this new data to this ring spot */ + pk->key_type = key_type; + pk->system = sys; + strncpy((char *)pk->name, (char *)name, sizeof(pk->name)-1); + strncpy((char *)pk->email, (char *)email, sizeof(pk->email)-1); + strncpy((char *)pk->description, (char *)description, sizeof(pk->description)-1); + pk->ID = kr_crc(pk->name, pk->email, pk->description); + + /* clear the memory area */ + zeromem(&(pk->key), sizeof(pk->key)); + + /* copy the key */ + switch (sys) { + case RSA_KEY: + memcpy(&(pk->key.rsa), &(key->rsa), sizeof(key->rsa)); + break; + case DH_KEY: + memcpy(&(pk->key.dh), &(key->dh), sizeof(key->dh)); + break; + case ECC_KEY: + memcpy(&(pk->key.ecc), &(key->ecc), sizeof(key->ecc)); + break; + } + return CRYPT_OK; +} + +int kr_del(pk_key **_pk, unsigned long ID) +{ + pk_key *ppk, *pk; + + _ARGCHK(_pk != NULL); + + pk = *_pk; + ppk = NULL; + while (pk->system != NON_KEY && pk->ID != ID) { + ppk = pk; + pk = pk->next; + if (pk == NULL) { + return CRYPT_PK_NOT_FOUND; + } + } + + switch (pk->system) { + case RSA_KEY: + rsa_free(&(pk->key.rsa)); + break; + case DH_KEY: + dh_free(&(pk->key.dh)); + break; + case ECC_KEY: + ecc_free(&(pk->key.ecc)); + break; + } + + if (ppk == NULL) { /* the first element matches the ID */ + ppk = pk->next; /* get the 2nd element */ + XFREE(pk); /* free the first */ + *_pk = ppk; /* make the first element the second */ + } else { /* (not) first element matches the ID */ + ppk->next = pk->next; /* make the previous'es next point to the current next */ + XFREE(pk); /* free the element */ + } + return CRYPT_OK; +} + +int kr_clear(pk_key **pk) +{ + int err; + _ARGCHK(pk != NULL); + + while ((*pk)->system != NON_KEY) { + if ((err = kr_del(pk, (*pk)->ID)) != CRYPT_OK) { + return err; + } + } + XFREE(*pk); + *pk = NULL; + return CRYPT_OK; +} + +static unsigned long _write(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr) +{ +#ifdef NO_FILE + return 0; +#else + _ARGCHK(buf != NULL); + _ARGCHK(f != NULL); + if (ctr != NULL) { + if (ctr_encrypt(buf, buf, len, ctr) != CRYPT_OK) { + return 0; + } + } + return (unsigned long)fwrite(buf, 1, (size_t)len, f); +#endif +} + +static unsigned long _read(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr) +{ +#ifdef NO_FILE + return 0; +#else + unsigned long y; + _ARGCHK(buf != NULL); + _ARGCHK(f != NULL); + y = (unsigned long)fread(buf, 1, (size_t)len, f); + if (ctr != NULL) { + if (ctr_decrypt(buf, buf, y, ctr) != CRYPT_OK) { + return 0; + } + } + return y; +#endif +} + +int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192], *obuf; + pk_key *ppk; + unsigned long len; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the desired key */ + ppk = kr_find(pk, ID); + if (ppk == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + if (ppk->key_type == PK_PUBLIC && key_type != PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* this makes PK_PRIVATE an alias for PK_PRIVATE_OPTIMIZED type */ + if (ppk->key_type == PK_PRIVATE_OPTIMIZED && key_type == PK_PRIVATE) { + key_type = PK_PRIVATE_OPTIMIZED; + } + + /* now copy the header and various other details */ + memcpy(buf, key_magic, 4); /* magic info */ + buf[4] = key_type; /* key type */ + buf[5] = ppk->system; /* system */ + STORE32L(ppk->ID, buf+6); /* key ID */ + memcpy(buf+10, ppk->name, MAXLEN); /* the name */ + memcpy(buf+10+MAXLEN, ppk->email, MAXLEN); /* the email */ + memcpy(buf+10+MAXLEN+MAXLEN, ppk->description, MAXLEN); /* the description */ + + /* export key */ + len = sizeof(buf) - (6 + 4 + MAXLEN*3); + obuf = buf+6+4+MAXLEN*3; + switch (ppk->system) { + case RSA_KEY: + if ((err = rsa_export(obuf, &len, key_type, &(ppk->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_export(obuf, &len, key_type, &(ppk->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_export(obuf, &len, key_type, &(ppk->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + + /* get the entire length of the packet */ + len += 6 + 4 + 3*MAXLEN; + + if (*outlen < len) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + *outlen = len; + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; + } +} + +int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen) +{ + _pk_key key; + int sys, key_type, err; + unsigned long ID; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + + if (inlen < 10) { + return CRYPT_INVALID_PACKET; + } + + if (memcmp(in, key_magic, 4) != 0) { + return CRYPT_INVALID_PACKET; + } + key_type = in[4]; /* get type */ + sys = in[5]; /* get system */ + LOAD32L(ID,in+6); /* the ID */ + + if (ID != kr_crc(in+10, in+10+MAXLEN, in+10+MAXLEN+MAXLEN)) { + return CRYPT_INVALID_PACKET; + } + + zeromem(&key, sizeof(key)); + + /* size of remaining packet */ + inlen -= 10 + 3*MAXLEN; + + switch (sys) { + case RSA_KEY: + if ((err = rsa_import(in+10+3*MAXLEN, inlen, &(key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_import(in+10+3*MAXLEN, inlen, &(key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_import(in+10+3*MAXLEN, inlen, &(key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + return kr_add(pk, key_type, sys, + in+10, /* the name */ + in+10+MAXLEN, /* email address */ + in+10+MAXLEN+MAXLEN, /* description */ + &key); +} + + +int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr) +{ + unsigned char buf[8192], blen[4]; + unsigned long len; + int res, err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + + /* init keyring */ + if ((err = kr_init(pk)) != CRYPT_OK) { + return err; + } + + /* read in magic bytes */ + if (_read(buf, 6, in, ctr) != 6) { goto done2; } + + if (memcmp(buf, file_magic, 4) != 0) { + return CRYPT_INVALID_PACKET; + } + + len = (unsigned long)buf[4] | ((unsigned long)buf[5] << 8); + if (len > CRYPT) { + return CRYPT_INVALID_PACKET; + } + + /* while there are lengths to read... */ + while (_read(blen, 4, in, ctr) == 4) { + /* get length */ + LOAD32L(len, blen); + + if (len > (unsigned long)sizeof(buf)) { + return CRYPT_INVALID_PACKET; + } + + if (_read(buf, len, in, ctr) != len) { goto done2; } + if ((err = kr_import(*pk, buf, len)) != CRYPT_OK) { + return err; + } + } + + res = CRYPT_OK; + goto done; +done2: + res = CRYPT_ERROR; +done: +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return res; +} + +int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr) +{ + unsigned char buf[8192], blen[4]; + unsigned long len; + int res, err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + + /* write out magic bytes */ + memcpy(buf, file_magic, 4); + buf[4] = (unsigned char)(CRYPT&255); + buf[5] = (unsigned char)((CRYPT>>8)&255); + if (_write(buf, 6, out, ctr) != 6) { goto done2; } + + while (pk->system != NON_KEY) { + len = sizeof(buf); + if ((err = kr_export(pk, pk->ID, pk->key_type, buf, &len)) != CRYPT_OK) { + return err; + } + + STORE32L(len, blen); + if (_write(blen, 4, out, ctr) != 4) { goto done2; } + if (_write(buf, len, out, ctr) != len) { goto done2; } + + pk = pk->next; + } + + res = CRYPT_OK; + goto done; +done2: + res = CRYPT_ERROR; +done: +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return res; +} + +int kr_make_key(pk_key *pk, prng_state *prng, int wprng, + int sys, int keysize, const unsigned char *name, + const unsigned char *email, const unsigned char *description) +{ + _pk_key key; + int key_type, err; + + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + + /* valid PRNG? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* make the key first */ + zeromem(&key, sizeof(key)); + switch (sys) { + case RSA_KEY: + if ((err = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) { + return err; + } + key_type = key.rsa.type; + break; + case DH_KEY: + if ((err = dh_make_key(prng, wprng, keysize, &(key.dh))) != CRYPT_OK) { + return err; + } + key_type = key.dh.type; + break; + case ECC_KEY: + if ((err = ecc_make_key(prng, wprng, keysize, &(key.ecc))) != CRYPT_OK) { + return err; + } + key_type = key.ecc.type; + break; + default: + return CRYPT_PK_INVALID_SYSTEM; + } + + /* now add the key */ + if ((err = kr_add(pk, key_type, sys, name, email, description, &key)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(&key, sizeof(key)); +#endif + return CRYPT_OK; +} + +int kr_encrypt_key(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash) +{ + unsigned char buf[8192]; + unsigned long len; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the key */ + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* store the header */ + memcpy(buf, enc_magic, 4); + + /* now store the ID */ + STORE32L(kr->ID,buf+4); + + /* now encrypt it */ + len = sizeof(buf)-12; + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_encrypt_key(in, inlen, buf+12, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + STORE32L(len,buf+8); + len += 12; + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_decrypt_key(pk_key *pk, const unsigned char *in, + unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192]; + unsigned long pklen, len, ID; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* check magic header */ + if (memcmp(in, enc_magic, 4)) { + return CRYPT_INVALID_PACKET; + } + + /* now try to find key */ + LOAD32L(ID,in+4); + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* is it public? */ + if (kr->key_type == PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* now try and decrypt it */ + LOAD32L(pklen,in+8); + len = sizeof(buf); + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_decrypt_key(in+12, pklen, buf, &len, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_decrypt_key(in+12, pklen, buf, &len, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_decrypt_key(in+12, pklen, buf, &len, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_sign_hash(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng) +{ + unsigned char buf[8192]; + unsigned long len; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the key */ + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* is it public? */ + if (kr->key_type == PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* store the header */ + memcpy(buf, sign_magic, 4); + + /* now store the ID */ + STORE32L(kr->ID,buf+4); + + /* now sign it */ + len = sizeof(buf)-16; + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_sign_hash(in, inlen, buf+16, &len, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + STORE32L(inlen,buf+8); + STORE32L(len,buf+12); + len += 16; + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash, + unsigned long hashlen, int *stat) +{ + unsigned long inlen, pklen, ID; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + + /* default to not match */ + *stat = 0; + + /* check magic header */ + if (memcmp(in, sign_magic, 4)) { + return CRYPT_INVALID_PACKET; + } + + /* now try to find key */ + LOAD32L(ID,in+4); + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* now try and verify it */ + LOAD32L(inlen,in+8); /* this is the length of the original inlen */ + LOAD32L(pklen,in+12); /* size of the PK packet */ + if (inlen != hashlen) { /* size doesn't match means the signature is invalid */ + return CRYPT_OK; + } + + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_verify_hash(in+16, pklen, hash, stat, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + return CRYPT_OK; +} + +int kr_fingerprint(pk_key *pk, unsigned long ID, int hash, + unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192]; + unsigned long len; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* valid hash? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + len = (unsigned long)sizeof(buf); + if ((err = kr_export(pk, ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) { + return err; + } + + /* now hash it */ + if ((err = hash_memory(hash, buf, len, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefile Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,254 @@ +# MAKEFILE for linux GCC +# +# Tom St Denis +# Modified by Clay Culver +# +# NOTE: This should later be replaced by autoconf/automake scripts, but for +# the time being this is actually pretty clean. The only ugly part is +# handling CFLAGS so that the x86 specific optimizations don't break +# a build. This is easy to remedy though, for those that have problems. + +# The version +VERSION=0.95 + +#ch1-01-1 +# Compiler and Linker Names +#CC=gcc +#LD=ld + +# Archiver [makes .a files] +#AR=ar +#ARFLAGS=r +#ch1-01-1 + +#ch1-01-3 +# Compilation flags. Note the += does not write over the user's CFLAGS! +# The rest of the flags come from the parent Dropbear makefile +CFLAGS += -c -I./ +# -Werror + +# optimize for SPEED +#CFLAGS += -O3 -funroll-loops + +#add -fomit-frame-pointer. v3.2 is buggy for certain platforms! +#CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +#CFLAGS += -Os + +# compile for DEBUGING +#CFLAGS += -g3 +#ch1-01-3 + +#These flags control how the library gets built. + +#Output filenames for various targets. +LIBNAME=libtomcrypt.a +TEST=test +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtomcrypt/pdf + +#List of objects to compile. + +#Leave MPI built-in or force developer to link against libtommath? +MPIOBJECT=mpi.o + +OBJECTS=keyring.o gf.o base64.o \ +\ +crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ +crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ +crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \ +crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \ +crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \ +crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \ +crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \ +\ +sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ +\ +rand_prime.o is_prime.o \ +\ +ecc.o dh.o \ +\ +rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ +\ +dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ +\ +xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ +rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ +\ +md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ +rmd128.o rmd160.o \ +\ +packet_store_header.o packet_valid_header.o \ +\ +eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \ +eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \ +\ +ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \ +ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \ +ocb_shift_xor.o ocb_test.o s_ocb_done.o \ +\ +omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \ +\ +pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ +pmac_shift_xor.o pmac_test.o \ +\ +cbc_start.o cbc_encrypt.o cbc_decrypt.o \ +cfb_start.o cfb_encrypt.o cfb_decrypt.o \ +ofb_start.o ofb_encrypt.o ofb_decrypt.o \ +ctr_start.o ctr_encrypt.o ctr_decrypt.o \ +ecb_start.o ecb_encrypt.o ecb_decrypt.o \ +\ +hash_file.o hash_filehandle.o hash_memory.o \ +\ +hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \ +\ +pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ +pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ +\ +pkcs_5_1.o pkcs_5_2.o \ +\ +burn_stack.o zeromem.o \ +$(MPIOBJECT) + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +PROFS=demos/x86_prof.o +TVS=demos/tv_gen.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind + +#Compressed filenames +COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz + +#Header files used by libtomcrypt. +HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \ +mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ +mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h \ +mycrypt_custom.h mycrypt_pkcs.h + +#The default rule for make builds the libtomcrypt library. +default:library mycrypt.h mycrypt_cfg.h + +#These are the rules to make certain object files. +rsa.o: rsa.c rsa_sys.c +ecc.o: ecc.c ecc_sys.c +dh.o: dh.c dh_sys.c +aes.o: aes.c aes_tab.c +twofish.o: twofish.c twofish_tab.c +sha512.o: sha512.c sha384.c +sha256.o: sha256.c sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + +#This rule makes the test program included with libtomcrypt +test: library $(TESTOBJECTS) + $(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN) + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) + +x86_prof: library $(PROFS) + $(CC) $(PROFS) $(LIBNAME) -o $(PROF) + +tv_gen: library $(TVS) + $(CC) $(TVS) $(LIBNAME) -o $(TV) + + +#make a profiled library (takes a while!!!) +# +# This will build the library with profile generation +# then run the test demo and rebuild the library. +# +# So far I've seen improvements in the MP math +# +# This works with GCC v3.3.x [tested with 3.3.3] +profiled: $(TESTOBJECTS) + make CFLAGS="$(CFLAGS) -fprofile-arcs" + $(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) + ./test + rm -f *.a *.o test demos/test.o + make CFLAGS="$(CFLAGS) -fbranch-probabilities" + + +#Profiling in GCC 3.4.x is a little diff. +# +#Tested with GCC v3.4.0 +profiled34: $(TESTOBJECTS) + make CFLAGS="$(CFLAGS) -fprofile-generate" + $(CC) $(TESTOBJECTS) $(LIBNAME) -lgcov -o $(TEST) + ./test + rm -f *.a *.o test demos/test.o + make CFLAGS="$(CFLAGS) -fprofile-use" + + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +install: library docs + install -d -g root -o root $(DESTDIR)$(LIBPATH) + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -d -g root -o root $(DESTDIR)$(DATAPATH) + install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + install -g root -o root crypt.pdf $(DESTDIR)$(DATAPATH) + +#This rule cleans the source tree of all compiled code, not including the pdf +#documentation. +clean: + rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME) + rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV) + rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \ + *.gcda *.gcno demos/*.gcno demos/*.gcda *~ + +#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed +#from the clean command! This is because most people would like to keep the +#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to +#delete it if we are rebuilding it. +docs: crypt.tex + rm -f crypt.pdf $(LEFTOVERS) + latex crypt > /dev/null + makeindex crypt > /dev/null + latex crypt > /dev/null + latex crypt > /dev/null + dvipdf crypt + rm -f $(LEFTOVERS) + +#beta +beta: clean + cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \ + cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)-beta/ ; tar -c libtomcrypt-$(VERSION)-beta/* > crypt-$(VERSION)-beta.tar ; \ + bzip2 -9vv crypt-$(VERSION)-beta.tar ; zip -9 -r crypt-$(VERSION)-beta.zip libtomcrypt-$(VERSION)-beta/* + +#zipup the project (take that!) +zipup: clean docs + cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ + cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \ + bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefile.cygwin_dll Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,84 @@ + + +default: ltc_dll + + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -mno-cygwin -DWIN32 + +# optimize for SPEED +#CFLAGS += -O3 -funroll-loops + +#add -fomit-frame-pointer. v3.2 is buggy for certain platforms! +#CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +CFLAGS += -Os + +#Leave MPI built-in or force developer to link against libtommath? +MPIOBJECT=mpi.o + +OBJECTS=keyring.o gf.o strings.o base64.o \ +\ +crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ +crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ +crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \ +crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \ +crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \ +crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \ +crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \ +\ +sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ +\ +rand_prime.o is_prime.o \ +\ +ecc.o dh.o \ +\ +rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ +\ +dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ +\ +xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ +rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ +\ +md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ +rmd128.o rmd160.o \ +\ +packet_store_header.o packet_valid_header.o \ +\ +eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \ +eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \ +\ +ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \ +ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \ +ocb_shift_xor.o ocb_test.o s_ocb_done.o \ +\ +omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \ +\ +pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ +pmac_shift_xor.o pmac_test.o \ +\ +cbc_start.o cbc_encrypt.o cbc_decrypt.o \ +cfb_start.o cfb_encrypt.o cfb_decrypt.o \ +ofb_start.o ofb_encrypt.o ofb_decrypt.o \ +ctr_start.o ctr_encrypt.o ctr_decrypt.o \ +ecb_start.o ecb_encrypt.o ecb_decrypt.o \ +\ +hash_file.o hash_filehandle.o hash_memory.o \ +\ +hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \ +\ +pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ +pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ +\ +pkcs_5_1.o pkcs_5_2.o \ +\ +burn_stack.o zeromem.o \ +$(MPIOBJECT) + +ltc_dll: $(OBJECTS) $(MPIOBJECT) + gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32 + ranlib libtomcrypt.dll.a + +test: ltc_dll + gcc $(CFLAGS) demos/test.c libtomcrypt.dll.a -Wl,--enable-auto-import -o test -s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefile.icc Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,213 @@ +# MAKEFILE for linux ICC (Intel C compiler) +# +# Tested with ICC v8.... +# +# Be aware that ICC isn't quite as stable as GCC and several optimization switches +# seem to break the code (that GCC and MSVC compile just fine). In particular +# "-ip" and "-x*" seem to break the code (ROL/ROR macro problems). As the makefile +# is shipped the code will build and execute properly. +# +# Also note that ICC often makes code that is slower than GCC. This is probably due to +# a mix of not being able to use "-ip" and just having fewer optimization algos than GCC. +# +# Tom St Denis + +#ch1-01-1 +# Compiler and Linker Names +CC=icc +#LD=ld + +# Archiver [makes .a files] +#AR=ar +#ARFLAGS=r + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -I./ -DINTEL_CC + +# optimize for SPEED +# +# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 +# -ax? specifies make code specifically for ? but compatible with IA-32 +# -x? specifies compile solely for ? [not specifically IA-32 compatible] +# +# where ? is +# K - PIII +# W - first P4 [Williamette] +# N - P4 Northwood +# P - P4 Prescott +# B - Blend of P4 and PM [mobile] +# +# Default to just generic max opts +CFLAGS += -O3 -xN -ip + +# want to see stuff? +#CFLAGS += -opt_report + +#These flags control how the library gets built. + +#Output filenames for various targets. +LIBNAME=libtomcrypt.a +TEST=test +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtomcrypt/pdf + +#List of objects to compile. + +#Leave MPI built-in or force developer to link against libtommath? +MPIOBJECT=mpi.o + +OBJECTS=keyring.o gf.o strings.o base64.o \ +\ +crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ +crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ +crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \ +crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \ +crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \ +crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \ +crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \ +\ +sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ +\ +rand_prime.o is_prime.o \ +\ +ecc.o dh.o \ +\ +rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ +\ +dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ +\ +xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ +rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ +\ +md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ +rmd128.o rmd160.o \ +\ +packet_store_header.o packet_valid_header.o \ +\ +eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \ +eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \ +\ +ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \ +ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \ +ocb_shift_xor.o ocb_test.o s_ocb_done.o \ +\ +omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \ +\ +pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ +pmac_shift_xor.o pmac_test.o \ +\ +cbc_start.o cbc_encrypt.o cbc_decrypt.o \ +cfb_start.o cfb_encrypt.o cfb_decrypt.o \ +ofb_start.o ofb_encrypt.o ofb_decrypt.o \ +ctr_start.o ctr_encrypt.o ctr_decrypt.o \ +ecb_start.o ecb_encrypt.o ecb_decrypt.o \ +\ +hash_file.o hash_filehandle.o hash_memory.o \ +\ +hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \ +\ +pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ +pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ +\ +pkcs_5_1.o pkcs_5_2.o \ +\ +burn_stack.o zeromem.o \ +$(MPIOBJECT) + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +PROFS=demos/x86_prof.o +TVS=demos/tv_gen.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind + +#Compressed filenames +COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz + +#Header files used by libtomcrypt. +HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \ +mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ +mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h + +#The default rule for make builds the libtomcrypt library. +default:library mycrypt.h mycrypt_cfg.h + +#These are the rules to make certain object files. +rsa.o: rsa.c rsa_sys.c +ecc.o: ecc.c ecc_sys.c +dh.o: dh.c dh_sys.c +aes.o: aes.c aes_tab.c +twofish.o: twofish.c twofish_tab.c +sha512.o: sha512.c sha384.c +sha256.o: sha256.c sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + +#This rule makes the test program included with libtomcrypt +test: library $(TESTOBJECTS) + $(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN) + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) + +x86_prof: library $(PROFS) + $(CC) $(PROFS) $(LIBNAME) -o $(PROF) + +tv_gen: library $(TVS) + $(CC) $(TVS) $(LIBNAME) -o $(TV) + + +#make a profiled library (takes a while!!!) +# +# This will build the library with profile generation +# then run the test demo and rebuild the library. +# +# So far I've seen improvements in the MP math +profiled: + make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen" test + ./test + rm -f *.a *.o test demos/test.o + make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use" + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +install: library + install -d -g root -o root $(DESTDIR)$(LIBPATH) + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + +#This rule cleans the source tree of all compiled code, not including the pdf +#documentation. +clean: + rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME) + rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV) + rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefile.msvc Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,86 @@ +#MSVC Makefile [tested with MSVC 6.00 with SP5] +# +#Tom St Denis +CFLAGS = /I. /Ox /DWIN32 /W3 + +default: library + +# leave this blank and link against libtommath if you want better link resolution +MPIOBJECT=mpi.obj + +#List of objects to compile. +OBJECTS=keyring.obj gf.obj strings.obj base64.obj \ +\ +crypt.obj crypt_find_cipher.obj crypt_find_hash_any.obj \ +crypt_hash_is_valid.obj crypt_register_hash.obj crypt_unregister_prng.obj \ +crypt_argchk.obj crypt_find_cipher_any.obj crypt_find_hash_id.obj \ +crypt_prng_descriptor.obj crypt_register_prng.obj crypt_cipher_descriptor.obj \ +crypt_find_cipher_id.obj crypt_find_prng.obj crypt_prng_is_valid.obj \ +crypt_unregister_cipher.obj crypt_cipher_is_valid.obj crypt_find_hash.obj \ +crypt_hash_descriptor.obj crypt_register_cipher.obj crypt_unregister_hash.obj \ +\ +sprng.obj yarrow.obj rc4.obj rng_get_bytes.obj rng_make_prng.obj \ +\ +rand_prime.obj is_prime.obj \ +\ +ecc.obj dh.obj \ +\ +rsa.obj rsa_exptmod.obj rsa_free.obj rsa_make_key.obj \ +\ +dsa_export.obj dsa_free.obj dsa_import.obj dsa_make_key.obj dsa_sign_hash.obj dsa_verify_hash.obj dsa_verify_key.obj \ +\ +xtea.obj aes.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj \ +rc6.obj rc5.obj cast5.obj noekeon.obj blowfish.obj twofish.obj skipjack.obj \ +\ +md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \ +rmd128.obj rmd160.obj \ +\ +packet_store_header.obj packet_valid_header.obj \ +\ +eax_addheader.obj eax_decrypt.obj eax_decrypt_verify_memory.obj eax_done.obj eax_encrypt.obj \ +eax_encrypt_authenticate_memory.obj eax_init.obj eax_test.obj \ +\ +ocb_decrypt.obj ocb_decrypt_verify_memory.obj ocb_done_decrypt.obj ocb_done_encrypt.obj \ +ocb_encrypt.obj ocb_encrypt_authenticate_memory.obj ocb_init.obj ocb_ntz.obj \ +ocb_shift_xor.obj ocb_test.obj s_ocb_done.obj \ +\ +omac_done.obj omac_file.obj omac_init.obj omac_memory.obj omac_process.obj omac_test.obj \ +\ +pmac_done.obj pmac_file.obj pmac_init.obj pmac_memory.obj pmac_ntz.obj pmac_process.obj \ +pmac_shift_xor.obj pmac_test.obj \ +\ +cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj \ +cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj \ +ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj \ +ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj \ +ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \ +\ +hash_file.obj hash_filehandle.obj hash_memory.obj \ +\ +hmac_done.obj hmac_file.obj hmac_init.obj hmac_memory.obj hmac_process.obj hmac_test.obj \ +\ +pkcs_1_mgf1.obj pkcs_1_oaep_encode.obj pkcs_1_oaep_decode.obj \ +pkcs_1_pss_encode.obj pkcs_1_pss_decode.obj pkcs_1_i2osp.obj pkcs_1_os2ip.obj \ +\ +pkcs_5_1.obj pkcs_5_2.obj \ +\ +burn_stack.obj zeromem.obj \ +$(MPIOBJECT) + +library: $(OBJECTS) + lib /out:tomcrypt.lib $(OBJECTS) + +test.obj: demos/test.c + cl $(CFLAGS) /c demos/test.c + +test: library test.obj + cl test.obj tomcrypt.lib advapi32.lib + +x86_prof: demos/x86_prof.c library + cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib + +tv_gen: demos/tv_gen.c library + cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib + +hashsum: demos/hashsum.c library + cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/md2.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,214 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* MD2 (RFC 1319) hash function implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MD2 + +const struct _hash_descriptor md2_desc = +{ + "md2", + 7, + 16, + 16, + &md2_init, + &md2_process, + &md2_done, + &md2_test +}; + +static const unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +/* adds 16 bytes to the checksum */ +static void md2_update_chksum(hash_state *md) +{ + int j; + unsigned char L; + L = md->md2.chksum[15]; + for (j = 0; j < 16; j++) { + +/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say + otherwise. +*/ + L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); + } +} + +static void md2_compress(hash_state *md) +{ + int j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) { + md->md2.X[16+j] = md->md2.buf[j]; + md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j]; + } + + t = (unsigned char)0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) { + for (k = 0; k < 48; k++) { + t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]); + } + t = (t + (unsigned char)j) & 255; + } +} + +void md2_init(hash_state *md) +{ + _ARGCHK(md != NULL); + + /* MD2 uses a zero'ed state... */ + zeromem(md->md2.X, sizeof(md->md2.X)); + zeromem(md->md2.chksum, sizeof(md->md2.chksum)); + zeromem(md->md2.buf, sizeof(md->md2.buf)); + md->md2.curlen = 0; +} + +int md2_process(hash_state *md, const unsigned char *buf, unsigned long len) +{ + unsigned long n; + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { + return CRYPT_INVALID_ARG; + } + while (len > 0) { + n = MIN(len, (16 - md->md2.curlen)); + memcpy(md->md2.buf + md->md2.curlen, buf, (size_t)n); + md->md2.curlen += n; + buf += n; + len -= n; + + /* is 16 bytes full? */ + if (md->md2.curlen == 16) { + md2_compress(md); + md2_update_chksum(md); + md->md2.curlen = 0; + } + } + return CRYPT_OK; +} + +int md2_done(hash_state * md, unsigned char *hash) +{ + unsigned long i, k; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md2.curlen >= sizeof(md->md2.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* pad the message */ + k = 16 - md->md2.curlen; + for (i = md->md2.curlen; i < 16; i++) { + md->md2.buf[i] = (unsigned char)k; + } + + /* hash and update */ + md2_compress(md); + md2_update_chksum(md); + + /* hash checksum */ + memcpy(md->md2.buf, md->md2.chksum, 16); + md2_compress(md); + + /* output is lower 16 bytes of X */ + memcpy(hash, md->md2.X, 16); + +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d, + 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73 + } + }, + { "a", + {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72, + 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1 + } + }, + { "message digest", + {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b, + 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0 + } + }, + { "abcdefghijklmnopqrstuvwxyz", + {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab, + 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b + } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39, + 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd + } + }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d, + 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8 + } + } + }; + int i; + hash_state md; + unsigned char buf[16]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + md2_init(&md); + md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md2_done(&md, buf); + if (memcmp(buf, tests[i].md, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/md4.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,266 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Submitted by Dobes Vandermeer ([email protected]) */ +#include "mycrypt.h" + +#ifdef MD4 + +const struct _hash_descriptor md4_desc = +{ + "md4", + 6, + 16, + 64, + &md4_init, + &md4_process, + &md4_done, + &md4_test +}; + +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +/* F, G and H are basic MD4 functions. */ +#define F(x, y, z) (z ^ (x & (y ^ z))) +#define G(x, y, z) ((x & y) | (z & (x | y))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) ROL(x, n) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +#ifdef CLEAN_STACK +static void _md4_compress(hash_state *md, unsigned char *buf) +#else +static void md4_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 x[16], a, b, c, d; + int i; + + /* copy state */ + a = md->md4.state[0]; + b = md->md4.state[1]; + c = md->md4.state[2]; + d = md->md4.state[3]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(x[i], buf + (4*i)); + } + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + + /* Update our state */ + md->md4.state[0] = md->md4.state[0] + a; + md->md4.state[1] = md->md4.state[1] + b; + md->md4.state[2] = md->md4.state[2] + c; + md->md4.state[3] = md->md4.state[3] + d; +} + +#ifdef CLEAN_STACK +static void md4_compress(hash_state *md, unsigned char *buf) +{ + _md4_compress(md, buf); + burn_stack(sizeof(ulong32) * 20 + sizeof(int)); +} +#endif + +void md4_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->md4.state[0] = 0x67452301UL; + md->md4.state[1] = 0xefcdab89UL; + md->md4.state[2] = 0x98badcfeUL; + md->md4.state[3] = 0x10325476UL; + md->md4.length = 0; + md->md4.curlen = 0; +} + +HASH_PROCESS(md4_process, md4_compress, md4, 64) + +int md4_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md4.curlen >= sizeof(md->md4.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->md4.length += md->md4.curlen * 8; + + /* append the '1' bit */ + md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md4.curlen > 56) { + while (md->md4.curlen < 64) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + md4_compress(md, md->md4.buf); + md->md4.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md4.curlen < 56) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md4.length, md->md4.buf+56); + md4_compress(md, md->md4.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md4.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md4_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct md4_test_case { + char *input; + unsigned char digest[16]; + } cases[] = { + { "", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, + { "a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, + { "abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, + { "message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, + { "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, + }; + int i; + hash_state md; + unsigned char digest[16]; + + for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + md4_init(&md); + md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); + md4_done(&md, digest); + if (memcmp(digest, cases[i].digest, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; + #endif +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/md5.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,258 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* MD5 hash function by Tom St Denis */ + +#include "mycrypt.h" + +#ifdef MD5 + +const struct _hash_descriptor md5_desc = +{ + "md5", + 3, + 16, + 64, + &md5_init, + &md5_process, + &md5_done, + &md5_test +}; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define G(x,y,z) (y ^ (z & (y ^ x))) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y^(x|(~z))) + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; + +#ifdef CLEAN_STACK +static void _md5_compress(hash_state *md, unsigned char *buf) +#else +static void md5_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 i, W[16], a, b, c, d; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->md5.state[0]; + b = md->md5.state[1]; + c = md->md5.state[2]; + d = md->md5.state[3]; + + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) + + md->md5.state[0] = md->md5.state[0] + a; + md->md5.state[1] = md->md5.state[1] + b; + md->md5.state[2] = md->md5.state[2] + c; + md->md5.state[3] = md->md5.state[3] + d; +} + +#ifdef CLEAN_STACK +static void md5_compress(hash_state *md, unsigned char *buf) +{ + _md5_compress(md, buf); + burn_stack(sizeof(ulong32) * 21); +} +#endif + +void md5_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->md5.state[0] = 0x67452301UL; + md->md5.state[1] = 0xefcdab89UL; + md->md5.state[2] = 0x98badcfeUL; + md->md5.state[3] = 0x10325476UL; + md->md5.curlen = 0; + md->md5.length = 0; +} + +HASH_PROCESS(md5_process, md5_compress, md5, 64) + +int md5_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md5.curlen >= sizeof(md->md5.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->md5.length += md->md5.curlen * 8; + + /* append the '1' bit */ + md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md5.curlen > 56) { + while (md->md5.curlen < 64) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + md5_compress(md, md->md5.buf); + md->md5.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md5.curlen < 56) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md5.length, md->md5.buf+56); + md5_compress(md, md->md5.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md5.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { "a", + {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + md5_init(&md); + md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md5_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpi.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,8414 @@ +/* Start: bn_error.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +static const struct { + int code; + char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + + +/* End: bn_error.c */ + +/* Start: bn_fast_mp_invmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on mp_invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int +fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto __ERR; + } + + /* we need y = |a| */ + if ((res = mp_abs (a, &y)) != MP_OKAY) { + goto __ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto __ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto __ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto __ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto __ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto __ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto __ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto __ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto __ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto __ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +__ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} + +/* End: bn_fast_mp_invmod.c */ + +/* Start: bn_fast_mp_montgomery_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of mp_montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int +fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} + +/* End: bn_fast_mp_montgomery_reduce.c */ + +/* Start: bn_fast_s_mp_mul_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int +fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix; + mp_word W[MP_WARRAY]; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* clear temp buf (the columns) */ + memset (W, 0, sizeof (mp_word) * digs); + + /* calculate the columns */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* this multiplier has been modified to allow you to + * control how many digits of output are produced. + * So at most we want to make upto "digs" digits of output. + * + * this adds products to distinct columns (at ix+iy) of W + * note that each step through the loop is not dependent on + * the previous which means the compiler can easily unroll + * the loop without scheduling problems + */ + { + register mp_digit tmpx, *tmpy; + register mp_word *_W; + register int iy, pb; + + /* alias for the the word on the left e.g. A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for the right side */ + tmpy = b->dp; + + /* alias for the columns, each step through the loop adds a new + term to each column + */ + _W = W + ix; + + /* the number of digits is limited by their placement. E.g. + we avoid multiplying digits that will end up above the # of + digits of precision requested + */ + pb = MIN (b->used, digs - ix); + + for (iy = 0; iy < pb; iy++) { + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); + } + } + + } + + /* setup dest */ + olduse = c->used; + c->used = digs; + + { + register mp_digit *tmpc; + + /* At this point W[] contains the sums of each column. To get the + * correct result we must take the extra bits from each column and + * carry them down + * + * Note that while this adds extra code to the multiplier it + * saves time since the carry propagation is removed from the + * above nested loop.This has the effect of reducing the work + * from N*(N+N*c)==N**2 + c*N**2 to N**2 + N*c where c is the + * cost of the shifting. On very small numbers this is slower + * but on most cryptographic size numbers it is faster. + * + * In this particular implementation we feed the carries from + * behind which means when the loop terminates we still have one + * last digit to copy + */ + tmpc = c->dp; + for (ix = 1; ix < digs; ix++) { + /* forward the carry from the previous temp */ + W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* now extract the previous digit [below the carry] */ + *tmpc++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + /* fetch the last digit */ + *tmpc++ = (mp_digit) (W[digs - 1] & ((mp_word) MP_MASK)); + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_mul_digs.c */ + +/* Start: bn_fast_s_mp_mul_high_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ + #include <tommath.h> + +/* this is a modified version of fast_s_mp_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mp_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int +fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int oldused, newused, res, pa, pb, ix; + mp_word W[MP_WARRAY]; + + /* calculate size of product and allocate more space if required */ + newused = a->used + b->used + 1; + if (c->alloc < newused) { + if ((res = mp_grow (c, newused)) != MP_OKAY) { + return res; + } + } + + /* like the other comba method we compute the columns first */ + pa = a->used; + pb = b->used; + memset (W + digs, 0, (pa + pb + 1 - digs) * sizeof (mp_word)); + for (ix = 0; ix < pa; ix++) { + { + register mp_digit tmpx, *tmpy; + register int iy; + register mp_word *_W; + + /* work todo, that is we only calculate digits that are at "digs" or above */ + iy = digs - ix; + + /* copy of word on the left of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias for right side */ + tmpy = b->dp + iy; + + /* alias for the columns of output. Offset to be equal to or above the + * smallest digit place requested + */ + _W = W + digs; + + /* skip cases below zero where ix > digs */ + if (iy < 0) { + iy = abs(iy); + tmpy += iy; + _W += iy; + iy = 0; + } + + /* compute column products for digits above the minimum */ + for (; iy < pb; iy++) { + *_W++ += ((mp_word) tmpx) * ((mp_word)*tmpy++); + } + } + } + + /* setup dest */ + oldused = c->used; + c->used = newused; + + /* now convert the array W downto what we need + * + * See comments in bn_fast_s_mp_mul_digs.c + */ + for (ix = digs + 1; ix < newused; ix++) { + W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + c->dp[ix - 1] = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + c->dp[newused - 1] = (mp_digit) (W[newused - 1] & ((mp_word) MP_MASK)); + + for (; ix < oldused; ix++) { + c->dp[ix] = 0; + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_mul_high_digs.c */ + +/* Start: bn_fast_s_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* fast squaring + * + * This is the comba method where the columns of the product + * are computed first then the carries are computed. This + * has the effect of making a very simple inner loop that + * is executed the most + * + * W2 represents the outer products and W the inner. + * + * A further optimizations is made because the inner + * products are of the form "A * B * 2". The *2 part does + * not need to be computed until the end which is good + * because 64-bit shifts are slow! + * + * Based on Algorithm 14.16 on pp.597 of HAC. + * + */ +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, newused, res, ix, pa; + mp_word W2[MP_WARRAY], W[MP_WARRAY]; + + /* calculate size of product and allocate as required */ + pa = a->used; + newused = pa + pa + 1; + if (b->alloc < newused) { + if ((res = mp_grow (b, newused)) != MP_OKAY) { + return res; + } + } + + /* zero temp buffer (columns) + * Note that there are two buffers. Since squaring requires + * a outer and inner product and the inner product requires + * computing a product and doubling it (a relatively expensive + * op to perform n**2 times if you don't have to) the inner and + * outer products are computed in different buffers. This way + * the inner product can be doubled using n doublings instead of + * n**2 + */ + memset (W, 0, newused * sizeof (mp_word)); + memset (W2, 0, newused * sizeof (mp_word)); + + /* This computes the inner product. To simplify the inner N**2 loop + * the multiplication by two is done afterwards in the N loop. + */ + for (ix = 0; ix < pa; ix++) { + /* compute the outer product + * + * Note that every outer product is computed + * for a particular column only once which means that + * there is no need todo a double precision addition + * into the W2[] array. + */ + W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); + + { + register mp_digit tmpx, *tmpy; + register mp_word *_W; + register int iy; + + /* copy of left side */ + tmpx = a->dp[ix]; + + /* alias for right side */ + tmpy = a->dp + (ix + 1); + + /* the column to store the result in */ + _W = W + (ix + ix + 1); + + /* inner products */ + for (iy = ix + 1; iy < pa; iy++) { + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); + } + } + } + + /* setup dest */ + olduse = b->used; + b->used = newused; + + /* now compute digits + * + * We have to double the inner product sums, add in the + * outer product sums, propagate carries and convert + * to single precision. + */ + { + register mp_digit *tmpb; + + /* double first value, since the inner products are + * half of what they should be + */ + W[0] += W[0] + W2[0]; + + tmpb = b->dp; + for (ix = 1; ix < newused; ix++) { + /* double/add next digit */ + W[ix] += W[ix] + W2[ix]; + + /* propagate carry forwards [from the previous digit] */ + W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* store the current digit now that the carry isn't + * needed + */ + *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + /* set the last value. Note even if the carry is zero + * this is required since the next step will not zero + * it if b originally had a value at b->dp[2*a.used] + */ + *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); + + /* clear high digits of b if there were any originally */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + + mp_clamp (b); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_sqr.c */ + +/* Start: bn_mp_2expt.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); + + return MP_OKAY; +} + +/* End: bn_mp_2expt.c */ + +/* Start: bn_mp_abs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_abs.c */ + +/* Start: bn_mp_add.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + + +/* End: bn_mp_add.c */ + +/* Start: bn_mp_add_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + + +/* End: bn_mp_add_d.c */ + +/* Start: bn_mp_addmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_addmod.c */ + +/* Start: bn_mp_and.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_and.c */ + +/* Start: bn_mp_clamp.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} + +/* End: bn_mp_clamp.c */ + +/* Start: bn_mp_clear.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + memset (a->dp, 0, sizeof (mp_digit) * a->used); + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + +/* End: bn_mp_clear.c */ + +/* Start: bn_mp_clear_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> +#include <stdarg.h> + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} + +/* End: bn_mp_clear_multi.c */ + +/* Start: bn_mp_cmp.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} + +/* End: bn_mp_cmp.c */ + +/* Start: bn_mp_cmp_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} + +/* End: bn_mp_cmp_d.c */ + +/* Start: bn_mp_cmp_mag.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} + +/* End: bn_mp_cmp_mag.c */ + +/* Start: bn_mp_cnt_lsb.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + + +/* End: bn_mp_cnt_lsb.c */ + +/* Start: bn_mp_copy.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} + +/* End: bn_mp_copy.c */ + +/* Start: bn_mp_count_bits.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} + +/* End: bn_mp_count_bits.c */ + +/* Start: bn_mp_div.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto __Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto __T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto __T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto __X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto __Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto __Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto __Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto __Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto __Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto __Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto __Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto __Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +__Y:mp_clear (&y); +__X:mp_clear (&x); +__T2:mp_clear (&t2); +__T1:mp_clear (&t1); +__Q:mp_clear (&q); + return res; +} + +/* End: bn_mp_div.c */ + +/* Start: bn_mp_div_2.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} + +/* End: bn_mp_div_2.c */ + +/* Start: bn_mp_div_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_div_2d.c */ + +/* Start: bn_mp_div_3.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +/* End: bn_mp_div_3.c */ + +/* Start: bn_mp_div_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + for (x = 1; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<<x)) { + *p = x; + return 1; + } + } + return 0; +} + +/* single digit division (based on routine from MPI) */ +int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) +{ + mp_int q; + mp_word w; + mp_digit t; + int res, ix; + + /* cannot divide by zero */ + if (b == 0) { + return MP_VAL; + } + + /* quick outs */ + if (b == 1 || mp_iszero(a) == 1) { + if (d != NULL) { + *d = 0; + } + if (c != NULL) { + return mp_copy(a, c); + } + return MP_OKAY; + } + + /* power of two ? */ + if (s_is_power_of_two(b, &ix) == 1) { + if (d != NULL) { + *d = a->dp[0] & ((1<<ix) - 1); + } + if (c != NULL) { + return mp_div_2d(a, ix, c, NULL); + } + return MP_OKAY; + } + + /* three? */ + if (b == 3) { + return mp_div_3(a, c, d); + } + + /* no easy answer [c'est la vie]. Just division */ + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +/* End: bn_mp_div_d.c */ + +/* Start: bn_mp_dr_is_modulus.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + + +/* End: bn_mp_dr_is_modulus.c */ + +/* Start: bn_mp_dr_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Loong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} + +/* End: bn_mp_dr_reduce.c */ + +/* Start: bn_mp_dr_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + + +/* End: bn_mp_dr_setup.c */ + +/* Start: bn_mp_exch.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + +/* End: bn_mp_exch.c */ + +/* Start: bn_mp_expt_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, x; + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + for (x = 0; x < (int) DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + + mp_clear (&g); + return MP_OKAY; +} + +/* End: bn_mp_expt_d.c */ + +/* Start: bn_mp_exptmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); + + /* if not, is it a uDR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } + + /* if the modulus is odd or dr != 0 use the fast method */ + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y); + } +} + + +/* End: bn_mp_exptmod.c */ + +/* Start: bn_mp_exptmod_fast.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int +mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto __M; + } + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else { + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; + } + } else if (redmode == 1) { + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; + } else { + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto __M; + } + redux = mp_reduce_2k; + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto __M; + } + + /* create M table + * + * The M table contains powers of the input base, e.g. M[x] = G^x mod P + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto __RES; + } + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto __RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto __RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +__RES:mp_clear (&res); +__M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + +/* End: bn_mp_exptmod_fast.c */ + +/* Start: bn_mp_exteuclid.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +{ + mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&u1, 1); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&v2, 1); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (mp_iszero(&v3) == MP_NO) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* copy result out */ + if (U1 != NULL) { mp_exch(U1, &u1); } + if (U2 != NULL) { mp_exch(U2, &u2); } + if (U3 != NULL) { mp_exch(U3, &u3); } + + err = MP_OKAY; +_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} + +/* End: bn_mp_exteuclid.c */ + +/* Start: bn_mp_fread.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + + +/* End: bn_mp_fread.c */ + +/* Start: bn_mp_fwrite.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } + + buf = OPT_CAST(char) XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + + +/* End: bn_mp_fwrite.c */ + +/* Start: bn_mp_gcd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == 1 && mp_iszero (b) == 0) { + return mp_abs (b, c); + } + if (mp_iszero (a) == 0 && mp_iszero (b) == 1) { + return mp_abs (a, c); + } + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (mp_iszero (a) == 1) { + mp_zero(c); + return MP_OKAY; + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto __U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto __V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto __V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto __V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto __V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +__V:mp_clear (&u); +__U:mp_clear (&v); + return res; +} + +/* End: bn_mp_gcd.c */ + +/* Start: bn_mp_get_int.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(mp_int * a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return res & 0xFFFFFFFFUL; +} + +/* End: bn_mp_get_int.c */ + +/* Start: bn_mp_grow.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + +/* End: bn_mp_grow.c */ + +/* Start: bn_mp_init.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* init a new bigint */ +int mp_init (mp_int * a) +{ + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XCALLOC (sizeof (mp_digit), MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_init.c */ + +/* Start: bn_mp_init_copy.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} + +/* End: bn_mp_init_copy.c */ + +/* Start: bn_mp_init_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> +#include <stdarg.h> + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + + +/* End: bn_mp_init_multi.c */ + +/* Start: bn_mp_init_set.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; +} + +/* End: bn_mp_init_set.c */ + +/* Start: bn_mp_init_set_int.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* initialize and set a digit */ +int mp_init_set_int (mp_int * a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} + +/* End: bn_mp_init_set_int.c */ + +/* Start: bn_mp_init_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XCALLOC (sizeof (mp_digit), size); + if (a->dp == NULL) { + return MP_MEM; + } + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_init_size.c */ + +/* Start: bn_mp_invmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_copy (a, &x)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto __ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto __ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto __ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto __ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto __ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto __ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto __ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto __ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto __ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto __ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto __ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto __ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +__ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} + +/* End: bn_mp_invmod.c */ + +/* Start: bn_mp_is_square.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Check if remainders are possible squares - fast exclude non-squares */ +static const char rem_128[128] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 +}; + +static const char rem_105[105] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 +}; + +/* Store non-zero to ret if arg is square, and zero if not */ +int mp_is_square(mp_int *arg,int *ret) +{ + int res; + mp_digit c; + mp_int t; + unsigned long r; + + /* Default to Non-square :) */ + *ret = MP_NO; + + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* digits used? (TSD) */ + if (arg->used == 0) { + return MP_OKAY; + } + + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127 & DIGIT(arg,0)] == 1) { + return MP_OKAY; + } + + /* Next check mod 105 (3*5*7) */ + if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { + return res; + } + if (rem_105[c] == 1) { + return MP_OKAY; + } + + /* product of primes less than 2^31 */ + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; + } + if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { + goto ERR; + } + r = mp_get_int(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto ERR. We know that res + * is already equal to MP_OKAY from the mp_mod call + */ + if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; + if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; + if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; + if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; + if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; + if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; + if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; + + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&t,&t)) != MP_OKAY) { + goto ERR; + } + + *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; +ERR:mp_clear(&t); + return res; +} + +/* End: bn_mp_is_square.c */ + +/* Start: bn_mp_jacobi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + */ +int mp_jacobi (mp_int * a, mp_int * p, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. if a == 0, return 0 */ + if (mp_iszero (a) == 1) { + *c = 0; + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto __A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto __P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = p->dp[0] & 7; + + if (residue == 1 || residue == 7) { + s = 1; + } else if (residue == 3 || residue == 5) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { + goto __P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto __P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +__P1:mp_clear (&p1); +__A1:mp_clear (&a1); + return res; +} + +/* End: bn_mp_jacobi.c */ + +/* Start: bn_mp_karatsuba_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 - a0)(b1 - b0) + a0b0 + a1b1) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1-b1)(a0-b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.sign = x1.sign = a->sign; + y0.sign = y1.sign = b->sign; + + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + register int x; + register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1-x0 and y1-y0 */ + if (mp_sub (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (mp_sub (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 - x0) * (y1 - y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (mp_sub (&x0, &t1, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x0y0 + x1y1 - (x1-x0)*(y1-y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ + if (mp_lshd (&x1y1, B * 2) != MP_OKAY) + goto X1Y1; /* x1y1 = x1y1 << 2*B */ + + if (mp_add (&x0y0, &t1, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x0y0 + t1 */ + if (mp_add (&t1, &x1y1, c) != MP_OKAY) + goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ + + /* Algorithm succeeded set the return code to MP_OKAY */ + err = MP_OKAY; + +X1Y1:mp_clear (&x1y1); +X0Y0:mp_clear (&x0y0); +T1:mp_clear (&t1); +Y1:mp_clear (&y1); +Y0:mp_clear (&y0); +X1:mp_clear (&x1); +X0:mp_clear (&x0); +ERR: + return err; +} + +/* End: bn_mp_karatsuba_mul.c */ + +/* Start: bn_mp_karatsuba_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of mp_karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +int mp_karatsuba_sqr (mp_int * a, mp_int * b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B, err; + + err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + register int x; + register mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1-x0)**2 */ + if (mp_sub (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (mp_sub (&t2, &t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + x1x1 - (x1-x0)*(x1-x0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ + if (mp_lshd (&x1x1, B * 2) != MP_OKAY) + goto X1X1; /* x1x1 = x1x1 << 2*B */ + + if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + t1 */ + if (mp_add (&t1, &x1x1, b) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ + + err = MP_OKAY; + +X1X1:mp_clear (&x1x1); +X0X0:mp_clear (&x0x0); +T2:mp_clear (&t2); +T1:mp_clear (&t1); +X1:mp_clear (&x1); +X0:mp_clear (&x0); +ERR: + return err; +} + +/* End: bn_mp_karatsuba_sqr.c */ + +/* Start: bn_mp_lcm.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto __T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +__T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} + +/* End: bn_mp_lcm.c */ + +/* Start: bn_mp_lshd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + +/* End: bn_mp_lshd.c */ + +/* Start: bn_mp_mod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} + +/* End: bn_mp_mod.c */ + +/* Start: bn_mp_mod_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b > (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_mp_mod_2d.c */ + +/* Start: bn_mp_mod_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} + +/* End: bn_mp_mod_d.c */ + +/* Start: bn_mp_montgomery_calc_normalization.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* calculates a = B^n mod b for Montgomery reduction + * Where B is the base [e.g. 2^DIGIT_BIT]. + * B^n mod b is computed by first computing + * A = B^(n-1) which doesn't require a reduction but a simple OR. + * then C = A * B = B^n is computed by performing upto DIGIT_BIT + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int +mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + /* compute A = B^(n-1) * 2^(bits-1) */ + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_calc_normalization.c */ + +/* Start: bn_mp_montgomery_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mp_mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * bn_mp_montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_reduce.c */ + +/* Start: bn_mp_montgomery_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (((mp_digit) 1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_setup.c */ + +/* Start: bn_mp_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + /* use Karatsuba? */ + } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else { + res = s_mp_mul (a, b, c); + } + } + c->sign = neg; + return res; +} + +/* End: bn_mp_mul.c */ + +/* Start: bn_mp_mul_2.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} + +/* End: bn_mp_mul_2.c */ + +/* Start: bn_mp_mul_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_mp_mul_2d.c */ + +/* Start: bn_mp_mul_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] */ + *tmpc++ = u; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} + +/* End: bn_mp_mul_d.c */ + +/* Start: bn_mp_mulmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* d = a * b (mod c) */ +int +mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_mulmod.c */ + +/* Start: bn_mp_n_root.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if ((b & 1) == 0 && a->sign == MP_NEG) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto __T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto __T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto __T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { + goto __T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto __T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto __T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto __T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto __T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto __T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { + goto __T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto __T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +__T3:mp_clear (&t3); +__T2:mp_clear (&t2); +__T1:mp_clear (&t1); + return res; +} + +/* End: bn_mp_n_root.c */ + +/* Start: bn_mp_neg.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int res; + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + if (mp_iszero(b) != MP_YES) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } + return MP_OKAY; +} + +/* End: bn_mp_neg.c */ + +/* Start: bn_mp_or.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_or.c */ + +/* Start: bn_mp_prime_fermat.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto __T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +__T:mp_clear (&t); + return err; +} + +/* End: bn_mp_prime_fermat.c */ + +/* Start: bn_mp_prime_is_divisible.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod __prime_tab[ix] */ + if ((err = mp_mod_d (a, __prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} + +/* End: bn_mp_prime_is_divisible.c */ + +/* Start: bn_mp_prime_is_prime.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + * (1/4)^t when 1 <= t <= PRIME_SIZE + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, __prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, __prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto __B; + } + + if (res == MP_NO) { + goto __B; + } + } + + /* passed the test */ + *result = MP_YES; +__B:mp_clear (&b); + return err; +} + +/* End: bn_mp_prime_is_prime.c */ + +/* Start: bn_mp_prime_miller_rabin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto __N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto __N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto __R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto __R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto __Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto __Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto __Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto __Y; + } + } + + /* probably prime now */ + *result = MP_YES; +__Y:mp_clear (&y); +__R:mp_clear (&r); +__N1:mp_clear (&n1); + return err; +} + +/* End: bn_mp_prime_miller_rabin.c */ + +/* Start: bn_mp_prime_next_prime.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, __prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((__prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((__prime_tab[y] & 3) == 3) { + mp_set(a, __prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, __prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == 1) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, __prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= __prime_tab[x]) { + res_tab[x] -= __prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep)); + + /* add the step */ + if ((err = mp_add_d(a, step, a)) != MP_OKAY) { + goto __ERR; + } + + /* if didn't pass sieve and step == MAX then skip test */ + if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) { + continue; + } + + /* is this prime? */ + for (x = 0; x < t; x++) { + mp_set(&b, __prime_tab[t]); + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto __ERR; + } + if (res == MP_NO) { + break; + } + } + + if (res == MP_YES) { + break; + } + } + + err = MP_OKAY; +__ERR: + mp_clear(&b); + return err; +} + + +/* End: bn_mp_prime_next_prime.c */ + +/* Start: bn_mp_prime_random_ex.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int res, err, bsize, maskOR_msb_offset; + + /* sanity check the input */ + if (size <= 1 || t <= 0) { + return MP_VAL; + } + + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if (flags & LTM_PRIME_SAFE) { + flags |= LTM_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3)+(size&7?1:0); + + /* we need a buffer of bsize bytes */ + tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = 0xFF >> (8 - (size & 7)); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = (size - 2) >> 3; + if (flags & LTM_PRIME_2MSB_ON) { + maskOR_msb |= 1 << ((size - 2) & 7); + } else if (flags & LTM_PRIME_2MSB_OFF) { + maskAND &= ~(1 << ((size - 2) & 7)); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 0; + if (flags & LTM_PRIME_BBS) { + maskOR_lsb |= 3; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= 1 << ((size - 1) & 7); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + + if (flags & LTM_PRIME_SAFE) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + } + } while (res == MP_NO); + + if (flags & LTM_PRIME_SAFE) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } + } + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + + +/* End: bn_mp_prime_random_ex.c */ + +/* Start: bn_mp_radix_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* returns size of ASCII reprensentation */ +int mp_radix_size (mp_int * a, int radix, int *size) +{ + int res, digs; + mp_int t; + mp_digit d; + + *size = 0; + + /* special case for binary */ + if (radix == 2) { + *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + return MP_OKAY; + } + + /* make sure the radix is in range */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (t.sign == MP_NEG) { + ++digs; + t.sign = MP_ZPOS; + } + + /* fetch out all of the digits */ + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + return MP_OKAY; +} + + +/* End: bn_mp_radix_size.c */ + +/* Start: bn_mp_radix_smap.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +/* End: bn_mp_radix_smap.c */ + +/* Start: bn_mp_rand.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (rand ())); + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (digits-- > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} + +/* End: bn_mp_rand.c */ + +/* Start: bn_mp_read_radix.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, char *str, int radix) +{ + int y, res, neg; + char ch; + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} + +/* End: bn_mp_read_radix.c */ + +/* Start: bn_mp_read_signed_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int +mp_read_signed_bin (mp_int * a, unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} + +/* End: bn_mp_read_signed_bin.c */ + +/* Start: bn_mp_read_unsigned_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int +mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} + +/* End: bn_mp_read_unsigned_bin.c */ + +/* Start: bn_mp_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int +mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { + if ((res = s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) { + goto CLEANUP; + } + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} + +/* End: bn_mp_reduce.c */ + +/* Start: bn_mp_reduce_2k.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* reduces a modulo n where n is of the form 2**p - d */ +int +mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* End: bn_mp_reduce_2k.c */ + +/* Start: bn_mp_reduce_2k_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* determines the setup value */ +int +mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} + +/* End: bn_mp_reduce_2k_setup.c */ + +/* Start: bn_mp_reduce_is_2k.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iz, iw; + + if (a->used == 0) { + return 0; + } else if (a->used == 1) { + return 1; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return 0; + } + iz <<= 1; + if (iz > (int)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return 1; +} + + +/* End: bn_mp_reduce_is_2k.c */ + +/* Start: bn_mp_reduce_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} + +/* End: bn_mp_reduce_setup.c */ + +/* Start: bn_mp_rshd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + +/* End: bn_mp_rshd.c */ + +/* Start: bn_mp_set.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} + +/* End: bn_mp_set.c */ + +/* Start: bn_mp_set_int.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} + +/* End: bn_mp_set_int.c */ + +/* Start: bn_mp_shrink.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + if (a->alloc != a->used && a->used > 0) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = a->used; + } + return MP_OKAY; +} + +/* End: bn_mp_shrink.c */ + +/* Start: bn_mp_signed_bin_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* get the size for an signed equivalent */ +int mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} + +/* End: bn_mp_signed_bin_size.c */ + +/* Start: bn_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else { + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else { + res = s_mp_sqr (a, b); + } + } + b->sign = MP_ZPOS; + return res; +} + +/* End: bn_mp_sqr.c */ + +/* Start: bn_mp_sqrmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} + +/* End: bn_mp_sqrmod.c */ + +/* Start: bn_mp_sqrt.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* this function is less generic than mp_n_root, simpler and faster */ +int mp_sqrt(mp_int *arg, mp_int *ret) +{ + int res; + mp_int t1,t2; + + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* easy out */ + if (mp_iszero(arg) == MP_YES) { + mp_zero(ret); + return MP_OKAY; + } + + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } + + /* First approx. (not very bad for large arg) */ + mp_rshd (&t1,t1.used/2); + + /* t1 > 0 */ + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* And now t1 > sqrt(arg) */ + do { + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1,&t2) == MP_GT); + + mp_exch(&t1,ret); + +E1: mp_clear(&t2); +E2: mp_clear(&t1); + return res; +} + + +/* End: bn_mp_sqrt.c */ + +/* Start: bn_mp_sub.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + + +/* End: bn_mp_sub.c */ + +/* Start: bn_mp_sub_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + + +/* End: bn_mp_sub_d.c */ + +/* Start: bn_mp_submod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_submod.c */ + +/* Start: bn_mp_to_signed_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* store in signed [big endian] format */ +int +mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); + return MP_OKAY; +} + +/* End: bn_mp_to_signed_bin.c */ + +/* Start: bn_mp_to_unsigned_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* store in unsigned [big endian] format */ +int +mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_to_unsigned_bin.c */ + +/* Start: bn_mp_toom_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* multiplication using the Toom-Cook 3-way algorithm */ +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + + +/* End: bn_mp_toom_mul.c */ + +/* Start: bn_mp_toom_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + + +/* End: bn_mp_toom_sqr.c */ + +/* Start: bn_mp_toradix.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + + +/* End: bn_mp_toradix.c */ + +/* Start: bn_mp_toradix_n.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto maxlen-1 chars and always a NULL byte + */ +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the maxlen, radix */ + if (maxlen < 3 || radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + + if (--maxlen == 1) { + /* no more room */ + break; + } + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + + +/* End: bn_mp_toradix_n.c */ + +/* Start: bn_mp_unsigned_bin_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* get the size for an unsigned equivalent */ +int +mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + +/* End: bn_mp_unsigned_bin_size.c */ + +/* Start: bn_mp_xor.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_xor.c */ + +/* Start: bn_mp_zero.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* set to zero */ +void +mp_zero (mp_int * a) +{ + a->sign = MP_ZPOS; + a->used = 0; + memset (a->dp, 0, sizeof (mp_digit) * a->alloc); +} + +/* End: bn_mp_zero.c */ + +/* Start: bn_prime_sizes_tab.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */ +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 }, +{ 1152, 3 }, +{ 1280, 3 }, +{ 1408, 3 }, +{ 1536, 3 }, +{ 1664, 3 }, +{ 1792, 2 } }; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return 1; +} + + + +/* End: bn_prime_sizes_tab.c */ + +/* Start: bn_prime_tab.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> +const mp_digit __prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; + +/* End: bn_prime_tab.c */ + +/* Start: bn_reverse.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + +/* End: bn_reverse.c */ + +/* Start: bn_s_mp_add.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_s_mp_add.c */ + +/* Start: bn_s_mp_exptmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto __M; + } + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto __MU; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto __MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __MU; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __MU; + } + if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto __MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto __MU; + } + if ((err = mp_reduce (&M[x], P, &mu)) != MP_OKAY) { + goto __MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto __MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +__RES:mp_clear (&res); +__MU:mp_clear (&mu); +__M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + +/* End: bn_s_mp_exptmod.c */ + +/* Start: bn_s_mp_mul_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int +s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_mul_digs.c */ + +/* Start: bn_s_mp_mul_high_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_mul_high_digs.c */ + +/* Start: bn_s_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int +s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_sqr.c */ + +/* Start: bn_s_mp_sub.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* End: bn_s_mp_sub.c */ + +/* Start: bncore.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#include <tommath.h> + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 /GCC v3.2 / 70/ 108 + AMD Athlon XP /GCC v3.2 / 109/ 127 + +*/ + +/* configured for a AMD XP Thoroughbred core with etc/tune.c */ +int KARATSUBA_MUL_CUTOFF = 70, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 108, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; + +/* End: bncore.c */ + + +/* EOF */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,83 @@ +#ifndef CRYPT_H_ +#define CRYPT_H_ +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include <limits.h> + +/* if there is a custom definition header file use it */ +#include <mycrypt_custom.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0095 +#define SCRYPT "0.95" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +/* descriptor table size */ +/* Dropbear change - this should be smaller, saves some size */ +#define TAB_SIZE 4 + +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ + CRYPT_PK_DUP, /* Duplicate key already in key ring */ + CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE/* Invalid size of prime requested */ +}; + +#include <mycrypt_cfg.h> +#include <mycrypt_macros.h> +#include <mycrypt_cipher.h> +#include <mycrypt_hash.h> +#include <mycrypt_prng.h> +#include <mycrypt_pk.h> +#include <mycrypt_gf.h> +#include <mycrypt_misc.h> +#include <mycrypt_kr.h> +#include <mycrypt_argchk.h> +#include <mycrypt_pkcs.h> + +#ifdef __cplusplus + } +#endif + +#endif /* CRYPT_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_argchk.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,24 @@ +/* Defines the _ARGCHK macro used within the library */ + +/* ch1-01-1 */ +/* ARGTYPE is defined in mycrypt_cfg.h */ +#if ARGTYPE == 2 || defined(NDEBUG) + +#define _ARGCHK(x) + +#elif ARGTYPE == 0 + +#include <signal.h> + +/* this is the default LibTomCrypt macro */ +extern void crypt_argchk(char *v, char *s, int d); +#define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define _ARGCHK(x) assert((x)) + +#endif +/* ch1-01-1 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_cfg.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,78 @@ +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef MYCRYPT_CFG_H +#define MYCRYPT_CFG_H + +/* you can change how memory allocation works ... */ +extern void *XMALLOC(size_t n); +extern void *REALLOC(void *p, size_t n); +extern void *XCALLOC(size_t n, size_t s); +extern void XFREE(void *p); + +/* change the clock function too */ +extern clock_t XCLOCK(void); + +/* ch1-01-1 */ +/* type of argument checking, 0=default, 1=fatal and 2=none */ +#define ARGTYPE 0 +/* ch1-01-1 */ + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */ +/* detect x86-32 machines somewhat */ +#if defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD +#endif + +/* #define ENDIAN_LITTLE */ +/* #define ENDIAN_BIG */ + +/* #define ENDIAN_32BITWORD */ +/* #define ENDIAN_64BITWORD */ + +#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in mycrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#ifdef YARROW + #ifndef CTR + #error YARROW requires CTR chaining mode to be defined! + #endif +#endif + +/* packet code */ +#if defined(MRSA) || defined(MDH) || defined(MECC) + #define PACKET + + /* size of a packet header in bytes */ + #define PACKET_SIZE 4 + + /* Section tags */ + #define PACKET_SECT_RSA 0 + #define PACKET_SECT_DH 1 + #define PACKET_SECT_ECC 2 + #define PACKET_SECT_DSA 3 + + /* Subsection Tags for the first three sections */ + #define PACKET_SUB_KEY 0 + #define PACKET_SUB_ENCRYPTED 1 + #define PACKET_SUB_SIGNED 2 + #define PACKET_SUB_ENC_KEY 3 +#endif + +#endif /* MYCRYPT_CFG_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_cipher.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,378 @@ +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef RIJNDAEL +struct rijndael_key { + ulong32 eK[64], dK[64]; + int Nr; +}; +#endif + +#ifdef XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef TWOFISH +#ifndef TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef SAFER +#define SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_MAX_NOF_ROUNDS 13 +#define SAFER_BLOCK_LEN 8 +#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +typedef union Symmetric_key { +#ifdef DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef RC2 + struct rc2_key rc2; +#endif +#ifdef SAFER + struct safer_key safer; +#endif +#ifdef TWOFISH + struct twofish_key twofish; +#endif +#ifdef BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef RC5 + struct rc5_key rc5; +#endif +#ifdef RC6 + struct rc6_key rc6; +#endif +#ifdef SAFERP + struct saferp_key saferp; +#endif +#ifdef RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef XTEA + struct xtea_key xtea; +#endif +#ifdef CAST5 + struct cast5_key cast5; +#endif +#ifdef NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef SKIPJACK + struct skipjack_key skipjack; +#endif +} symmetric_key; + +/* A block cipher ECB structure */ +typedef struct { + int cipher, blocklen; + symmetric_key key; +} symmetric_ECB; + +/* A block cipher CFB structure */ +typedef struct { + int cipher, blocklen, padlen; + unsigned char IV[MAXBLOCKSIZE], pad[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CFB; + +/* A block cipher OFB structure */ +typedef struct { + int cipher, blocklen, padlen; + unsigned char IV[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_OFB; + +/* A block cipher CBC structure */ +typedef struct Symmetric_CBC { + int cipher, blocklen; + unsigned char IV[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CBC; + +/* A block cipher CTR structure */ +typedef struct Symmetric_CTR { + int cipher, blocklen, padlen, mode; + unsigned char ctr[MAXBLOCKSIZE], pad[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CTR; + +/* cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern struct _cipher_descriptor { + char *name; + unsigned char ID; + int min_key_length, max_key_length, block_length, default_rounds; + int (*setup)(const unsigned char *key, int keylength, int num_rounds, symmetric_key *skey); + void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *key); + void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *key); + int (*test)(void); + int (*keysize)(int *desired_keysize); +} cipher_descriptor[]; + +#ifdef BLOWFISH +extern int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int blowfish_test(void); +extern int blowfish_keysize(int *desired_keysize); +extern const struct _cipher_descriptor blowfish_desc; +#endif + +#ifdef RC5 +extern int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc5_test(void); +extern int rc5_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc5_desc; +#endif + +#ifdef RC6 +extern int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc6_test(void); +extern int rc6_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc6_desc; +#endif + +#ifdef RC2 +extern int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc2_test(void); +extern int rc2_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc2_desc; +#endif + +#ifdef SAFERP +extern int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int saferp_test(void); +extern int saferp_keysize(int *desired_keysize); +extern const struct _cipher_descriptor saferp_desc; +#endif + +#ifdef SAFER +extern int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); + +extern int safer_k64_test(void); +extern int safer_sk64_test(void); +extern int safer_sk128_test(void); + +extern int safer_64_keysize(int *desired_keysize); +extern int safer_128_keysize(int *desired_keysize); +extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; +#endif + +#ifdef RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#define aes_ecb_encrypt rijndael_ecb_encrypt +#define aes_ecb_decrypt rijndael_ecb_decrypt +#define aes_test rijndael_test +#define aes_keysize rijndael_keysize + +extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rijndael_test(void); +extern int rijndael_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rijndael_desc, aes_desc; +#endif + +#ifdef XTEA +extern int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int xtea_test(void); +extern int xtea_keysize(int *desired_keysize); +extern const struct _cipher_descriptor xtea_desc; +#endif + +#ifdef TWOFISH +extern int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int twofish_test(void); +extern int twofish_keysize(int *desired_keysize); +extern const struct _cipher_descriptor twofish_desc; +#endif + +#ifdef DES +extern int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int des_test(void); +extern int des_keysize(int *desired_keysize); + +extern int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int des3_test(void); +extern int des3_keysize(int *desired_keysize); + +extern const struct _cipher_descriptor des_desc, des3_desc; +#endif + +#ifdef CAST5 +extern int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int cast5_test(void); +extern int cast5_keysize(int *desired_keysize); +extern const struct _cipher_descriptor cast5_desc; +#endif + +#ifdef NOEKEON +extern int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int noekeon_test(void); +extern int noekeon_keysize(int *desired_keysize); +extern const struct _cipher_descriptor noekeon_desc; +#endif + +#ifdef SKIPJACK +extern int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int skipjack_test(void); +extern int skipjack_keysize(int *desired_keysize); +extern const struct _cipher_descriptor skipjack_desc; +#endif + +#ifdef ECB +extern int ecb_start(int cipher, const unsigned char *key, + int keylen, int num_rounds, symmetric_ECB *ecb); +extern int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb); +extern int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb); +#endif + +#ifdef CFB +extern int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +extern int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); +#endif + +#ifdef OFB +extern int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +extern int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); +#endif + +#ifdef CBC +extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc); +extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc); +extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc); +#endif + +#ifdef CTR +extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CTR *ctr); +extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); +#endif + + + +extern int find_cipher(const char *name); +extern int find_cipher_any(const char *name, int blocklen, int keylen); +extern int find_cipher_id(unsigned char ID); + +extern int register_cipher(const struct _cipher_descriptor *cipher); +extern int unregister_cipher(const struct _cipher_descriptor *cipher); + +extern int cipher_is_valid(int idx); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_custom.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,68 @@ +/* This header is meant to be included before mycrypt.h in projects where + * you don't want to throw all the defines in a makefile. + */ + +#ifndef MYCRYPT_CUSTOM_H_ +#define MYCRYPT_CUSTOM_H_ + +/* this will sort out which stuff based on the user-config in options.h */ +#include "../options.h" + +#ifdef CRYPT + #error mycrypt_custom.h should be included before mycrypt.h +#endif + +#define XMALLOC malloc +#define XREALLOC realloc +#define XCALLOC calloc +#define XFREE free +#define XCLOCK clock +#define XCLOCKS_PER_SEC CLOCKS_PER_SEC + +#ifdef DROPBEAR_SMALL_CODE +#define SMALL_CODE +#endif + +/* #define LTC_TEST */ + +#ifdef DROPBEAR_BLOWFISH_CBC +#define BLOWFISH +#endif + +#ifdef DROPBEAR_AES128_CBC +#define RIJNDAEL +#endif + +#ifdef DROPBEAR_TWOFISH128_CBC +#define TWOFISH + +/* enabling just TWOFISH_SMALL will make the binary ~1kB smaller, turning on + * TWOFISH_TABLES will make it a few kB bigger, but perhaps reduces runtime + * memory usage? */ +#define TWOFISH_SMALL +/*#define TWOFISH_TABLES*/ +#endif + +#ifdef DROPBEAR_3DES_CBC +#define DES +#endif + +#define CBC + +#if defined(DROPBEAR_DSS) && defined(DSS_PROTOK) +#define SHA512 +#endif + +#define SHA1 + +#ifdef DROPBEAR_MD5_HMAC +#define MD5 +#endif + +#define HMAC +#define BASE64 + +#include <mycrypt.h> + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_gf.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,32 @@ + +/* ---- GF(2^w) polynomial basis ---- */ +#ifdef GF +#define LSIZE 32 /* handle upto 1024-bit GF numbers */ + +typedef unsigned long gf_int[LSIZE]; +typedef unsigned long *gf_intp; + +extern void gf_copy(gf_intp a, gf_intp b); +extern void gf_zero(gf_intp a); +extern int gf_iszero(gf_intp a); +extern int gf_isone(gf_intp a); +extern int gf_deg(gf_intp a); + +extern void gf_shl(gf_intp a, gf_intp b); +extern void gf_shr(gf_intp a, gf_intp b); +extern void gf_add(gf_intp a, gf_intp b, gf_intp c); +extern void gf_mul(gf_intp a, gf_intp b, gf_intp c); +extern void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r); + +extern void gf_mod(gf_intp a, gf_intp m, gf_intp b); +extern void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c); +extern void gf_invmod(gf_intp A, gf_intp M, gf_intp B); +extern void gf_sqrt(gf_intp a, gf_intp M, gf_intp b); +extern void gf_gcd(gf_intp A, gf_intp B, gf_intp c); +extern int gf_is_prime(gf_intp a); + +extern int gf_size(gf_intp a); +extern void gf_toraw(gf_intp a, unsigned char *dst); +extern void gf_readraw(gf_intp a, unsigned char *str, int len); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_hash.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,447 @@ +/* ---- HASH FUNCTIONS ---- */ +#ifdef SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +#ifdef WHIRLPOOL +struct whirlpool_state { + ulong64 length, state[8]; + unsigned char buf[64]; + ulong32 curlen; +}; +#endif + +typedef union Hash_state { +#ifdef WHIRLPOOL + struct whirlpool_state whirlpool; +#endif +#ifdef SHA512 + struct sha512_state sha512; +#endif +#ifdef SHA256 + struct sha256_state sha256; +#endif +#ifdef SHA1 + struct sha1_state sha1; +#endif +#ifdef MD5 + struct md5_state md5; +#endif +#ifdef MD4 + struct md4_state md4; +#endif +#ifdef MD2 + struct md2_state md2; +#endif +#ifdef TIGER + struct tiger_state tiger; +#endif +#ifdef RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef RIPEMD160 + struct rmd160_state rmd160; +#endif +} hash_state; + +extern struct _hash_descriptor { + char *name; + unsigned char ID; + unsigned long hashsize; /* digest output size in bytes */ + unsigned long blocksize; /* the block size the hash uses */ + void (*init)(hash_state *); + int (*process)(hash_state *, const unsigned char *, unsigned long); + int (*done)(hash_state *, unsigned char *); + int (*test)(void); +} hash_descriptor[]; + + +#ifdef WHIRLPOOL +extern void whirlpool_init(hash_state * md); +extern int whirlpool_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int whirlpool_done(hash_state * md, unsigned char *hash); +extern int whirlpool_test(void); +extern const struct _hash_descriptor whirlpool_desc; +#endif + +#ifdef SHA512 +extern void sha512_init(hash_state * md); +extern int sha512_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha512_done(hash_state * md, unsigned char *hash); +extern int sha512_test(void); +extern const struct _hash_descriptor sha512_desc; +#endif + +#ifdef SHA384 +#ifndef SHA512 + #error SHA512 is required for SHA384 +#endif +extern void sha384_init(hash_state * md); +#define sha384_process sha512_process +extern int sha384_done(hash_state * md, unsigned char *hash); +extern int sha384_test(void); +extern const struct _hash_descriptor sha384_desc; +#endif + +#ifdef SHA256 +extern void sha256_init(hash_state * md); +extern int sha256_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha256_done(hash_state * md, unsigned char *hash); +extern int sha256_test(void); +extern const struct _hash_descriptor sha256_desc; + +#ifdef SHA224 +#ifndef SHA256 + #error SHA256 is required for SHA224 +#endif +extern void sha224_init(hash_state * md); +#define sha224_process sha256_process +extern int sha224_done(hash_state * md, unsigned char *hash); +extern int sha224_test(void); +extern const struct _hash_descriptor sha224_desc; +#endif +#endif + +#ifdef SHA1 +extern void sha1_init(hash_state * md); +extern int sha1_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha1_done(hash_state * md, unsigned char *hash); +extern int sha1_test(void); +extern const struct _hash_descriptor sha1_desc; +#endif + +#ifdef MD5 +extern void md5_init(hash_state * md); +extern int md5_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md5_done(hash_state * md, unsigned char *hash); +extern int md5_test(void); +extern const struct _hash_descriptor md5_desc; +#endif + +#ifdef MD4 +extern void md4_init(hash_state * md); +extern int md4_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md4_done(hash_state * md, unsigned char *hash); +extern int md4_test(void); +extern const struct _hash_descriptor md4_desc; +#endif + +#ifdef MD2 +extern void md2_init(hash_state * md); +extern int md2_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md2_done(hash_state * md, unsigned char *hash); +extern int md2_test(void); +extern const struct _hash_descriptor md2_desc; +#endif + +#ifdef TIGER +extern void tiger_init(hash_state * md); +extern int tiger_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int tiger_done(hash_state * md, unsigned char *hash); +extern int tiger_test(void); +extern const struct _hash_descriptor tiger_desc; +#endif + +#ifdef RIPEMD128 +extern void rmd128_init(hash_state * md); +extern int rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int rmd128_done(hash_state * md, unsigned char *hash); +extern int rmd128_test(void); +extern const struct _hash_descriptor rmd128_desc; +#endif + +#ifdef RIPEMD160 +extern void rmd160_init(hash_state * md); +extern int rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int rmd160_done(hash_state * md, unsigned char *hash); +extern int rmd160_test(void); +extern const struct _hash_descriptor rmd160_desc; +#endif + + +extern int find_hash(const char *name); +extern int find_hash_id(unsigned char ID); +extern int find_hash_any(const char *name, int digestlen); +extern int register_hash(const struct _hash_descriptor *hash); +extern int unregister_hash(const struct _hash_descriptor *hash); +extern int hash_is_valid(int idx); + +extern int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen); +extern int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen); +extern int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen); + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *buf, unsigned long len) \ +{ \ + unsigned long n; \ + _ARGCHK(md != NULL); \ + _ARGCHK(buf != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + while (len > 0) { \ + if (md-> state_var .curlen == 0 && len >= block_size) { \ + compress_name (md, (unsigned char *)buf); \ + md-> state_var .length += block_size * 8; \ + buf += block_size; \ + len -= block_size; \ + } else { \ + n = MIN(len, (block_size - md-> state_var .curlen)); \ + memcpy(md-> state_var .buf + md-> state_var.curlen, buf, (size_t)n); \ + md-> state_var .curlen += n; \ + buf += n; \ + len -= n; \ + if (md-> state_var .curlen == block_size) { \ + compress_name (md, md-> state_var .buf); \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +#ifdef HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char key[MAXBLOCKSIZE]; +} hmac_state; + +extern int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +extern int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len); +extern int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen); +extern int hmac_test(void); +extern int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, + const unsigned char *data, unsigned long len, + unsigned char *dst, unsigned long *dstlen); +extern int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +extern int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +extern int omac_process(omac_state *state, const unsigned char *buf, unsigned long len); +extern int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen); +extern int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); +extern int omac_file(int cipher, const unsigned char *key, unsigned long keylen, + const char *filename, unsigned char *out, unsigned long *outlen); +extern int omac_test(void); +#endif /* OMAC */ + +#ifdef PMAC + +typedef struct { + unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + block[MAXBLOCKSIZE], /* currently accumulated block */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ + buflen; /* number of bytes in the buffer */ +} pmac_state; + +extern int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); +extern int pmac_process(pmac_state *state, const unsigned char *buf, unsigned long len); +extern int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen); + +extern int pmac_memory(int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); + +extern int pmac_file(int cipher, const unsigned char *key, unsigned long keylen, + const char *filename, unsigned char *out, unsigned long *outlen); + +extern int pmac_test(void); + +/* internal functions */ +extern int pmac_ntz(unsigned long x); +extern void pmac_shift_xor(pmac_state *pmac); + +#endif /* PMAC */ + +#ifdef EAX_MODE + +#if !(defined(OMAC) && defined(CTR)) + #error EAX_MODE requires OMAC and CTR +#endif + +typedef struct { + unsigned char N[MAXBLOCKSIZE]; + symmetric_CTR ctr; + omac_state headeromac, ctomac; +} eax_state; + +extern int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); + +extern int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); +extern int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); +extern int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); +extern int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); + +extern int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +extern int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *res); + +extern int eax_test(void); +#endif /* EAX MODE */ + +#ifdef OCB_MODE +typedef struct { + unsigned char L[MAXBLOCKSIZE], /* L value */ + Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + R[MAXBLOCKSIZE], /* R value */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb_state; + +extern int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce); + +extern int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +extern int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); + +extern int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +extern int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *res); + +extern int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +extern int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *res); + +extern int ocb_test(void); + +/* internal functions */ +extern void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); +extern int ocb_ntz(unsigned long x); +extern int __ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); + +#endif /* OCB_MODE */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_kr.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,81 @@ +#ifdef KR + +#if !defined(MRSA) || !defined(MDH) || !defined(MECC) + #error "Keyring code requires all three public key algorithms." +#endif + +#define MAXLEN 256 + +enum { + NON_KEY=0, + RSA_KEY, + DH_KEY, + ECC_KEY +}; + +typedef union { + rsa_key rsa; + dh_key dh; + ecc_key ecc; +} _pk_key; + +typedef struct Pk_key { + int key_type, /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */ + system; /* RSA, ECC or DH ? */ + + unsigned char + name[MAXLEN], /* various info's about this key */ + email[MAXLEN], + description[MAXLEN]; + + unsigned long ID; /* CRC32 of the name/email/description together */ + + _pk_key key; + + struct Pk_key *next; /* linked list chain */ +} pk_key; + +extern int kr_init(pk_key **pk); + +extern unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description); + +extern pk_key *kr_find(pk_key *pk, unsigned long ID); +extern pk_key *kr_find_name(pk_key *pk, const char *name); + +extern int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name, + const unsigned char *email, const unsigned char *description, const _pk_key *key); + +extern int kr_del(pk_key **_pk, unsigned long ID); +extern int kr_clear(pk_key **pk); +extern int kr_make_key(pk_key *pk, prng_state *prng, int wprng, + int sys, int keysize, const unsigned char *name, + const unsigned char *email, const unsigned char *description); + +extern int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen); +extern int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen); + +extern int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr); +extern int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr); + +extern int kr_encrypt_key(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash); + +extern int kr_decrypt_key(pk_key *pk, const unsigned char *in, + unsigned char *out, unsigned long *outlen); + +extern int kr_sign_hash(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng); + +extern int kr_verify_hash(pk_key *pk, const unsigned char *in, + const unsigned char *hash, unsigned long hashlen, + int *stat); + +extern int kr_fingerprint(pk_key *pk, unsigned long ID, int hash, + unsigned char *out, unsigned long *outlen); + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_macros.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,241 @@ +/* fix for MSVC ...evil! */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* this is the "32-bit at least" data type + * Re-define it to suit your platform but it must be at least 32-bits + */ +typedef unsigned long ulong32; + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[z0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64L(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + +#ifdef _MSC_VER + +/* instrinsic rotate */ +#include <stdlib.h> +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) + +#elif defined(__GNUC__) && defined(__i386__) && !defined(INTEL_CC) + +static inline unsigned long ROL(unsigned long word, int i) +{ + __asm__("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR(unsigned long word, int i) +{ + __asm__("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#endif + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#undef MAX +#undef MIN +#define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_misc.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,20 @@ +/* ---- BASE64 Routines ---- */ +#ifdef BASE64 +extern int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +extern int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ---- MEM routines ---- */ +extern void zeromem(void *dst, size_t len); +extern void burn_stack(unsigned long len); + +extern const char *error_to_string(int err); +extern int mpi_to_ltc_error(int err); + +#if 0 +/* Takes up space we don\'t need for Dropbear */ +extern const char *crypt_build_settings; +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_pk.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,245 @@ +/* ---- NUMBER THEORY ---- */ +#ifdef MPI + +#include "tommath.h" + +/* in/out macros */ +#define OUTPUT_BIGNUM(num, out, y, z) \ +{ \ + if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + STORE32L(z, out+y); \ + y += 4; \ + if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ + if ((err = mp_to_unsigned_bin(num, out+y)) != MP_OKAY) { return mpi_to_ltc_error(err); } \ + y += z; \ +} + + +#define INPUT_BIGNUM(num, in, x, y, inlen) \ +{ \ + /* load value */ \ + if ((y + 4) > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if ((x+y) > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + \ + /* load it */ \ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\ + err = mpi_to_ltc_error(err); \ + goto error; \ + } \ + y += x; \ + if ((err = mp_shrink(num)) != MP_OKAY) { \ + err = mpi_to_ltc_error(err); \ + goto error; \ + } \ +} + +extern int is_prime(mp_int *, int *); +extern int rand_prime(mp_int *N, long len, prng_state *prng, int wprng); + +#else + #ifdef MRSA + #error RSA requires the big int library + #endif + #ifdef MECC + #error ECC requires the big int library + #endif + #ifdef MDH + #error DH requires the big int library + #endif + #ifdef MDSA + #error DSA requires the big int library + #endif +#endif /* MPI */ + + +/* ---- PUBLIC KEY CRYPTO ---- */ + +#define PK_PRIVATE 0 /* PK private keys */ +#define PK_PUBLIC 1 /* PK public keys */ +#define PK_PRIVATE_OPTIMIZED 2 /* PK private key [rsa optimized] */ + +/* ---- PACKET ---- */ +#ifdef PACKET + +extern void packet_store_header(unsigned char *dst, int section, int subsection); +extern int packet_valid_header(unsigned char *src, int section, int subsection); + +#endif + + +/* ---- RSA ---- */ +#ifdef MRSA + +/* Min and Max RSA key sizes (in bits) */ +#define MIN_RSA_SIZE 1024 +#define MAX_RSA_SIZE 4096 + +/* Stack required for temps (plus padding) */ +#define RSA_STACK (8 + (MAX_RSA_SIZE/8)) + +typedef struct Rsa_key { + int type; + mp_int e, d, N, qP, pQ, dP, dQ, p, q; +} rsa_key; + +extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +extern int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +extern int rsa_pad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int wprng, prng_state *prng); + +extern int rsa_signpad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +extern int rsa_depad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +extern int rsa_signdepad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + +extern void rsa_free(rsa_key *key); + +extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, + unsigned char *outkey, unsigned long *outlen, + prng_state *prng, int wprng, rsa_key *key); + +extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + rsa_key *key); + +extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + rsa_key *key); + +extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, int *stat, rsa_key *key); + +extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); +#endif + +/* ---- DH Routines ---- */ +#ifdef MDH + +typedef struct Dh_key { + int idx, type; + mp_int x, y; +} dh_key; + +extern int dh_test(void); +extern void dh_sizes(int *low, int *high); +extern int dh_get_size(dh_key *key); + +extern int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key); +extern void dh_free(dh_key *key); + +extern int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key); +extern int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); + +extern int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen); + +extern int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + dh_key *key); + +extern int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + dh_key *key); + +extern int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key); + +extern int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key); + + +#endif + +/* ---- ECC Routines ---- */ +#ifdef MECC +typedef struct { + mp_int x, y; +} ecc_point; + +typedef struct { + int type, idx; + ecc_point pubkey; + mp_int k; +} ecc_key; + +extern int ecc_test(void); +extern void ecc_sizes(int *low, int *high); +extern int ecc_get_size(ecc_key *key); + +extern int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +extern void ecc_free(ecc_key *key); + +extern int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +extern int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); + +extern int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +extern int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +extern int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + ecc_key *key); + +extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +extern int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); +#endif + +#ifdef MDSA + +typedef struct { + int type, qord; + mp_int g, q, p, x, y; +} dsa_key; + +extern int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); +extern void dsa_free(dsa_key *key); + +extern int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +extern int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, dsa_key *key); + +extern int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); + +extern int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); + +extern int dsa_verify_key(dsa_key *key, int *stat); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_pkcs.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,53 @@ +/* PKCS Header Info */ + +/* ===> PKCS #1 -- RSA Cryptography <=== */ +#ifdef PKCS_1 + +int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, + int hash_idx, + unsigned char *mask, unsigned long masklen); + +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); + +int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out); +int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen); + + +#endif /* PKCS_1 */ + +/* ===> PKCS #5 -- Password Based Cryptography <=== */ +#ifdef PKCS_5 + +/* Algorithm #1 (old) */ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #2 (new) */ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +#endif /* PKCS_5 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mycrypt_prng.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,66 @@ +/* ---- PRNG Stuff ---- */ +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; +}; + +struct rc4_prng { + int x, y; + unsigned char buf[256]; +}; + +typedef union Prng_state { + struct yarrow_prng yarrow; + struct rc4_prng rc4; +} prng_state; + +extern struct _prng_descriptor { + char *name; + int (*start)(prng_state *); + int (*add_entropy)(const unsigned char *, unsigned long, prng_state *); + int (*ready)(prng_state *); + unsigned long (*read)(unsigned char *, unsigned long len, prng_state *); +} prng_descriptor[]; + +#ifdef YARROW +extern int yarrow_start(prng_state *prng); +extern int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int yarrow_ready(prng_state *prng); +extern unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor yarrow_desc; +#endif + +#ifdef RC4 +extern int rc4_start(prng_state *prng); +extern int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int rc4_ready(prng_state *prng); +extern unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor rc4_desc; +#endif + +#ifdef SPRNG +extern int sprng_start(prng_state *prng); +extern int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int sprng_ready(prng_state *prng); +extern unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor sprng_desc; +#endif + +extern int find_prng(const char *name); +extern int register_prng(const struct _prng_descriptor *prng); +extern int unregister_prng(const struct _prng_descriptor *prng); +extern int prng_is_valid(int idx); + + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +/* ch2-02-1 */ +extern unsigned long rng_get_bytes(unsigned char *buf, + unsigned long len, + void (*callback)(void)); +/* ch2-02-1 */ + +extern int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/noekeon.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,270 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* Implementation of the Noekeon block cipher by Tom St Denis */ +#include "mycrypt.h" + +#ifdef NOEKEON + +const struct _cipher_descriptor noekeon_desc = +{ + "noekeon", + 16, + 16, 16, 16, 16, + &noekeon_setup, + &noekeon_ecb_encrypt, + &noekeon_ecb_decrypt, + &noekeon_test, + &noekeon_keysize +}; + +static const ulong32 RC[] = { + 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL, + 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL, + 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL, + 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL, + 0x000000d4UL +}; + + +#define kTHETA(a, b, c, d) \ + temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + b ^= temp; d ^= temp; \ + temp = b^d; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + a ^= temp; c ^= temp; + +#define THETA(k, a, b, c, d) \ + temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + b ^= temp ^ k[1]; d ^= temp ^ k[3]; \ + temp = b^d; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + a ^= temp ^ k[0]; c ^= temp ^ k[2]; + +#define GAMMA(a, b, c, d) \ + b ^= ~(d|c); \ + a ^= c&b; \ + temp = d; d = a; a = temp;\ + c ^= a ^ b ^ d; \ + b ^= ~(d|c); \ + a ^= c&b; + +#define PI1(a, b, c, d) \ + a = ROL(a, 1); c = ROL(c, 5); d = ROL(d, 2); + +#define PI2(a, b, c, d) \ + a = ROR(a, 1); c = ROR(c, 5); d = ROR(d, 2); + +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 temp; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + LOAD32H(skey->noekeon.K[0],&key[0]); + LOAD32H(skey->noekeon.K[1],&key[4]); + LOAD32H(skey->noekeon.K[2],&key[8]); + LOAD32H(skey->noekeon.K[3],&key[12]); + + LOAD32H(skey->noekeon.dK[0],&key[0]); + LOAD32H(skey->noekeon.dK[1],&key[4]); + LOAD32H(skey->noekeon.dK[2],&key[8]); + LOAD32H(skey->noekeon.dK[3],&key[12]); + + kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]); + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,temp; +#ifdef SMALL_CODE + int r; +#endif + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]); + LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]); + +#define ROUND(i) \ + a ^= RC[i]; \ + THETA(key->noekeon.K, a,b,c,d); \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + +#ifdef SMALL_CODE + for (r = 0; r < 16; ++r) { + ROUND(r); + } +#else + ROUND( 0); ROUND( 1); ROUND( 2); ROUND( 3); + ROUND( 4); ROUND( 5); ROUND( 6); ROUND( 7); + ROUND( 8); ROUND( 9); ROUND(10); ROUND(11); + ROUND(12); ROUND(13); ROUND(14); ROUND(15); +#endif + +#undef ROUND + + a ^= RC[16]; + THETA(key->noekeon.K, a, b, c, d); + + STORE32H(a,&ct[0]); STORE32H(b,&ct[4]); + STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); +} + +#ifdef CLEAN_STACK +void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _noekeon_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d, temp; +#ifdef SMALL_CODE + int r; +#endif + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]); + LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]); + + +#define ROUND(i) \ + THETA(key->noekeon.dK, a,b,c,d); \ + a ^= RC[i]; \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + +#ifdef SMALL_CODE + for (r = 16; r > 0; --r) { + ROUND(r); + } +#else + ROUND(16); ROUND(15); ROUND(14); ROUND(13); + ROUND(12); ROUND(11); ROUND(10); ROUND( 9); + ROUND( 8); ROUND( 7); ROUND( 6); ROUND( 5); + ROUND( 4); ROUND( 3); ROUND( 2); ROUND( 1); +#endif + +#undef ROUND + + THETA(key->noekeon.dK, a,b,c,d); + a ^= RC[0]; + STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); + STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); +} + +#ifdef CLEAN_STACK +void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _noekeon_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); +} +#endif + +int noekeon_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0x18, 0xa6, 0xec, 0xe5, 0x28, 0xaa, 0x79, 0x73, + 0x28, 0xb2, 0xc0, 0x91, 0xa0, 0x2f, 0x54, 0xc5} + } + }; + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key); + noekeon_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (memcmp(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int noekeon_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *desired_keysize = 16; + return CRYPT_OK; + } +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/base64_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,35 @@ +Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1 + + 0: + 1: AA== + 2: AAE= + 3: AAEC + 4: AAECAw== + 5: AAECAwQ= + 6: AAECAwQF + 7: AAECAwQFBg== + 8: AAECAwQFBgc= + 9: AAECAwQFBgcI +10: AAECAwQFBgcICQ== +11: AAECAwQFBgcICQo= +12: AAECAwQFBgcICQoL +13: AAECAwQFBgcICQoLDA== +14: AAECAwQFBgcICQoLDA0= +15: AAECAwQFBgcICQoLDA0O +16: AAECAwQFBgcICQoLDA0ODw== +17: AAECAwQFBgcICQoLDA0ODxA= +18: AAECAwQFBgcICQoLDA0ODxAR +19: AAECAwQFBgcICQoLDA0ODxAREg== +20: AAECAwQFBgcICQoLDA0ODxAREhM= +21: AAECAwQFBgcICQoLDA0ODxAREhMU +22: AAECAwQFBgcICQoLDA0ODxAREhMUFQ== +23: AAECAwQFBgcICQoLDA0ODxAREhMUFRY= +24: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX +25: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA== +26: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk= +27: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka +28: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw== +29: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw= +30: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd +31: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg== +32: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/cipher_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1539 @@ +Cipher Test Vectors + +These are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style. +The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key) + +Cipher: aes +Key Size: 16 bytes + 0: 0A940BB5416EF045F1C39458C653EA5A + 1: 2B20AF92A928562CF645B1B824F2E6D9 + 2: FC29C3356937ECC3159D8D6EF5E883A1 + 3: 4C07B5A2EF31A3229C87AB2E4DE88602 + 4: 93AFA1147E793FFCC3D852695A62D008 + 5: D4BCC317DC9AFE0E6C7AD1E76F79DBE9 + 6: FEDB3371F3C65162AFCCDC6D18C79A65 + 7: 4AF2A76F93F07C14161C16B5C176E439 + 8: 00A1A596AF7CF44FD12981FA12CB1515 + 9: 8013D7006AB38AEBD40D0DC10328751C +10: 81A077F3A262FA4D00D98EE4D1BEC390 +11: 0CCBC99A3135F26D2BE824D633C0366F +12: CDBB5568610AD428706408B64DB66E50 +13: CE94461EB0D57C8DB6AEB2BC8E8CE1D2 +14: 06F14868F4298979462595C0FBF33F5A +15: FE22A7097513246074B7C8DFD57D32B2 +16: 0F2D936610F6D9E32C0E624568BB8E6F +17: F32BCD92B563D475E98322E5850AC277 +18: 6E6FCB72930D81469F9E05B20FD406C0 +19: 42FF674CBA6C19C4AD84D42816173099 +20: 41C12474A49B6B2B5E7D38E03A4DD4E0 +21: F9E234E3CE3FCED184C775B6140AD733 +22: 7EB5CC6B183D8B3EB4FBA4717CD8838A +23: CB6C5D78F9721E5BF8E980F0EDCAD4AF +24: B3F20EF6C26FD9301576D82DA6D50809 +25: F9375037377D86599FB4F241166C43E9 +26: 98BAF9AB7402479C2DA356F5DAE35D5F +27: 58D1A8E0DC3BC53FD995BB0F60F25FE7 +28: 0A75C0D22D2627C97BA2A7344B9B8C74 +29: 88C299B2F8C9EDAF86A301BBF534BDA7 +30: 755E3A17420281F2C619588A6B521FF9 +31: 0E540DD25C0C147461146E11F832A63D +32: DC5B58691C6BA5B243036A41301BD7D1 +33: E9299A7336C2D8A51D6C7E2BD1B8F054 +34: 78CA6F682FC649DB289DD62D28D3A22D +35: 98D96EDA081DE416083650B22BD3869D +36: E747DE96D122CE1EF6F89BDE0FAE75FF +37: E48DDF2EDDEB54C861A1E42F5B649EEE +38: C650C2CF1E903B7F9C8536A2446CA762 +39: CF0BCDCE0F1FE7EB40016C1231FB2962 +40: 37B1C8BE3812147E0D5D115A797663EF +41: 45DD8184581049C4B28FBC0809690C5D +42: 11B0D889F96E677EEC2E934E9F7F5398 +43: CEC30BC1128A96CD506E406B5ADFAE19 +44: DE67D5439BF83D5338D53F362FCF79B6 +45: 724FBB2D95CBEABC568AA44941D9B6E5 +46: C63F480DA3C73B2A661F1FBC3E4D1F89 +47: 225CD18789D18FF09C982EF38AEF0AAF +48: B493DEC7E3D11911DEF8788102453670 +49: 23E0B12A67DF025CB77CBDF9E295FCAF + +Key Size: 24 bytes + 0: 0060BFFE46834BB8DA5CF9A61FF220AE + 1: 597FA00D03EDDC81C2575B4DD6B6AEFD + 2: 4881E4EF69005DCB9110BA327CAC8460 + 3: FC4A968AF65FCFF45E4698455918673D + 4: 3079D7B27A3DA5C0805A61CC37109EE0 + 5: 9B3F2C7C35806276E2C53826EC1B3C84 + 6: FCDFCB1FD9FCF1B63E1AB6737FC154E8 + 7: 4A8012AFD410D29CE2CEE0FD195EF9DA + 8: 9F4201C4174C71A3AEF8FD6822197D67 + 9: DE3E5E98DA60E895389A1C17E3D50DA1 +10: 20C9064A076C01D1BC121A5A2A1F913C +11: BA41A36CD24B515545B8B464B244E5BE +12: 2CC1DE9DBCAC45269C6DBBC9203095F4 +13: 2ED2499CFEB30203E6305B3E1C329C4D +14: FD709FC0AB48B204C95B74AD189C8832 +15: 7ED298B472C53A4CB7A3BAE588805E86 +16: CB0C6FE2BA76901F9EDE752634DCC31D +17: 6C5CA6EFCF7101881507AB8770ACF1DE +18: DEC3C5209E98BBFAA469C5FE6C02A674 +19: CFAC040C1198C8264679CACEAA7E9DE7 +20: EF990992EBA8ECA7E5F95E3B9D69D3A4 +21: 8FC1B640EB55A96D08D83D1184B77769 +22: E1F3DFB9D055BCB2D6CED6DCB8361BFB +23: 6621F47057706F2A079819DBC0197B9C +24: 882611AC68778CBD6A46FB5DD4611A37 +25: F35E1367A283CC641FBCE26512A8F2F1 +26: 5A4A71F69056CFBAB67DDA777F5CD945 +27: C446F2BFAD060A9E9E17F71B05ADABD0 +28: 1F0E50F71A67FAA7D169A7A1017FFD65 +29: A6A38588848915509451A2354D2AAC8E +30: 4C887574F2C5DB00ED4FBAF814A70302 +31: 1B642944162A049CCA9FD0284D7AB4C3 +32: 431BD9293C5BFD12F948C255C838880B +33: 32CD23A30039AE2FB80B804B905362B1 +34: EBB30E07E7517580A645CD1B5F664182 +35: 292F2BB28BB172620B05C7621BA347D6 +36: 46C06E1223F392D57B98EFCF4C832C18 +37: 451DFBAD2AA92080204F85432236A42C +38: 768D6206D2B3DD1B9C26FAA5977A6477 +39: 3705F9CEBFE8F91ECE07F84578C05494 +40: 085EB0DCF360F5403FF1E7402A0F7A03 +41: 2A0D56F2E7C7FCE3095F511BDE4AD9A2 +42: A8AB2F3643A61AF164F99FEFAE2CE1B4 +43: E73FD4B1FAE0E5E6A6A31CCC2AF96386 +44: 578E84FD1AA16FF350374E4FD5FDD529 +45: EEAE301DD57084801DB01F8B9C4036CE +46: 1C44A93B404298327857F71962E0604C +47: B5F64CD5835C85A68DC23E26D4B8FF80 +48: 6C6F97850A87088AF195D0500B3F5D78 +49: 0BAB3A60A25CD1A750C2C443AA01C57A + +Key Size: 32 bytes + 0: 5A6E045708FB7196F02E553D02C3A692 + 1: 5F7229D6AACF0DAFE3B518C0D4ADBAB4 + 2: 96477F47C0A6F482AC4036D2C60FAAD8 + 3: 7F791D54914F12E9F0D92F4416EFBEC0 + 4: 87DDB19415BEDC42BD361FE380553C5A + 5: 8EDB2A09DC8731DB76D9F67A03AC4D9E + 6: 269A7C08C28D5E4D9355DDBA161F862E + 7: 042A3397BA5029C443DD76755008DB2A + 8: 469C82A94BC5F7B2DF57F0CE1716EE74 + 9: 5A84A93077FA19146078310035F4B7E4 +10: 28CAF1C0D811F86CFD3C5EFC30DF79F9 +11: 05B575D06C2D593B708F7C695CE97571 +12: B7E8CACF0A0BD7F2F5DA0B09CC8B8AEC +13: 0ADDE90F66F1BCF38CEC63EFBF9DBD46 +14: 9BF99E7F5B8F176DD686AF017D5196E2 +15: ABC189EE80D4A4588B3D54DDACCD9778 +16: A57405378580B1E8A8D877791300374C +17: D1EF03F72FAB3DB68022FC60A2CEC13D +18: 3D2406231BA17FF7CC973C5E203872DF +19: C3E07233BD101502953D6186001838E4 +20: DC281C0CE02A83098C80D6C9463F3449 +21: A923023D2390B2230FCE9217776AAAFC +22: 92E28E69009959FB84046C5ED1B64D1A +23: CEF8F684EC64A31C651280CDC942DFC2 +24: 5A954684B22691F9CFC60442A654EF61 +25: 56A38A0D93188BAA50DFAF2CB799A76C +26: 54503340C5DE26679AA5F35215DE85EA +27: E74BFAF64946DFD699583FF9C47A1EAF +28: 01F234F9868B085E9B1A2EC84738E2DB +29: BBCA3DAEAB24EF25BC7B623F4D9FD680 +30: 3956C880F7F7D94ABC259D3D86157F27 +31: 4672C2149054C839C537BDA1F5BBF8F4 +32: CF1E9ACBEB391062593BD88C7948F64D +33: CA5B4E867AE9D8BA2D4416C908EB99F1 +34: 36666180C768636CF1708CC5C85A6875 +35: 53E396D2755218675494C7AA515A2310 +36: C2B7D31A59A602A65E155F80353DB83D +37: 0EBCE19FF6FC03E327A2602F858D835E +38: E47CC2A5E6C7FEF185806E2CFB304D91 +39: D61F15FF75E0F523FA3872132A09AF42 +40: DCC25495052980986AE30756BA0417DA +41: 451BF5B7C1F1AED9F3D5E18A391EA4DA +42: 1B6B105C580083D23F3A8EACE41B7984 +43: 8C2F86CD6C86B67C9EBDCAFC5720E4F8 +44: 41360BDB3E4C6836BE0D15B659CEC5AA +45: F972104AD851BAE0AD963817A3F03F58 +46: 396095F7C102B5A238110DD3D6D4ADFF +47: F58391AEB9A5D8BB32A3055B37556E81 +48: A23789B146CE89C876F3C331901261D8 +49: 2684AF345C4B13FA154E93A3E2CD2A90 + + +Cipher: blowfish +Key Size: 8 bytes + 0: 84BF44A1442B8217 + 1: 3981205BDD22C01E + 2: 0ACC5CCBA118CD07 + 3: DF76980D5E089145 + 4: A8503E8D849C599D + 5: 5E56574687038F5F + 6: D63296B036996F50 + 7: FD2FD7A0669A9E7A + 8: BC6583720A962585 + 9: 4B38C2856256103E +10: 48A4FA354DB3A8A6 +11: EF97C32734BE2A10 +12: A7467E9C729F8123 +13: 04D2507F9C4B5854 +14: 57F76A4D406B22D1 +15: ED0A3B26D842C8F2 +16: 047CB457E9730CD1 +17: 9F13BB1A97BF5E2F +18: 628CA4F77161C95A +19: 37C7D8EF718DFD50 +20: 2C9A9C655B839B1E +21: AB222D66579DBE0D +22: 57950CDEAD6FAE88 +23: 67AAB3669431E403 +24: 6B35C87144F6B748 +25: 94C2E8A1DBC963C2 +26: ECD68F56EED1F78E +27: 2E7BE0B866B1D3C7 +28: 6671DCDCB3D8EED4 +29: 8ACBE7A2F77FBB35 +30: 0BF0AC4EAE284F93 +31: 29928AE5DC8A57C6 +32: 84E48C27E21264DF +33: 4EF0E943E4F48ED3 +34: DA155BEFBFFD2638 +35: 611EC83E0931FFBE +36: 3BDDEC15BC543A92 +37: D7B9564BBAEE19FC +38: DE44907E9F0A1F11 +39: C8638C0594D13614 +40: 9E67F1B15418BF14 +41: EDF531A083F72852 +42: 7E5F8F9A72890BB3 +43: 2A0B060E3EDDE9C3 +44: 9B4B0F6FE6511106 +45: 328658F222C7FCE4 +46: F6F1B50B4F9F9C93 +47: A620519E69952F5E +48: 24DA24DFE96AD818 +49: 226C43435FBDA34A + +Key Size: 32 bytes + 0: 46CDCC4D4D14BA2E + 1: C079641BD6584E5A + 2: 38828DF8B4C4920C + 3: B4ABCF6B78A721F3 + 4: 8E7E2914CBBA708C + 5: C0EBE7002C888495 + 6: C60F404DE7CF9B78 + 7: B29E843E1771EF26 + 8: 983033386CA6A09B + 9: 76F1F89AFDCF7130 +10: BED4E2114F4376FA +11: 879A2B9D19AFAB87 +12: 366201BC87532AE5 +13: 6F409580FA907A64 +14: F7A202F00A38863E +15: 98B0A9C79FFC27B1 +16: 1CB68D9BBF8A1A8A +17: C21A2C54E5471D23 +18: 76A81C3DFC149934 +19: C7A0627412FC323A +20: A034684D7058E7A6 +21: AC87722F27029BC2 +22: 36A6C2AF10245E3E +23: 1F85B90D11217EBE +24: 9C2A0C383A4AB7D5 +25: 11D5C689039CA179 +26: B0B38C7077E1450B +27: C59C7DCCC3B8A1BB +28: 9BC539F29208AC24 +29: 8546F17C77C60C05 +30: B189C3E92AF53844 +31: 3C7689163B8D2776 +32: 6AFEB9A0671156A8 +33: 05514E39F2990008 +34: C941E31A2A1F42BF +35: 87C3777C74A730A0 +36: 2861667755C8B727 +37: AF75A0312433B151 +38: F76939331E9C9792 +39: 819FF8C81FC7C8DC +40: 31E7B07EB03D170D +41: 696E5EC1A741170E +42: 6C5BF0E0BA48FEC3 +43: 6D751BCCDC475797 +44: BB5A91D0CA7E60F4 +45: 7F7EC0531C88B14C +46: 9F302392529B70E8 +47: CAC9A1A88F09AC1D +48: 39D56A652E02D5B0 +49: 13641D42BC126517 + +Key Size: 56 bytes + 0: 373C66BBA50EB9CC + 1: A4E8C602AE3A2CEB + 2: A59F08BA78502F32 + 3: D0D4968015F4E4FF + 4: 0D3C2F291E6C2EE0 + 5: 3F99F5DADAD5FD2C + 6: 5BA41EC1A506396D + 7: 0BDE3B5B50591D35 + 8: 5C4A6AEFA69A115D + 9: ADABFE96D6D159E8 +10: F97F0B9C88ACD5C0 +11: 8882A163F0F02BB2 +12: F00556C9F5A56A32 +13: 257615BEC96CC228 +14: D58DAEC547DD8B89 +15: E677F4953EC44097 +16: 20156D066DC37000 +17: 6F18E01C6FDF947E +18: C8DFF24F12621237 +19: 032F91C5119AE308 +20: 394194AD8BC1E5CF +21: 6F24E937F3925581 +22: 086A4510D95759F3 +23: 073204BADF0EE942 +24: 5BC8B8E402D90F43 +25: A10B7E9D01DD3809 +26: 22C0B183AFFDA506 +27: 216306AE6DDBAF3F +28: E275E1F52430A1FD +29: C3BDB49D588D31BB +30: B860818C5923B688 +31: BE1BC7A444B0E141 +32: E4C4B67900DBC8DB +33: 36D7B7ECB6679A9C +34: C1EAD201EE34BEF7 +35: 9ABBC877CE825B14 +36: 3B211121C0C3C09A +37: BE3B34FF2E83F5A7 +38: 46C2B3E628A53EAD +39: B7E7DDE16C7DFF62 +40: 3C9A14C4226EBCC5 +41: C5FD46242DB29704 +42: D45A96723FF62201 +43: BB015D10878CF70D +44: 71DB021BE398D41A +45: 06F52D237F06C260 +46: 3552F47E8CCFC73F +47: 769E33828AD5D88E +48: 659861DDF080AA67 +49: CF7A13782F317342 + + +Cipher: xtea +Key Size: 16 bytes + 0: 256004E1F55BC0C7 + 1: 2D385C151A691C42 + 2: F93BFEA758A7DDB4 + 3: 2A905D97C0CA3E48 + 4: 12C7C2787B913AE6 + 5: FB24B1F32549EF59 + 6: 2A8BFF867FB4FF73 + 7: 5692243526C6BA77 + 8: 4CD423ADFCDD1B6C + 9: 9B99AFC35EB2FED0 +10: 416B4AA4E07DA7F4 +11: 4DBC9052ABFF9510 +12: 8AF9457F8E599216 +13: BC3CA2B1C7267395 +14: E4BE31DF42282F7A +15: B344CA8AA57E9E40 +16: 57A1F94CD2F4576D +17: 96177FCD28BFF1BB +18: 78A1F63A0EBAAC33 +19: 5F3FCBCD7442B617 +20: D6F7CD5ECA688967 +21: D92EDF70CBDE703F +22: E2E2C2EE5D18E58E +23: 4BF00478CB7833C3 +24: F9936D550815FE8F +25: 19A3B07B3E47D7D8 +26: ACA441F099A7E30C +27: F70183F199988E3F +28: 0A41FC22F369310A +29: ABFAF40853A4A38C +30: 6B5D29DB1155D96B +31: 0DD0C08A27561D66 +32: 4C56E22292F17AA3 +33: 3F925ED65613DF4A +34: 521B4C97081DC901 +35: 2B1EC3E1C8CF84EC +36: 2A412556F42A48F6 +37: 0A57B8A527DFE507 +38: EB55C9C157E3C922 +39: 6E6D6E9AB925ED92 +40: A4C5C90A0D4A8F16 +41: 7F9F9F658C427D55 +42: 9A5139994FF04C3F +43: 9054771F027E29BC +44: 90543E7BAED313BD +45: 5DEC1EBE6A617D36 +46: 19AB6A708CDB9B2D +47: BABB97BB5CF9D4E4 +48: 2C2ADC05AF255861 +49: 52266710153E3F7E + + +Cipher: rc5 +Key Size: 8 bytes + 0: 04F6B9B18E6828C1 + 1: BEA50D165E50EA04 + 2: 6F3728FE19F09B03 + 3: C682C26278B372FE + 4: 78BCC81E144E1B0F + 5: B62775716366450F + 6: 5BC49690F97CBCFC + 7: 359414E9EACDE379 + 8: D3331D8ECBF684FF + 9: 13129FB10EAFC82E +10: 7F29218421CC4B5A +11: FC225A4F31A75162 +12: 29BF8BFDA8A15D37 +13: 6854AC5BD98EEE95 +14: DEF05AB6D102E992 +15: 317C3EA6F0600016 +16: D6F3658B2E80B77F +17: 7C1DF7ED6C92C23D +18: F8665145BAFE28C5 +19: 9D8059C34B79F0EF +20: DC8D1617D3EBC7DB +21: 2D8FF59FCA19BE6C +22: 5C6956743715EA13 +23: 91160BE1F4F3D4A0 +24: 1D482C2359EC93F5 +25: 9C21D1A3755A7251 +26: E48D1BB926D51E63 +27: 08A054946263F617 +28: 9C900BA37199B7C7 +29: 0C6C58743EC83082 +30: B24197EEB5603D3D +31: CF5B735F8A492E49 +32: 337C504698BBE553 +33: 3A2BCCC88BE9ED51 +34: F3E9241743203ABF +35: B67BCC625815C585 +36: F8E96E4EEBC2566C +37: E27D162006C67C8D +38: 08CE8C1A5E3C169A +39: 0CF8AD04125EFCD8 +40: 6712F9F044864FAA +41: 0FD465AFFD64085E +42: 6BA8C82B3974391F +43: A5FFF24CE9659357 +44: 0947F81E1EB4970E +45: DEA966CA50243067 +46: 1F1BE4866F48E39F +47: 03A7D7CE793F52C7 +48: A1FADE3F801B414A +49: DE7DA6D14A50E305 + +Key Size: 68 bytes + 0: C8704ABBDA9624EE + 1: C719C645E301FC16 + 2: 32D82553B0E35EF8 + 3: C63C77EE6C2A6E36 + 4: F84EDA1E77ECB5F0 + 5: 382C1E72AA1FD1BC + 6: 6B00939F535F9C83 + 7: 3CE0825AE10C2B0E + 8: 1F9E7738602BDD0A + 9: 9273E7933CED0B0A +10: 4CAB45EEA45C32DC +11: FD0208C6A89FB519 +12: 520D8E6912E9551D +13: 5B88684544868BD5 +14: 32AA2A8EE58135D4 +15: 281045702DD38766 +16: 26D68E073C996747 +17: 23DFB9E174D86192 +18: E32FD5AF5101E45C +19: 3DEFB679670A143C +20: E616394D859BFE94 +21: 217B9BE0ED47DDAD +22: 4F7901A5620EA484 +23: 6654C042783F5737 +24: 752AA74BACF9BE65 +25: 2FAEBEB8B325F89B +26: 6FEA020B058F32CB +27: 2A32682A36691665 +28: 338C8AB628A30105 +29: DFAE9DD082DFE38C +30: 51B451C29DBA19C4 +31: A2993DA9B8C1D5FD +32: 24D92FA331E2F93A +33: 821A961C0524C89D +34: A07BF305EE8964D9 +35: 981652361262C5CE +36: 3DD770C3761B695B +37: F36359AFE1C8A07C +38: BEBC629B8938F4A3 +39: 2E31DC53F77898B3 +40: 52E4104C4E8E6901 +41: 75C912DA610525EA +42: 2F280F70963F82DE +43: D7E3FCCA75AEE5DF +44: 8EBC7E825A14A2BB +45: C1138701F64187DB +46: 1294E21ED2550DFA +47: 577820D772BE2C8E +48: 48CE93C46BFD33CD +49: 3B50D264382E03BC + +Key Size: 128 bytes + 0: 236CF0A207576E8E + 1: AC12D8F1AE55F057 + 2: CEC4230F747B547A + 3: 61EA1B510D033B26 + 4: E064F51998E20804 + 5: 6247797DF02BAEF7 + 6: D25A766244063A7F + 7: 2C2B3FDDA0E07067 + 8: 04EED646C3F6FF90 + 9: 05487E7702865E4A +10: 6C0A92AC23ED07C5 +11: 6E54E768C797F797 +12: A7C53BF7B252A884 +13: 731052795E12C80B +14: 3E4DAD15A826C43D +15: 10B1191B4012C2A0 +16: ADD244B33AEAEF7E +17: F6CC7B5F0885E056 +18: E23489F3B7BE438E +19: B0C27661692FDE4C +20: E81CE014DA769F07 +21: 7A8BE0D2D52623A8 +22: 082F444E00D5E127 +23: AE42F684ADD1DAC7 +24: 9061BA686F76A450 +25: 9BEB7141B8F6F5F0 +26: 38CBA9933AEF85E7 +27: C66F4245901CB341 +28: 8659AA47E6B06BC3 +29: 357AB20DCE2DDA3E +30: 236689C2F36976D9 +31: 331EFD7D5CF7AD50 +32: C373526C2D44DB80 +33: 79F7ACBA770F5C92 +34: 64325C5A67F364F6 +35: DF2F720829FF1694 +36: 9EE17F47ED487BC6 +37: C41067896AF4CFC5 +38: 5776E1E5FBE59933 +39: 07A05B1508B739E0 +40: B19EF72A65B3C035 +41: F8BF5FF4095C0173 +42: 7F1226C6CA7B4072 +43: 8A6C8F26A97DD33B +44: 62948A9A627E98AD +45: 9EC58E3F8A477D21 +46: A656F285AE0684B4 +47: 8489690681A53EE5 +48: 940915E733721837 +49: 1221956BCEE0143B + + +Cipher: rc6 +Key Size: 8 bytes + 0: 6533F7041D69B9B883A5305180A85520 + 1: 496683D6356950E8F4AF4582630BE46C + 2: CA421828FCFCEF2F042F6D81F14CBE76 + 3: 92DB67F2F057858FC806E071D239F245 + 4: 203CDFE0C36434AEDDBE2DA68ADC5EF0 + 5: 8EB23BDBD58A279C1F3BF75199FC9E34 + 6: 8FA8BB4E772E09DD1EFBE03090E77FF8 + 7: 2018803BFD91D157AE20C6E8FF1894B0 + 8: 267319634294F0684AFA7B26EB612B3C + 9: 108745E1F2E80864D9043582CD5550EE +10: E4F9EFE5A6C426BB719EA17174890D0A +11: EFFD4CAE649740B3309692AA19ACA227 +12: EB909E6D0789F649538E7EA1686FC0F9 +13: 0216851E23EDAE52D9964939DA0A7493 +14: D6A9CD3429D1679D26A9599EBDE5409A +15: 5DCDECA6E89A7F0EB40649EFDE6420AF +16: B74FD556B06C07BA8D9E517348CC66CC +17: 9A22CB5B73EF1DDE68A5AEF1B1510ECC +18: 77F78557143E08A7449A75A13098FEF8 +19: 548FE6700BD17D0AE247B07C2F1AB0E7 +20: B7DFD8CB428A36733BBE9A51CF45C072 +21: E7E8B7AA2D93E3DE99C543A473CC6760 +22: 3FA5821248B0F0AEB5CF00EEF7958F5E +23: 0A655AC6C51DB33849BCDA72DAE106F1 +24: 9EE93EAB01E1A1DC57B698C266469481 +25: A7D398720E0ABA2D0D143D8306FD5AC8 +26: 98A46C94125BD2E5600BD26EEA420F2A +27: F4789EDC3C50BC4186816F14A86403D1 +28: F8AFBA8EC652EFDC3AF5EA5CFE143E16 +29: CEEEBD4B6724A30E1859A5B4EF9B2B3D +30: 766715B4C4FA7CD4B365A2A67C79E48A +31: 92C5EB7BE61155D79DE0A6F55715DA22 +32: 42CF0C9B2BAACB085CB1603688037D0F +33: 6C4BE816F7B573CCFA8BB6E399EEB17F +34: B6D7E606CC99D267ECCFDBC006878691 +35: 2048B58B74F9A721B2E33D2EB86F5991 +36: 3E458C1015ECB08CC7B8980135E71893 +37: E4E28A032CF2F3C8262CD4BBE7A4CDF8 +38: 701EAA449AD9E5AF81DF3F436AB25620 +39: D1C3FB7C16F5249503EB389A692B112F +40: 7012790DB65526DC87F9A2BF0FBB5664 +41: B782A3104FFE65DDB340F713ACFFE25B +42: A155F033E4536FB1176EBDF9EB5FEC4C +43: 8898BCC7A008127014850D5529327352 +44: 8F4B3BE150FAA0371CDE69891E52A3C9 +45: D371C8283F68DE983C98D98A7563B934 +46: DEB679915E8F0D0B65B37918BE4596F7 +47: 84D74F7FA199304A47BB37B8AF893CF0 +48: 5367B0187496539F6DF6CCE0965B376D +49: 4B9C6011D43CF2D8FAFA2E7105D85024 + +Key Size: 68 bytes + 0: 6BBF763FF30876A4BBB68A7E7E290770 + 1: 59852279E82E98B8B680E5CEE12BB99A + 2: F96989565E5B163EA483FF74ACA22DC9 + 3: 221F7A410F5AD73C1C67DEBA99683E0A + 4: 55F058D1D9B8C372E2A28AB6E953A851 + 5: 24A8F7E07620A55D69CC3981B92E5CCE + 6: F4D9DA95BF66FE28BA3A84E77E62822D + 7: EE7EAC2BD34DDE6F83E6D4F23C0A49D3 + 8: 4218AA697FB7C5D897E66EB00A9FB489 + 9: 55A8CDF8608A3B1A6B14275E2258A096 +10: 18D50743982F5C8A5C528BDB5896CDFC +11: 391403B889F0CEE865893EBE9F1BF90A +12: F3CA9C30C163C510432D3207DB6967EA +13: B14B6574DF53257BE4508DBE78843B47 +14: F52F1E5FD6FB19C1F5466276F9C33A97 +15: 9D5AABA86E8B65E4F633B6EDE17516E8 +16: 9038CF746F722DA1A0C34461359FD378 +17: 398E317E9CC074C2293B59598F72EA64 +18: 9D75D897D487DD2B5BC534B4B223ADD1 +19: 6C6DFF734BFB9700EDD6B3CFC6E311F7 +20: E27591407CA9771F227A5B6B3A77C928 +21: 1618F15FFA8E2692A3B3EF8EB6151427 +22: FA426AC6161F31F0D63FC9DA97A6A393 +23: 1281869E9959DED2CF75F50DA7FAB66A +24: E8BF17E4B76D6DC5C1D07DC80970665A +25: 9A869B6C5EEF391C7E7C4585FFD9FF3A +26: 59564F799AFC984D39A8168D1A30C8C8 +27: 1D3927AA2E2C48E6CFEF88D04ADD30DE +28: 39BF89DE1365DF15A8ABA86856ED074B +29: 0CCC4A4DEB36A000E7EB271F5EE54543 +30: 26476623D35A514B8833D868426A2BE9 +31: C3C85993EA15AB2D056D670707851802 +32: BF5F7ED18E1320BAD536DCEDEE1A9AF7 +33: 337BDC5FF0F7AD44E6A3F5D6712BD5DF +34: 7DBA76B3D9C818D0CE1A530BC79E77D2 +35: 20DF55E617CD2598F18534DA7A22B555 +36: B0A0C1BDF9E81B4F07F47D31A9CC8408 +37: CB9586F4B27F759B9B9C6C7DB01D26A8 +38: 1E79A2894906A64098AC43799CEFED38 +39: 82FA120F237EB0B3A1F8B52379B8346F +40: 3DB9848603E3B1134585E5C9001D119B +41: A750875900E244996887EC995131D151 +42: 12133748D3745F77C161470A921F73BD +43: A265C351694574B44517FDAD8816133F +44: 5E50CC8281C2A69FD376250D99620DD3 +45: 443ABBC1AD5605A0BA05B8E6ABA5D2A1 +46: 73546A87B39C54F0639EBEC118ADA007 +47: 380244C822817453C75405B727D67C4B +48: 73F1E23DFF05EFAB5D39E503031C4165 +49: 8030071491490590A8913AE4B5D082CC + +Key Size: 128 bytes + 0: 24B06811BD97AE9512B3799E3189DCD3 + 1: 92DBA6269E880F8D8A09143D792A46DE + 2: F956F459C333DFBA4C6A309C613DD661 + 3: C31488EA551CC0FC8885F6817CA696FF + 4: F59634FE907F9DF9467BD1059F82DAAC + 5: 051AF11DD2FCF742169B58A786128CE7 + 6: 87326A3A4A98CC15B23DFBFFC5AE16D3 + 7: 58FCDE2E88A79D5682729ADB4D971142 + 8: EAA787D68EB68CA79CCC6BFAC3BE9247 + 9: 8BCF6980AEED36AF38B68A50DD454AF0 +10: 4B0E31AE48E903DFF52939800BB16DC0 +11: 19766AA929B40840715D53D9170C986F +12: F9CAEB36F03CE7B3BB363AC7EB3ACF99 +13: C8E34A6BDEDA4DB836DF3D863D02A6EB +14: 370547CEA441FDCBAFD281A8653BE2D4 +15: 77E0F33343158A8C3AC3C6D14FD69431 +16: 7A985B1368F842C644538C654D081FD3 +17: 60E0C8933F43D40003030196E8E881AC +18: 3473474B58AE6BC7582ADD7AE24711B7 +19: 75936C8D46F6D5AF5C7EE0E8DCEB5AB2 +20: 4A04F619FB0E05F7B07C43F4B9F2E134 +21: FD53A5A7F4F0B9D933E38D9F07AC88CD +22: F62EE43B20F582AC77879AD7E66FCCAC +23: 4436AD771624896683D7D29E8879F89F +24: F88F3C0EF2B9FD0CA997BEF17787DA2F +25: FF5576F42CE9A0665A1D6A2420A691D0 +26: C077D6AEBA65B61CD1A9AAE17FCFC04D +27: 84D0D7C52D6DB3979BC3F6F34456CB91 +28: F163121D9EB7569CA7DE3B7619E0BE51 +29: 727D23FB43215467B57DC67A8890CF26 +30: 60BA577F3C6627267D7B33E693FB7BCB +31: 82C66B23586CCEA2AE1480B469B3F3C3 +32: A65092726D6CF2F77CE00648E2D117B0 +33: EC30662CBA891A3380B846DA6C64024E +34: CE1B253FBCE36B217ED1EFBAAAD2E783 +35: 9D963CD5E65A9ECD2DAEE93B6C6C1178 +36: 1B8E3D07E7BD4BB4248B6A7DF8935980 +37: DBC3FD5888B80C4CEFC6C5E170E271CE +38: 307CA8CDDFE5DA152B66E10346BB2E1C +39: 8858250F933650D978B403A4504EA581 +40: F06005FA6E56E0C0D96988A3FAD359FC +41: 816CBE37FDE3719804DBFD093E3FD87D +42: 4878C07B127D696214393DDC66F5EB36 +43: EFBA6045243050C0D8D82046B17008E8 +44: 3D30C3E5892D32BA3C685DC5B186E959 +45: D4A4C41F0E6687E4021FB90D7A8A9F81 +46: FE1057B2013308C4CE839B4186F43B4C +47: D7333AC65F66ED6D4BB8D069E265020F +48: 33C262F58BF0D91DF2047E799BAA5F37 +49: B960A18764D7A6E17FA1F88487EFF192 + + +Cipher: safer+ +Key Size: 16 bytes + 0: 7D42607880B424C27E5A73A34FECE686 + 1: 1A99D469F1946EA46523083FBAA79CBB + 2: 831385E400FD681C8A30AAD9477F1ABB + 3: 5C1BB8F259CDEC2C1BE0B803C7D9447F + 4: C57C1CBB18D87FCF72A87B247392752D + 5: 1625183B0C595A33FE0E8AE0DCE40ADE + 6: 4AF3A9D6733DC4FFF3422AA5BE5ADC94 + 7: 853133894C87A23318DFAD2B247FBFF3 + 8: 8C7F68E01A8413D19B9A479246E54722 + 9: 8620898ECD3BF91A47CC54E6D9987FA7 +10: 33F12ABB7CC6A9041543A2073AEDFFA7 +11: A096E46F2834F79C096D0B655EDC9A63 +12: 3DD0D7824A87C9F5D8D25F5AF57E70B7 +13: 6B7C99E5CD29AC1C5A8D66AB460E5AD5 +14: 95A9F6009AB4DD2AC7E8E45F36D91E9C +15: 60CCEFC6630329C341782B17365995A2 +16: 0276C96A7B1191BC16C8A9C98468DB05 +17: 1F352CB77C21139C058837B8194E3E64 +18: 2DB8E340F58844705F217551782F6B4D +19: 34E99832E0722C5AE8F0CA1A50E9E7E2 +20: 7E1538DC10C1F56C3723A87BFD127743 +21: 36B9714A8ACDC8B8A17E85E2803A8C88 +22: 11848329B0DB9DC7768C07D95F0CF662 +23: 93ECEDEB4C6369AC56AF1F49345720A6 +24: A3ED7F9D17067C2650728E266B623124 +25: F33574590B435D1DDBBA925F0D0EA8AD +26: 87E542DBD40DCBD80C4AB52555C264C1 +27: 6D806991AB8E3604C8267AC1EBEC2E21 +28: 4B7333F87EBB46BB2A8ECD392C85A12B +29: 4FF49ACA62898F558AC065B66CAD0234 +30: 62DE7B2133B09544EDD0DF66DC4F5E2A +31: 82195B39FF7B8A85D7F0EE52D19E510F +32: 24FA56176A4F0B37F851CBAB176C9702 +33: 85FA9230D9B93CDCC0752FC738211703 +34: D441132032BDAC6715F4453CBC2434D8 +35: 438AB9BEA8A900368D84EF870EAF7E84 +36: 433BE5BFE1529BFA7C5688CFE3BD4DE5 +37: 2A79FB6F37AA08533445B8BEA5098EA2 +38: B9C986EE45D204B6A1CA152944912C9F +39: 8289C9F78760D02AA71873FD97E2ECB8 +40: 48B0D1244523165055BE9A5E95CF852E +41: 471E211E5E784C2AF476DB3CB555CF35 +42: F290CBEB1F1009D250F7B12E044B80C3 +43: 1B9796D80C3976FE3071B1C01154D42E +44: A80E21A1A1007B69E8BCAE728BBE6A92 +45: 652058EF0FAF8549424F998669660931 +46: 89418FB4740E9801F6DFFEDC593FA32E +47: 907561A69CFA117F167A52B88777D89C +48: EA2EB4B1EE739320F99894B476A8A51E +49: E627E64AAB6E2FF6B99643A7FBB84BFC + +Key Size: 24 bytes + 0: E8975F94A8B1392FBA78CBDDCC8E8F08 + 1: 708CEFB68A0281AEA424B3D4698D2F2B + 2: 21A0DE56545BC950FCE4DF209C96CE6F + 3: F2CA4103B703264D46CBC09E13D5B8EE + 4: 2892101077FEE427C434CCFBBAB598B5 + 5: C2F191CC5C681CBFC098B264C479B2AD + 6: 308C3B794C8A7971BBA96FE4C727F48E + 7: 8A4F9D4463B5DC4DD461ED0763CDAEA2 + 8: B7E1BBBE455AEDF18329A6EECD6E222C + 9: C80DAAE7FBDF56DE05A897FBDBB53DEC +10: 6A3D38758BF0390156F22F83C20F0262 +11: CA493DF771E37A93822D6117ED14B60C +12: 623012748826A08F3C59B71FF3D66327 +13: A283BCB126B9795D306B129035BCC2DC +14: 3790A6704BB0F119139A0264F7E8B2C8 +15: 9B369BBC095428EBD712517B2C4D06F0 +16: 0F488018162193ADB11E4C39CFDEE0DC +17: 8AFB7C6FD7D6DD64C2C77DA3A0D91EE2 +18: B8BEFA241BA339BF6F059464C533F9F0 +19: E76141C8CD54200FAB2F8C2B76AF5FEE +20: 80B4FE57851C0240D81E78DA8200F195 +21: 8BF1C690EF5FCE7ADC74E31C24F83F5E +22: D30C4F78703BDE91750E0E49FA0E8982 +23: 86C5D1E0B88EF0AF9B899850510000EB +24: FDE727442BCC0305A7B06E6EE179D836 +25: 0B4A719342F9226FA680796887A98FA5 +26: 980D4BE9AF3E3CF9D4558478D1DD03AB +27: 03ECD11992D3D5864B8D1987966BA544 +28: 8DBC2931D7D17657BF38E3931F486850 +29: 76AE069E39FA7308BBF507ABE35BC1E8 +30: 9541B59CE18EA255CDC06DFD3FFCD1C1 +31: 5A382748AE3641ABF6D9CA24A35B2002 +32: 9B7A49DCC2CFC5A6078AB41E6F62B4CD +33: 91B2EAC878E5628DBCC7C876B91B73D1 +34: 31125CFFC41A0D3528FB16BAE761C47A +35: 916D2A769DA002ADCA8C87F8241BB50D +36: 681C3F601EE5D82F9B040932F2FB4AEF +37: 6B6F32E5EAC2F424074C33F7C988D5FE +38: D15A5FDC2A4956DE61BA6E1C98867242 +39: 0747BCFE1B979E947EED5225FAFCA44F +40: 133B43C85CCBC360DF8649BBBD2EB45B +41: 052D943062A6D475D30100EA412C30EE +42: BD6401C591D585F4A82CDCF678679D5B +43: F95D1A5E338F56760C425D972D67B57B +44: 9B1569308608CA00BB1E2BC9E20289A7 +45: B6454C52C64F64D69F1D36D2D224A222 +46: 529B5B013AE3F37E38BE340D1D200A64 +47: 1B65904F177212AC8E9ED4D8DB287810 +48: CD5CAC56236E0B9A25A5D306F12D8C4B +49: 01DF7E1D0F5F7A5DAA0B379388425126 + +Key Size: 32 bytes + 0: 7FBC212996ECE9CA2C4D5BD88FA0B3D9 + 1: EA3D788C25CF3BE7F4101EDECF23455B + 2: BD0B98481366AE0869ABA11DB18D1E95 + 3: 53393E2B757C90489EB6B47F67837337 + 4: E1D350640CCA6C13648C3B57BE00B950 + 5: 951E1EF99E6DE72744A9D8D9EBFBA94E + 6: 433E4D4E64B41818097BD5E2EBA01D8E + 7: 8FCBD07E303B381B2935FB82CA0CBF13 + 8: CF46569005BD968B9310149E892B4D69 + 9: F1B672657C2657AD53BFFE2BA5DDE1D2 +10: 0035337210703240F9CF2F5A9184FDB7 +11: 773951841F77DCF8A6730109DEDF3E9A +12: E47DC0FB381DB86EBD208A0D649E7B03 +13: 0D9E34ADB257146EAB95AF14636301D2 +14: AB5D5C106E52AC7662C26F9F27F2CD55 +15: 6938F205DC23C3500B7723281E9F626F +16: 3CABD52558D7F418CAF6B41CEC334DAD +17: D2192F1E5AFC3B989C42C396B3764862 +18: 59D32E3A41141C6CAA2A8F44FD587D94 +19: 483CFECF65D71CB2994E1C12A1A7F907 +20: 8F086AD81B1FD5B13195EDB4DAB7DC73 +21: EFEB1328CE7AE6A63E7D8B3ECA9E12B9 +22: 362AAE308B3BBA588DBCFBB7197E693C +23: B817A136EB30CD127B5015A85A7B6E95 +24: 03796E7F244CC916BE02AF61E5FEC42F +25: 5854F2889CFF44B0688718C23B0A822D +26: 0F772AC6E37364AA7B844AEACB33F4A2 +27: B3E95F5195BA646DAF333AA89130451F +28: 911A32AF7CC44309B37D75E158A4AB18 +29: 232CFE228EB72A949616B307C2BEED15 +30: 7C8989F135B8DE6FD26C7792B8354F35 +31: E79231779BFB9F792BD179C0625280A8 +32: 015F6CCAE8A1275A2E836A207D8254EA +33: 4EB94709245CE1FBF7C6D9587FA92D40 +34: 63D82005320F974EFDC4C021FB73ABB5 +35: 0F15B2E8E389C2D59289D7DA41ABD07D +36: CEE7FBBF766540D4E39903D0494DB797 +37: FB564C18A15D53108C1954FCD3518FC1 +38: A67C5F4A4A95AF2BD8E4FC1182B2EEBB +39: 0D354E664C35B9364E4EE9DB8DE0CA76 +40: 3295826D52F3B980B50EFF3E9317F1CB +41: BC65592A9C0BADD84F363A175EE6BC54 +42: 58DE762ADA621FE2A7A6A83F68E93213 +43: AD774FC8402F7DDBB881B703EC836057 +44: F1C95AD5E004AF35AE315AE88A2577FA +45: 968775A2C3485875B024B008D96182EC +46: 623E736238B5800ACD9B67D76C84D236 +47: 1C5E9F65D43343D743E50C80D0E0F648 +48: A62E4A197E15CF90C2569DC38D9FC915 +49: 165B139BE483A71381B9A8E93D9473DA + + +Cipher: twofish +Key Size: 16 bytes + 0: 9FB63337151BE9C71306D159EA7AFAA4 + 1: 8CC5A931DEC29B4C7D85595D24FF8405 + 2: E867FC0E144FDEA24FEA88D22D8776EA + 3: B450A2969C67D93E1AE3A4093BA4C48F + 4: 7AEA41F9956149F336612E868E42B3C4 + 5: F201FBB730E6E58CF9E5AD1DC4844C4C + 6: 13D8869E66412C6C288B5D7F37F2D94A + 7: CD57DDDDB782C0A04C40E47D920799DC + 8: 65371C8ABC919EC09004A7D63D9302BF + 9: CC31DFD3B7DCCC86866CC79D45A89C3F +10: 541D548D311714EF8661BFA721568D16 +11: 269F3AA2D2D10DBD3DD3992BFEE23C05 +12: F86DA5D73AFBA94A9D592D02B5855D25 +13: EAD8D785B50E036437E39F3B27DB4657 +14: 2AD0A13C493B9F3EDD259E11A495B205 +15: C05F9D72AA384F05B28A3519AF218CA9 +16: D442072F588D38AC8B9D447762E9FCF3 +17: FDD3BFB91EFD127196FF9F19ADADBF28 +18: F56717661B424E41D7DE1CD13E21DF89 +19: 0F6C952D9BE6CA49B5147EFD44455A92 +20: 6C214935726364F2766BE7B4C2B64362 +21: 5D5316D7E057FF481CCC10C7452D1A17 +22: 56C78DBD802CC9B040446A3EFF3F12AC +23: A38CEADA8448DBE29C2D11DF2A487715 +24: CB2F786AB8063350F3FAE11EC8C65A5B +25: F5B7298B6F558E2C4FCC11744AD22653 +26: 01BF89C1B48C5F6918FC6BDC10B12A21 +27: A031F25AAFF294EE79220BC76E73E52E +28: 42C94B50E12499DA35F14BB6BB6E684D +29: FD68B6840DC9A271CDE2032EF0200295 +30: A9863C1B04B3FE3945D29966F67B87E2 +31: 6226D4CEEC1E8AEC1B7B3E13D80A83FF +32: 6100A71B1E3ABBBA48A9ED280DD1617E +33: 5CE93A26D4EFF0CC7DFA2DD43A511871 +34: 282D165BFBA0F7F229161BE533BFC4D9 +35: E6AC479970891392972B2845C949A068 +36: 4E4A887368F8443BE51FA7CD16CF0B87 +37: 121AFC81AA2750572B35D100BDC34DB5 +38: 7C41FA7E0A18A87E44BE488F331B35E0 +39: C8847D295E1F505C04E2F5CE2CBF5E00 +40: 4686EE8628BC1BBB92CE825F04B1D5E8 +41: 397DFACD19C283B3FC27D3FCBE952254 +42: 815B6C69608B5A379E3C9E67FB1BA15A +43: A73E72B912EB3AA4929E9EAF73A448BB +44: 5BC4E2C88512BCD55408CC5AEAD15A91 +45: EF20B2BF297456DED1F4AB7BE0747902 +46: 3D876135E19BB56B98050450C6B0FD06 +47: D68100E1BAD07B438786337C0957471D +48: CE85A91938049B5E21C983F7C45ECA3E +49: 9FACEFFB9D08BB65DDC34E3C575B8442 + +Key Size: 24 bytes + 0: 95ACCC625366547617F8BE4373D10CD7 + 1: 99AEB25CCE73B3796C351A19791ACD52 + 2: 56B9D6689830275C1A3E4266B3D56D53 + 3: 2F5F822E11F087BCB8A0F428414855A0 + 4: 65400F729990FE175AAA894BCFBB1A59 + 5: 947BA33D20194BBB0D4904023FB32FFB + 6: 116B0C6744D215AE98DEB1F9FF1D36C0 + 7: BA6964C101FA044ED06877E46D540850 + 8: A36B18526FA0004CF557C99A3AC1423A + 9: 573099674B8AFC2DD6424A2E4C581B89 +10: F46169CFE9496A2696A93EEB7EC561FB +11: 2C64BC052898F3F3A2B78F2591F2BF1E +12: E8A0D40B08585459199DD6ECC108A490 +13: 47927989BE5EB55B9A0F294C04FF035F +14: 54A3024E3AD86005A2C44E4B8BDBBEFB +15: D0AD51D1DADFAD7ED0EBCC756DBCDCC9 +16: 5DE698B7014C34AA6F0099CBB5937A20 +17: 9BA30F49470C6DB9632C5EDE34F8EE73 +18: 0BDF558A2AE9298288E60616442D3408 +19: 25F6DD23BA4E090E1CFFA6EE3487AFA7 +20: DAC5FB99E299D2672F79F0C38E177D83 +21: 58CB113430895C9890D96EA60E3DDC23 +22: 48A0771F0049B776A44AE8877B57EFFB +23: 2F12B26A4BF7065076417530CDEE14CC +24: AA6ADCB0176D5324C4C1FFD640D502EE +25: 384B52A66F4C7A70ED36091BC3FEA09C +26: 2AFE7ACF071C6B0FD69930A09D6DD5E5 +27: 9A2DB9A5E7712A5BFB095D2C09453CA3 +28: 716C0EF522A13EA05A48F16BAD3FD10A +29: 44AB46F3CCFD02BDD2C77A332293A4D9 +30: CE6AB27A0F60F410B1B3CACD9AB923A8 +31: 69EAFAFC171C55D1D90ED1C6E1F3A48F +32: 5EEEB0B7833121AD7D27BCFAF2D4F8ED +33: 47133445A4EBCC60E27B29FCC160FA75 +34: 9F1BFEB9715A20D5FA7BA3BFF1A27BBC +35: 516D4615F07756B4DBE7D37EBBF4684E +36: B88744E53073BDA0F1B115E3DB224E83 +37: 1B77C3D067BBE00420450BA5CD9A83CA +38: 94B87AC96F8CBFF36B01A68E0651E591 +39: 52ACE87A1A8E46655935536FB3701290 +40: B406BB632D5B7985400EC78D621C8801 +41: 20F9ABCBF97A9917EC6C5DE3CB2C925B +42: 539A8AF920833F9E81A20A6D10543176 +43: B79AFB8BB39B0351094F37C6EC93F8A9 +44: 5830BD21289FED3F95C3E3740AC6C5BF +45: 86C4AF5839ECB9860B175642ADA32895 +46: A6427E5E08CEA2A50B8426B063AEE189 +47: 2E872129B5BC5F535BCE2B81F013A103 +48: 2203EB9B2BF51FC2025549D0BF1924A7 +49: 6A5E383A4FC78F6E03B9B276F81195BE + +Key Size: 32 bytes + 0: 8EF0272C42DB838BCF7B07AF0EC30F38 + 1: 9F8801E94E41A7DC875665663BFA7912 + 2: EBE2CA6B45A0BEE83B54402E1A843A3B + 3: F6C5A1187AEF4B5A88E97E866CD757A1 + 4: B3E62CD473E53812EDF9ECE875F39F5B + 5: D8C38B1EC23264BB7C42B5589C1300B2 + 6: BE315EB75B944EC9E51F5EAE65F70BD2 + 7: D4275409941A44993037364886B60598 + 8: FC34F1D4E9C4A634C1349F6D4E9AB94E + 9: BE712387C59A40A8A35F854333A0302E +10: 1F1FE164834BABC71DBFDFCCA7D2B4B6 +11: BB2413CCB5347B5157651819E698D988 +12: 6EB5523A968ECE965D9AA4B975D7C2EF +13: B5DD49AB7E269F9D8516FB57EB47D57D +14: 74F5D81856F192D49A70B3743945BFC0 +15: 95437BB00D57CD88BD52DE0A66D934C6 +16: AE4804A975D67C6B6F99176F407AAA3C +17: 5E5B2FB9B2A028A5467B56F8BDBA6980 +18: 8C617FF1F9C50A36BE2EC19A629BA96B +19: E3401F7CBE177A1D224117894E7EA08A +20: F8451D9DD31A08BE828FA9AF39708921 +21: 5BE66DD577826804817B85A07BCEDE28 +22: E426227780943AA1A830B7E7D7F7CA0A +23: B39C7277C3A5CA21897563DBD8DD6D94 +24: FA9992385396F959841D1E0E68CCE00D +25: E1DE89B1DD5CC31685558A51CC731E6C +26: 64618455C46C6FF117F19FF300B3B557 +27: 882758C02B3C11D406A21012977D4BF8 +28: F948B62F8038D3A3AFB73041B2F263AE +29: AE3BF626020D2877052B90B31E70B8A4 +30: F1C6DBBC166985C9EC2E1A3A61BD8E75 +31: 82C343FA36B6D4E9E7AF6D0B7741FB09 +32: 0BFB756EC55AC63BEA71E4A8187C2B10 +33: F1941AD10BE60DAD3FBA33CB899B63A3 +34: 18236A39CD34743DE7B60B2575A9B204 +35: AA37FBC2525F74710D7561D316E8D90B +36: 413E0F72C2B349FE2691554F77162B5C +37: 5B9E6F98B2CA0F637E463BE4A6EFD39E +38: 1B4A4CA36DC60D51BA981392D6070379 +39: B1E26163A90F339E33F86D252EFBAB99 +40: BB98F9F844FA81B25ECC89A8482404BE +41: CE142F512A42A28F4788847B971AA7E9 +42: C5CE782936F3D28C69C2BD45FD7BC117 +43: 9B6E142582E0A309EDB550DED51238B0 +44: 0D9D80C01612977FF3A2C7A982D0894A +45: A7630C752B1F787B07C382693334C6AF +46: 9F24990F270D575881C746481A59C245 +47: C38B5E11479C200B5ACE1D6522FC6B1F +48: 99118D8114D24B6559CC5D9456F1BEDB +49: F8B974A4BC134F39BE9B27BD8B2F1129 + + +Cipher: rc2 +Key Size: 8 bytes + 0: 83B189DE87161805 + 1: 7DCB9C9E50D15508 + 2: C724D535853CDE79 + 3: 113AFD4BA7D3D7E3 + 4: CFA06CFB93C2280C + 5: B3F291C1AAD9CB07 + 6: 606F74D9AAD4FA71 + 7: 1CC3F7AD551C5F89 + 8: 43F8772BA6C6B60D + 9: 2F933E12F57689DD +10: 2BC1AF0D5571D17E +11: 4123AAFABDB254E5 +12: 413E0AD5C709DCE0 +13: 6B3CF01A7542BD2F +14: 1E5E2CA0CD605999 +15: D0F7C9DC472A0709 +16: 00482798857A2BB9 +17: EED583440CFA8B48 +18: DFB377FE1EE5E055 +19: 30511C4C565E8F75 +20: F74A72482B43B99E +21: 1EE4EA7849B0B070 +22: DB7A4ACF022706FD +23: 2D7EBABC8C8E4DD4 +24: 6F0369BF66A8B637 +25: 59E5D13B247EE0F6 +26: C7BAB430AA89A5FE +27: AE0F03746D38138B +28: 942DF0B523D02482 +29: 929CE0963CFA46B1 +30: F8C68A91DC53B7CC +31: 5735395C63E15094 +32: 7821605C18D83D42 +33: DEC892FD743BA6DC +34: 77AC80C1177963D3 +35: 3E223EB4EA297456 +36: AF63B231D671D9DC +37: 665CA287AF32E92C +38: E451EAB337DC1EB6 +39: 95B179EC950992CA +40: B8937115492802AE +41: 355A6E5EDF40A939 +42: 353E77D4A5A28D79 +43: C958FA5903F921B8 +44: C334E296BCB24ABE +45: 4F37F7F652FE31ED +46: 77304A655B03ED67 +47: 3548A4209ACB6EE2 +48: 696E712B1911B695 +49: E4B63641D22A3DDD + +Key Size: 68 bytes + 0: 7ED68E8B30A7D5DA + 1: 867E18AE64B783EE + 2: 032E554D6AAD7055 + 3: 26BD785D0DDAD48B + 4: FFBD4009ABF53D03 + 5: A71006E1E30C3855 + 6: 92638EE741BE65B5 + 7: FC8C5F28CB38C83D + 8: F03F145CBCC4CF80 + 9: A28A7C63F67DDE7B +10: 3089486A2247B72A +11: CDD6E6BA5ED53A8D +12: B75A2DE8CB96A267 +13: F74D72A2CD68CEF5 +14: 3865AC8D170EEDBA +15: B1B520CE5FC2BA39 +16: 658DACFDD701B4EA +17: 6B5C1DA9484FCEDF +18: E3CDFB5755BDFFC1 +19: 56DAFF7E9A908880 +20: B6F8B970F68BC2BD +21: 7A00DEE6977A91F2 +22: 6C0CE4FD2D02B36C +23: 8EDA10D868504648 +24: 76FB106689E66EA7 +25: 67F45BB28A20E110 +26: 5F3207099AF93B07 +27: F5E382F7266AB342 +28: 0E31AC2E4CEFFBDC +29: 8DBA1B2FC6980FF0 +30: 311368E62EC2A9E2 +31: 50DD1F7A319727EB +32: F0DE146C9ECF5662 +33: 81CE0842CE223F15 +34: 4C442535A8BC9AD2 +35: 06EE8869DB91EBDA +36: 4078E7CAC29DCEE7 +37: 115D619FB705F289 +38: 3D3F8A380DCB8FB1 +39: 9044E5AB8049D21A +40: 66327F00B07CFC76 +41: 811AB23A4AD3F132 +42: D4A507E96BB39BC2 +43: 51C9E4C9318F87D9 +44: D2255C13DBD09E88 +45: ECB76BCB961F812D +46: 83D7E39727BBBEC5 +47: 415540F0AE34DD65 +48: 232D20F9E188E2C7 +49: EE37261ABA270B22 + +Key Size: 128 bytes + 0: 8A8F8E5C5A04C73B + 1: B197CF922883CE71 + 2: 8AF3F896460CC597 + 3: 755F313AEB18D3B8 + 4: F1DB52688BB879A8 + 5: 29D68EA6456B1CF9 + 6: BE7C444267A7925D + 7: 46A7BF7DED575933 + 8: E2C7AD7C902E5E15 + 9: 90A38AE1DD69C2EA +10: AA95FA050CD3388C +11: 23822B6AD5B83018 +12: 8FD42F0DBFF3FEE1 +13: 645098BC94FDE21B +14: 7E43D43EAC50E992 +15: 2F540FC66A9E0F43 +16: 453E52EA7B2D1F92 +17: F6F731E8C5A32C54 +18: B1E89646504E4D7C +19: AB8168452A7984E1 +20: 044BB0758DB5435B +21: E9BAE7C99A152BFF +22: B758F70708B6597E +23: 23A1EFD0AA925D7E +24: CA60DD174CBA23DC +25: 5E916F2DF7B6B3CF +26: F2723A9BFD82BB62 +27: 2BC381F6C048687E +28: 573BFD71896A4133 +29: 03DF7250C3D69801 +30: 8639060454669BCB +31: E31945F0A87221AB +32: AA39447BBF0A77EA +33: 174F1B65BF6A34A3 +34: 2712F966022A9589 +35: B6358876D6D56D16 +36: 2A92C131E68B77BE +37: 040C6935F4CFC43B +38: F23503C74121C660 +39: EDD120883F1F813D +40: AFC6500D34BD9D33 +41: 963117444417BDD3 +42: 2FC3A58861B4A58E +43: CFDB70ED8BCD1173 +44: 91B75760CF38B8D5 +45: 93A59048B78B3415 +46: 7E60C5E75225D45F +47: D4212C6422878FFA +48: DDD1B241E0E0EF6E +49: 20337DB931078078 + + +Cipher: des +Key Size: 8 bytes + 0: E1B246E5A7C74CBC + 1: 9262AFD8AD571E2E + 2: 36D2067D960EB870 + 3: 319834DC66705192 + 4: B4508A7C5F012C93 + 5: CAD1DECDDEE81342 + 6: AE9E1CBB71C719E6 + 7: D7FBB1CDAFD5B2C1 + 8: BE1A70564E3BFB5A + 9: 96D9EC1407A1BD34 +10: 05E4B9AF3A4DABB3 +11: 0DC77419E1F12C02 +12: F73E62369190A5E3 +13: 830C1CA7820ABA2D +14: D2574B6AEED0A4F4 +15: BC08782E293546A1 +16: A35DCC9AAD1EBFB3 +17: 79B2224667B33706 +18: F9462FFD2808233A +19: D6421CD0D9697DC5 +20: 57CB2173D67E7001 +21: DBE2DB0BDC07644F +22: 014E72E7E99C969F +23: 37901B1963D0B29B +24: 8E12C23929125686 +25: 73AA9E2A60C327A1 +26: 54A19D07D941EAC2 +27: ADB8CBBAEE1848D6 +28: 3997E866119856B5 +29: 4D647526FE7E1E27 +30: D574FE7342104F93 +31: B84383E34A790E11 +32: 322214BE9B93BB6F +33: D4C8E0B7AA139D68 +34: 2B9747CD280E48C8 +35: F92EB2E3711FEE2C +36: 5CEE84E124B7882B +37: 82427488597FF618 +38: B1E8B313D2DC76CF +39: 03E237CD40D7F214 +40: 8C8DC1299293E15D +41: D6C7463FE86D4EF8 +42: CF1550CACE647779 +43: B998B3D32B69F00B +44: 1B94C342C3D91107 +45: ABD4551B27F58BE8 +46: 2B24D978D1BFB3DA +47: 85361D36950635CB +48: 448009F38F1DBB4A +49: 6B901B2B79B6950C + + +Cipher: 3des +Key Size: 24 bytes + 0: 58ED248F77F6B19E + 1: DA5C39983FD34F30 + 2: 0BD322177B935920 + 3: 9D093F3174EDBAE3 + 4: 756B1F2CDF02B791 + 5: 57C31C2A913C1126 + 6: CF936257517C53FA + 7: 5F06305849E5E158 + 8: 9A85DFD788C59D19 + 9: 6392279BBE29DC1F +10: 76B0AF835D79C4E8 +11: 7073F36DB1E31464 +12: 276258605F2CAB3B +13: 3B69E97811FDA996 +14: 3E6E491D2862A1F3 +15: F8F3F68BDB006520 +16: FD376E66D401A097 +17: CA2FE47825804996 +18: 6F5C256F84FD14AF +19: D7B07F5C40FF0CDE +20: 73F2E074F1324496 +21: 0B2A35016F24BD21 +22: B040D2E3B311C193 +23: 3938DEA347112E2E +24: 9D7C1703CEC0BFAA +25: A07949F76BDFAF68 +26: 43087EEF52564C4C +27: 11132B599734AF0E +28: 62A04C819FDD9A8C +29: B74F0E5649D33690 +30: 8E77E5009B0AA322 +31: 5174134B9A1889B9 +32: 053E33441D11AE63 +33: 01EF381013F86E4C +34: BCA358DEF35DFD60 +35: 5908A88513E2E5A0 +36: A3214C8367E04B05 +37: B2CBBE851A54BE9C +38: B271817F63B3B76A +39: 08AFBF82ABB97D8A +40: 2CE02ED014186B86 +41: 63F3011C97F6E990 +42: C392351F432738D9 +43: 0534DDA50E685725 +44: 1509456871F5CC20 +45: 2383029935901342 +46: 8714F1A53CCB213A +47: 2491B2FD3CE6A7CB +48: 4BB02399D85BB66E +49: B8AC2CDFF7AC22C1 + + +Cipher: cast5 +Key Size: 5 bytes + 0: 9B32EF7653DAB4E6 + 1: 48AEB06B1BDB2397 + 2: B530927183622D58 + 3: 0ECC8F24BA742216 + 4: F6352F9B6461D82C + 5: AF6315AE98E12A71 + 6: C364D4B506EF28B9 + 7: 817061BEDF5E0A5D + 8: C19DE7B1F2066C04 + 9: A6E1345E3AA1B79D +10: 06B036B04785428F +11: 244DAB3F7223F567 +12: B9CF3791F6C79F4A +13: 86C5A02AF0517C5E +14: A16E3198F1317E04 +15: CF72A44C01E36DDD +16: 199C72ECD5E632ED +17: 0BC66BF05EB7887A +18: AE1F696F3D6B7952 +19: 685C92084F600885 +20: DBC1353A95AD2097 +21: F481E98CB36CAB3B +22: 8F1C06A482C70BB6 +23: EA087739954A9CE5 +24: 6D0AD727D8E4EF9D +25: 61CA0F7965FEE246 +26: 0D664CA16BA785DA +27: 2359D363755605B9 +28: 6B6E3A216ABFB55A +29: 6FBCCF7B0342D3C9 +30: 3431F4572E2CBE57 +31: 36D84FCE6D5D8FE4 +32: C234F6AD41E34E76 +33: 522F12E8D0617263 +34: AD8199B6E94D4E74 +35: 56DEC7C21C83B2AD +36: 22CDBFBC5B476E69 +37: 70BAD497381F378D +38: 4584F15DBC0EB7F3 +39: DE0603CEE19BCFCD +40: EA8D582C1CE62FC9 +41: 4299C28A912CE568 +42: 7208AB000E3FA9D4 +43: 7AAE6CB398D01665 +44: 33A6AA42B6D7949C +45: 2AEC5640AD535D69 +46: 74D37D9DD7B67248 +47: A5300FFF5CF85833 +48: 834F83398D591C38 +49: 85C787A8B7E519DB + +Key Size: 10 bytes + 0: 95827CB504BD43C7 + 1: 8FBF4EBCB8413ABF + 2: 5CFF411BECED9971 + 3: CEE2AEB4415E0A5D + 4: BB3A8DF7C54FA88F + 5: D508B933EF335111 + 6: 993745722EF0D8D3 + 7: 04EFB233AA88E796 + 8: 478A7DCEAF243F90 + 9: 269CC3D138ED48E7 +10: 88EBD14D2F999C89 +11: B7441626D4487A20 +12: 46A6E2CE6C66058E +13: 60687D2D5381757F +14: 885D05ABBF187B89 +15: 5032A7ECD3D51521 +16: 50BAF36BC5C14A8B +17: 8E805499569FBB0E +18: F8359B18AF3E69C5 +19: F24E415CB4D2AA95 +20: 361805D4E45B56B4 +21: 3172336F01E3530C +22: 333A551E0A03C4A3 +23: E2B991995A2D2962 +24: 067CEEDD8F213B67 +25: FEC3F306851F8616 +26: 4B80DAE6AB11894F +27: 250C26E21A8273A2 +28: 313F2A505915C909 +29: 42E0DC3D4816B38D +30: 9FAEEF0510DEE721 +31: 3BB5F5EF74B4CD7E +32: 0FBC9007F462BEAC +33: B9D1467B0D7A1043 +34: D9B991C9348DF321 +35: 061D577806C50742 +36: 48AEA67AAAB6FA23 +37: 22F7910383BDA87C +38: 9987087EDBA56FD8 +39: 2FCC8341B69BAA14 +40: 29DEDB6C2A433F50 +41: E067D2746B99A9CB +42: A5C9CB975A856D57 +43: AAFEFD3A82D6185B +44: BBE8952CC93CCCC8 +45: FC08CE0934EF2E25 +46: E44E642DBA7CF3F0 +47: CC26F0E8E85AB372 +48: D95D63B8389082E0 +49: BCA941C921B91E16 + +Key Size: 16 bytes + 0: 20B42D77A79EBAE5 + 1: 96CF6C91E5183CA2 + 2: BD87E77A38DDB4E2 + 3: E7454CA30B69DE2D + 4: 888F278D219384EE + 5: 972CB887CDE920F8 + 6: 49BEC1E7913F3CAE + 7: 96A81B37FEF63CA5 + 8: 408DD23A6DA940FC + 9: DA86E92BB735755F +10: 2032F2D972F228BD +11: 8F9EF7DEEF74EFEA +12: 547C92025DCAF9F4 +13: 80CD440DFF2EA62A +14: 7D6141D102E1B941 +15: 307596ABF5C9A6B2 +16: 82E3F1B17EBD52FE +17: 5917DDD11EDB55A3 +18: 2909F77166F24F9F +19: 88BDE9D686328942 +20: 8F987B737F6A011A +21: A74B3D1D6433B9F4 +22: DA8F95DE949482EC +23: 953BA9B26B9AC476 +24: 76A52FE193CBFAF9 +25: 4BB7D2597A78F2D8 +26: 5C8BE951251F4B1D +27: 6E8AB32A4A279D84 +28: BB94BC9937B42848 +29: FF0EE686F97BF8DB +30: 4146656AB1477E13 +31: 1BFCA7053E6DB8AC +32: 4B9A6A349BFA926E +33: 3B5F6FDD127B0A87 +34: 53C996E956598599 +35: 62C142E63C28B5EE +36: BBB71D6548F32693 +37: 107576AA26352455 +38: DE32E31FFE02B6F9 +39: 4C5DB81D1715FF5C +40: 8E5C706206F493A6 +41: 4BBC51E184A67C92 +42: AAE216B413DE2A06 +43: 77AE26F467233B06 +44: E8680D0E71F6AAD6 +45: 7061DCED4BC94F78 +46: 06772D63818C7E86 +47: EE5B9CFC06CBD639 +48: 5784B3EFCDC28DD4 +49: 4F962107A2EF843C + + +Cipher: noekeon +Key Size: 16 bytes + 0: 18A6ECE528AA797328B2C091A02F54C5 + 1: 2A570E89CD8B7EEEE2C0249C8B68682E + 2: 828F4F6E3F3CB82EEEF26F37B26AEA78 + 3: A3CA71833499F244BF26F487620266A4 + 4: 333ACCE84B0A9DE91A22D1407F9DA83C + 5: 224285F3DB3D0D184D53F8FFDC8008D0 + 6: DE39E2973025FE9EC1ACDE8F06985F91 + 7: 2F00F45A01B1B0AA979E164DC5CCFE10 + 8: 43775F3CBEE629EF6A9BA77CA36171D9 + 9: 1E6A67ABF1B6ACF59FB484866AC15A86 +10: 70490989E2CD2145730921CCC37F0A17 +11: 67B0DD0EA903486B1CB56591FCF42678 +12: 774AAB71FF28E49A30E1E718D98114E8 +13: DF4797990E1C65C9F6735BD967164D45 +14: DE2779DF26FC1B99F576ED4CFBAE76CB +15: A13AD17440641B3460A01175E3274AB9 +16: 1166499165F2A1196CA2DB831F264E77 +17: 35D24A385416CF2A44AB97A4AEC45E14 +18: D3D0E0DC962B1AD1AED92F57129088B2 +19: 00EF3E246B32634ABAF8BEE31D5C592A +20: 79BBF3F807675B9F264BABC67DF4C2AB +21: F391F2D58F0998F24BC9E5FA75DB9E99 +22: 066EF13C2617E97E6015B86BA1E059B2 +23: 5B0E2D7AE1E2734B9D5734C87F7BE272 +24: CDF7020212B7CF21F4817829386A6F8E +25: 24873E1A0EF4908DF85114ED9BDB0168 +26: 99904360C843472F71AB86B26DC78A00 +27: BEE70B3735A67268578FF107C328940B +28: 97DBB283536BC8AE8DBF56F3474C7740 +29: 2F4C903975EF709E004D24DC132A8A51 +30: 3EF0859A281782F905198C607FBE5C43 +31: 2D9CD48BC6A99E86468CBDD2A55C7D5F +32: 5518D3ED18D5E5A62752CDF0846D0C77 +33: F751E9CAF107BAD8A1F1F9C374277A6A +34: C5BA4DE907C41221FBABC5EC43710D0C +35: 5CA48836330870365A10E7B676695C9D +36: 937A964E0EA4D246E97293375B167EFD +37: C0A876CB6957717541A90CCCB034BFB8 +38: A57C93A09F9160A28D3D4DEDC987746C +39: 1FFA1E0B5EE0F0A18425F62717254419 +40: 8411C87262AE482CFC43C3092BEAFD90 +41: 0B9BB379FB3587A9ACEEED4771D8DC20 +42: 3B32EDBF9557E1DFBCEEC269B51FA494 +43: D1104E2888679A9EF6A13AE00ED7E1FB +44: 0EC9849BAD58A279B42B5BA629B0045B +45: CF206E8D3399918E75DE4765DD743060 +46: 55CCEB28E27D4DC7CE2546454FFD2C33 +47: 6E2339281583420B76E1750D35296C12 +48: 7800EC3D8C344BE7F2D2812F5AFF3DA4 +49: B80F4B0BDAA54A04D5A26BCA185F4EA2 + + +Cipher: skipjack +Key Size: 10 bytes + 0: F62E83484FE30190 + 1: 03B4DFE5423A117B + 2: 8CE4DAA2307CF018 + 3: 77D8C958DAE4336D + 4: 00D367D5C1FC95D8 + 5: C1F1305A5B01A474 + 6: C3956225C846F695 + 7: 2A8977DC186749A3 + 8: 433AC6B56AE5C200 + 9: 10489A7E87F803CE +10: F176DF022D02D136 +11: 1395AE1C0C00AA1B +12: 0C1C3FF32E93F789 +13: 901EAAD562EE92DF +14: 59D55D9EE3EA0154 +15: D9135CE0BBF68AC7 +16: 90A8E4A8E76349A3 +17: C04ED52AA69D1ED0 +18: 19E842698B5008A4 +19: 26FCA0FA3AA7718D +20: 62635FD1A542C7C0 +21: 5A3695398C979E40 +22: 34998BB72108D89F +23: F889CF892998D689 +24: 2C6A4D61F468F19C +25: EC70D59FC906349B +26: B95F11FD098B34A6 +27: 32F86206BB4E525B +28: E6BE51063B60CB9A +29: 8964E47BAC22F995 +30: B1C297883819747B +31: F2AE1F39F55FB6C2 +32: E633EA2DE342767E +33: AF1F0ECBCA788A28 +34: 6A898F4407696B27 +35: CD9CB5374EA080BD +36: 15881B0200AE6A42 +37: 579D05E5F5DE7840 +38: 86F8C683D23EB976 +39: FDAC7DC6C8F7777D +40: 10D6F7641409F027 +41: FCDAA0872D1EC61A +42: 7A353991A81344DC +43: 43661187956D3F8D +44: 5190FDFB904A78F0 +45: EF651E67F65CCD57 +46: 5E539C61748BDE3D +47: E11E23BA8BEBA42E +48: BAEF0956173B32AD +49: 0AAB29DF65861F4C + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/eax_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,331 @@ +EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. + +EAX-aes (16 byte key) + 0: , 9AD07E7DBFF301F505DE596B9615DFFF + 1: 47, 57C4AC75A42D05260AFA093ACD4499ED + 2: C4E2, 26C5AB00325306772E6F6E4C8093F3D2 + 3: 16177B, 852260F91F27898D4FC176E311F6E1D1 + 4: F09F68BE, 700766CA231643B5D60C3B91B1B700C1 + 5: 8472705EDF, AC4C3359326EEA4CF71FC03E0E0292F2 + 6: 14C25EB5FD0D, 8DBD749CA79CCF11C1B370F8C975858C + 7: F6A37F60670A85, AFBD1D5921557187504ADE61014C9622 + 8: 1AACFEAE8FBAD833, 82F477325D6F76BB81940AE25F9801C2 + 9: 069414324EC293697C, B980E21C09CA129B69E9032D980A9DC5 + 10: D8174DE9A2FC92B7DA9C, 1E42CC58BA2C8BFD83806444EA29DB61 + 11: 2C087DEA30F8B7EE510990, 83DB400A080C4D43CAA6EC3F1085A923 + 12: F36B93C272A703D3422C6A11, 1370C3AF2F3392916364BBBCC2C62EC1 + 13: A0F33477BAE2E28E6747AA3193, B626DC719528CAC65DB0EF94E35422CE + 14: FCF5193506052E8BFA095C1A5205, F5BD02E0B3C91CC7D6FAAA8A9A76CE6A + 15: 3797D7F8599B8EEAB39C56241880DC, 0B70003E77146B903F06EF294FECD517 + 16: C4BAD0E0356FFD369110C048D45D81BE, DE7C2B1D83BE2CC8EA402ABE1038BB79 + 17: AF5C358BD31CDCAC2F0EA5252F1C3BE1E4, 2D700986F93B22DFE6695C2A243B4E42 + 18: 7DEF9056FBDAF491D7206B26B19DEF617AA1, E71A7D00BE972D85C77931D7591B2151 + 19: 6E9B2C0A90BF9D38A6EA3B5D2B9B2D97F938EB, 5B483D7F15C39602C2918181E57DA341 + 20: 7C5F68DEE9BBA3B04F11D5FC7C9C7FE6E8B5025C, 0AE6A12D37A9C10BB1A494E16705DC05 + 21: AF0A886BF673BC72045FC074F06A0176C96105E2E6, 06B2DC9A2868C23F86D710E01E37E07B + 22: 5F228A986DFE4301EDBAF07A02E114F1B30932995CD1, 74EBF68627C78B1FD024A59B56B2A8FA + 23: 911322F60555118CBECD8DD82F186AC19514316E8D48BA, B6A8BAF2F175CD0C71B63B1EF37E185E + 24: E7F52730CFB808EFDB376A5D5DF31A7EF8292DC5FC37E9BC, BA2AD158A2D2E5CE01296402B592E1DB + 25: B3F8D7CA47D8D86E94D670AFBAFA3B8D9E186C97DC029D4705, 709D2D2B9975D4729C19D4EAC430E65E + 26: 7178FEC027AFADDC2C03518E75CF34D207CAC2EB1537A0DBA520, A315F034CE5E66601444402520F55DE2 + 27: FC230B2B8522F53459D0B968421469BBA7E683ACB0190393B2870F, 48679A78E470E175CF3D3E9B46CEDFCE + 28: 35A641127C78C721ECDC50866C21637FDC9515E41CE60F09015EA713, 0062987222F6412B7AAF8A9ABF6FBF98 + 29: 3D42D6C113421743C08A6F682CFA0E517D5531BB66241C02EC4DCC26F7, B1AAFE11FA2D6E0C870177DDD7F98FF0 + 30: DAD065B4669B7C59C8392D8E7BD7E64BC01CEFFF27E335B25A328D356F0E, 8973B9B9ECF26DAB58CCF0787EE928E5 + 31: EBE626F9E241FD233D9781C359430C982667AA26921B62E98FAEC502C01B0B, 2AC0D7052A2CDCCE8E26FEA7595198AA + 32: 64D842B66796A797C2B4C6905742FDF2148FFC445E192F9E03B53810C082F788, 9778B345EC12D222DCC6DBABD2651750 + +EAX-blowfish (8 byte key) + 0: , D8C4C23A6AC0B7B7 + 1: 2A, 5E0E4BDDB60772FB + 2: 7695, 7581B16CCC9C45F1 + 3: EB14C8, 6223A121CFA216C7 + 4: 5A5C809C, 4A47658796337D6A + 5: 8BC2041181, E1FBA8DBA00571FC + 6: 89C666F015FA, 2B4A76A0E699FCFE + 7: 86C1FA92484AF6, 31B3B738A261D6F5 + 8: D1F401C145C9328B, 4C4A045EB489F59C + 9: 70C9C7753698324A73, AB298B5B20567EB4 + 10: A50D9D88DC101B6DC8D2, 529DFCBFD13B8E6C + 11: 7CC2885C2BE79C44F28FF2, 566255022B40C81C + 12: 6902D58347C29250EE07981C, 34619AF18E14C690 + 13: AB6C3C4AD3EC45143392B642DA, E6D2DD323DA175BB + 14: 7065B28BA8AB67B2FB7B6D5E3FAF, AEDCAA54F4B0772F + 15: CBBA14A74AD4ADC0EF036EDAE42D51, F2BFFA4D81BAC034 + 16: 60A315193F58144F5701D547C79FEEED, 912FDBDB05467DF5 + +EAX-xtea (16 byte key) + 0: , 86881D824E3BC561 + 1: EE, 4C3505F04611D9C2 + 2: 80C8, 6A3428BEEAD60738 + 3: BF88E7, 04F1E99E9F5906C2 + 4: E06574B7, 33B0153AAEF9776F + 5: 42D950AF63, 4A0F415640322FDF + 6: C30F6AD46EC9, 9646FE909D2B95CB + 7: A0049FCA856A14, A0257289C6BBF278 + 8: 2814B0C1358440E0, C4B0A2354925E887 + 9: BF4F062B52C1E489CF, B56442A3CA57A041 + 10: 63DF433956831B8780FC, ADF9ED0B46DCA19E + 11: C317FD079817F50E0E8A16, 2EA0EC993FC603AE + 12: 2BD12FDDD81EB11660346D2A, FBC6F69125BBA88D + 13: 85D356536FE2843C6BBE60EDBC, BB2FEFD04F230E79 + 14: 22493009DB01B4746F4927A8C4FB, 64CC08471D93C9AC + 15: C0F3C0DB08DC93FBA725D1E02DE084, 77B762213DDCCFFE + 16: 568B66D3112556BD98FF9339E9C002E5, C8355F508219FE0C + +EAX-rc5 (8 byte key) + 0: , 169C7954341EF44D + 1: 22, DABFDA9A0B0BA067 + 2: 2E54, 6A3D6D9AA5877C5A + 3: 2A6ECF, 2A34A3AF5DE8919E + 4: 9CC5F84F, D3F673EDAF75E3B5 + 5: FF5611756C, CC647FAAC8D49BF1 + 6: 74C939BEB31C, C335999CCFE8F5FA + 7: 7976B6F7709B5F, 2A7969C5FD063A88 + 8: 421EEC5022276174, 2C9BFB1EAC3C54A2 + 9: 6A4761CD266B1C0ECB, 3EA3CCEBC85FAC4E + 10: 7C09201098E764239A2E, 8043ABA9BF4D5AEE + 11: 8CE26277562F646DE33C88, D72AED48895E3B40 + 12: 52150F44D37D121560DA87F6, 58E865E22B485906 + 13: BA0A73B45F93ECFBFC3AB3D8D0, 683D52FA47FB1A52 + 14: 96546CBE01054AD24CC95DB54724, D80D0D530E5D1DDE + 15: 61E654BB18CD26FC36C09F874DC2C7, C65884CB9D9FEC1E + 16: 1D77B8BF02CDEAB4A707C07628826D5B, F18D1730C3D64701 + +EAX-rc6 (16 byte key) + 0: , 1DF8B0B92A3F0C951C425AF4830E63FD + 1: 1A, 8A2959EBBE90180999994DEB7036DB85 + 2: 435D, 7EF00CB57DB7B4155DB530D75CE6B025 + 3: 08A6CF, 2ED6AF0F2D5BAB05F623D389480A01F2 + 4: A86E54D3, FC69547C8BD922A5BF2F7B26C4D20F98 + 5: ED0822E439, 0007A3C6DEFC6C912C0E5B853B520368 + 6: 7BEFC7FD4054, D32C43A4D1086D57C5BCFAEE04EBC600 + 7: 5235E58E79287C, A27E9C781327C0FC7C55410EB0C828A9 + 8: CEB5EE99BE521F4D, 547F46383987F2A3582A81A3BCF9B280 + 9: 0358B063D5F99C3770, C0A73730512CDA6AD49599775D59EDA1 + 10: 434B9AEE07DFADD0A332, 499BD88881E558E09A8E822BE27D2496 + 11: D47849E650F350BB622D74, 638E37A84E7FAAF8F5D77F1B061773DC + 12: 814592F568284085E79A024B, 9EB1405E8422FE50BC0D88D837A2C650 + 13: 6F2B55EC91B591082053AF692E, C48F91EF01AA43A1EE3B36D233DDD48B + 14: 506CBDD2901838EE2F178B6953DA, 03778957F536509BFCA577B23A18F726 + 15: 446EE435D3D1848B51BB8C5F7BE4A1, 1129EAEAADE534940546D43242A4C839 + 16: FB9D2B150C42465B1685D8F069CC06DB, 41E2940F5DC63CB4E2FBEC25ED8A31E6 + 17: 9684F683260107BE8FEBBEE1D3EEDAA7BD, BAE7C116F7FF96631F4ACEE95C65CEF3 + 18: 5082B1FE48CD3AB58F63C2DCFDD4069AC736, 19AC7B8EE315CBB7131A283851B32266 + 19: 8C72AE495B6F003A3C784D144E84E88885F78E, FA4CEC023740A8D670E351FBCF62C1CB + 20: 815D6361C7AE34C9D796ADF9C71ABC46AEF88BC9, 9A1F7288C61A6623B9A82748137ED7CC + 21: 904A853E2E96BD2B85AAB3F5DFB900E9B3642EE667, 9AA90DBDD461CAD20495DCFBCB513DD2 + 22: 79D738A462F727B3D3C529ED999B6FDCCD991D1C5A4D, BF0987BEDDE650D73CAE7D380FED3431 + 23: B2DEFDB7D503A84E83155A04B8DE8C8DBB68C2FC475007, B7CE900CF43CD518024123C76F6DA328 + 24: 9E723E15439E12F6C46DF8A309AE1E97B6FD18436259CFB0, DF8B6E1E23512CC4CF5FF531A1908F69 + 25: A7F0AD03CEBCC9202718AA164886E1026975306A664C5AC7A9, 4A771BF8B9A4325705C85E5499FD98E9 + 26: A53A92AD1C6835F28E04EF591E783D36F3D76E489B31B87BEB7A, AA263B52A6E6A043DE4D7029D4DC73F5 + 27: 79BE3C38291A7F77E932C8A9DEAC08DE6442EA9B3895B101A14E7B, 33B84DE06342E675E019CD0237292ED0 + 28: FA108123C5A69571CFDFE8C3D00535121FDE3096DDC0D700F8F26A5A, 764025D7CA1A3F2C54D28956423B0C77 + 29: 36EC2D67FD977BD2B73DB6D8EB756B3EADA13690E1B6DFC12A4781B34B, 4BC6B38DE3B02283D92F4DF19A5C48C5 + 30: 96D3243C945905C9732B5927E46F00886D511463B38C86002FC26B65AB8C, 5B5511CDEC35687AB8425AB22D58B4F1 + 31: 9CF83B87BEA3374AF7722E999863E3DABB858B0383383EAC7757F5B80FD44B, 1E0CBC961940FDA93B73A92DACFD67F3 + 32: CE3BC3C9FA5EF4AFE5272B3EDD24B1B003FED2C2E501528CFF44D3FABFF52CB4, DC94FDDC78AAB2B7CAA1E1EF149AC355 + +EAX-safer+ (16 byte key) + 0: , B120C7B37450C46189712E4DFD1F0C44 + 1: CA, 82BA1869C5FF1EF2A4F6ADC1E7DC1F1D + 2: DD20, 6BD5601B16C9943A84AC1F99A176E6D1 + 3: C1C09F, 0911DC63AA414C004E2BD825BECDC93B + 4: 27E43F59, BD858F084B082F76814DC385E1FB20D1 + 5: 2A9A92F246, 5ADC4A32491934AC0BD00FCE686B26F1 + 6: 52C78C0CD6F4, F35886F46C03EDCA10B3D01CF07B1E0A + 7: 23E0D3CED3795F, FE33D96FC98B78A30C0A412C60E93992 + 8: CD3FC9961559F239, 9982364A61609FC41068260267231EE9 + 9: 6EA46CB7AD7505C1BC, BB15053EF0F78B9091B3064118F3E9BF + 10: 05D9BA230A56CCA0703A, 1338E68E3DC992B6EB2685C668E75869 + 11: 7AAD6049DFDCA6771AE42B, 35267E431051E1812495615324C4CBE6 + 12: 8695091532B83B23C296F620, 7B2EEA861E9A91E6B6A911E10FC3FDD1 + 13: D909DA4BC7372ACAEA78E6A0EE, EA6C1CD16180DF0B07F4E204A4B4FACB + 14: 7DEC8443600D0563AEFE87A2064F, DA454728069B3B409889664783588189 + 15: C042FE656742CD2FE5D9C212D18C6C, 5929E4AECC2CA047BAE948E7023FE4D0 + 16: 0B84D3CF59EEF7319633F4A397D47CF8, 31F892FFDB7535DF5D9143456E404163 + 17: 8C9E57AAFA7969B142742B63AB73286600, C418231C44F96660DDBA8C26B3BB3681 + 18: E9EED66D370A3A6A39C7E0E570D96F807EAC, A4AFE8D1D3C31B956A3BDBD043E7A665 + 19: 1A5D47992DA5597D1449B4C8DD47B7404C7657, F3ECEE5182014FC3365FDBC4C33CC06A + 20: E7C7945FD1AFD3F5DCE666D8A5A2E8A3C11A7A5F, 86D78B2FBA7597B8806BED505B52BDF6 + 21: 9E2165B47B29CBC4ACD50660E011D691F061209969, E9B1E860BD02085177E1A94E1EE6F3F0 + 22: 48EA2945C8DD3FE09407BAC8973A861DB15B788C8FFD, 502926712EDB1B3DD13806052C6C75D7 + 23: F37D46B35B60819EA52B00457D79155C04B55972D0DFA9, BB2B7D210BF0570F422640BF81F39B9E + 24: 12E85C0C78227205CC682360C79E35BF58EC6551CF8FE2D0, 042990D7A58D458C570A15DD375DB4E7 + 25: 4F6C15109DE980DD14A7F4C27F48671E4787C53A564232F427, B097A5990D8067DD89C21473150C070F + 26: AAC472E49DB101B564A8A01E2C80C0C6AE9065D332C2DE79FAB6, ACDD587A7DB86542E195DF73AF1C1CBC + 27: B9912CE18019C31692A1F7E11D9CCB20297ACCB9DC62C47C01D2C2, B0ACBF028CA5B15E0035D2EB8CA916BE + 28: B4F2B1FE14A1ECDC9C8EA1A0120395E6ED1E69D3FC85DD0F3F90F350, 9A561EBC769369B95B9CB74FC6AC27D3 + 29: 3FE397C8AD02689B7437A37861F0907AF1F6014A293B46419348771C5A, 6B7BEB9BD5018FECD71BE5081C7C2544 + 30: 5019089142199F7207E1B7731B8B247A18A685B231499DF12A73F5D67D37, 307E93446777005BA1B088F178A0DB6E + 31: EAE8F9F02F8DB3D70B78B08CFB0949D99F1A86C958A8E3823736BCEAB86BE1, 6C94F48591C18BF9C450515B73379973 + 32: B9C795F7A87305B4AD36DBA10B3B1C70B329D29E49C8C6A932D96A74334AEE4A, D18E6E233FEFD6E5C7148BDC1504299C + +EAX-twofish (16 byte key) + 0: , DB0C02CB069E3773296D3BD4A87A381B + 1: 99, 7D21D19E9C440F68E99F1F2EA2668694 + 2: 0696, EA590EC417C88E23FD23917F9ECFB0C6 + 3: B9B082, 82D4C9B68DDB02C906496413E13A2D68 + 4: D6B29D74, 5BCE5CA4F662E883BF7FCAAE5FB2CE01 + 5: A59C9CB009, CBFB04226D1029A7EC9D64A48A6729BE + 6: F4924FE3E355, 3D85B3900DECA0528C815F1447A1F209 + 7: 679C88D52FB519, 931C7A863C3701D8015FDBD8696C6C30 + 8: 26DA41C0D115375E, 7627E23E791A4DCB0FA5ED71B1ED2288 + 9: 8FEC6EB7016AD2B178, F65ED0286A724F0CB2EA317D5022B0D8 + 10: B5F22415B1334133C531, 87C4F3A8991BBB85984BC4D3305A5CF1 + 11: 23E1D0ED2E820AFE7DA2FE, 100499F1093FAB2ECF73B643594E98E3 + 12: 79519ABA91F46B8DAD6D5335, FBDCD1FCDB20AB99135F28A714C6992F + 13: 5968D0B4198A0AAD3D0395018F, 781F22E2DA98F83398FCF911B2010057 + 14: 4E55B14432B601E3EF2EF567CB15, 8BF6E53D7657E56EA3DA1BFD9C9EC06E + 15: 6ED89651CE19B3DD1EE5C8780B5015, 131CFD657D32D4E1B35140ADDCA0E13A + 16: 2295A968B4D072D12757756247554850, F35FAC95C2AA4155450EAAA6E2E789B5 + 17: F9B2AA2AA502EA79BBA0C5EAD932B8E1EE, 0ED81AA40B9BF39A9AAEDDDB7A04BEA6 + 18: 385055F1C1C26C0472A504B4CD225DCA55FE, 24831680B56368231AC54227D737F582 + 19: 771529585C741A3F8B1C973709892F255A99EE, 2A132B4BF96FD5109DB04459103F5E84 + 20: E7A2197D9FAA8AB8B303B5EC71AE34AD5EC5DD66, CCAB6518371EC8E0A9E9EE4F7CA5878B + 21: 279E54F755EAC6B57375B9EC4406E43DB3139D740C, 7B6F26F2C0ECC9F2DF4EDD7513E6E0B7 + 22: 27816AA94CBA2BF98E49E595AF5B3FAD12BF1D6F1AC6, D04876C5492D275F15C834E3CF794F0E + 23: B5658DC148855F68B282211D879F688F3C142FE555CF81, 4539CDA8A65DB9047AAD76B421B81120 + 24: 72F0BD4F939C2C9B4FA734DCB0AE4FB9BD342BC8459ED2FE, CEA8469BC0457EBF3418C1114288C904 + 25: 70568245E6E6BD5D11AD0C74030D7AE08BA05057DEA0FBF4AD, 71554FDE6B87477A51EE4499D78783D2 + 26: 8702D35BE07D7ADF70684046CC6C72FBBBF821E0BBCCBC973601, 33CC6FBFDA15E306919E0C3BB2E22BB6 + 27: 0BA23F4A6174165D4A8BA80B7C875340B0F8B2A6967D34E106BC22, 00E6679496714236EECEC84B9AF3072E + 28: B9E25ABA84C6BD95B5149E7616FE2E1D6FAACEAAD77A636C60279176, 8D8AD0B9D4C709E1DA370EE01611482A + 29: 74759711F6D542581F9F83498FB616638D092732BA07109BF4B5BE045C, 71A40DC777BD09F75362F7B20E0B7576 + 30: ADBF7E98926484BA2C7F6CD7CD9734FC19265F68AF3BFCAEB025F6296E37, 8DF15B5F69B67F7DABE44E3666B55047 + 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF + 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1 + +EAX-rc2 (8 byte key) + 0: , D6CC8632EEE0F46B + 1: 4C, EA19572CB8970CB4 + 2: 5537, 3EDD3253F6D0C1A8 + 3: 206FA6, 20FA88F03F240D31 + 4: 17EE8B40, 702E8194F1FCBFDE + 5: 2A89287136, 31C5534786E15FB3 + 6: 3A6AEDC7066B, 3C663A4081E1D243 + 7: 8BC5203947A644, 6AAC806C92BFBD6E + 8: 2E0274BBE14D21A3, CEB0E0CB73C3664C + 9: 9C4B292B0CF17E3A29, F23CD535559023EC + 10: 8E322734308F85662877, 46363D7EFC322821 + 11: C413C405767FF5F98E3667, E7BA35D8F3678E7E + 12: D77806B7A218098B1569EADC, BA67C306E5C0181B + 13: 4BE5EF74F9E9799A4D636FEA9F, 4C511C44ADBA4030 + 14: 7E19969170C2C8D8AEBA8C7FBC2C, 54CC6D466A2DF6DA + 15: 2EF1CEDC1DD3403CF440FC5561BE33, 61C6FB277E93701F + 16: DE052719153EBACE9D7B19F52AC4282F, 4AC2A96F2FA8634C + +EAX-des (8 byte key) + 0: , 44048B7F240B6F5F + 1: 0A, 37009B7D4E09953A + 2: 03BA, BFD2FD7758961728 + 3: 37EE10, 16A6AF96DE888A19 + 4: 07F44290, 100CA84AA0EDAA1D + 5: 389EF0023B, 9614FB800A533268 + 6: 3F4DBA8AA01C, EFA6B55B7ED5E40F + 7: 8C7B837896EAE7, C113CE8F664CE3D4 + 8: 7011D993D8EDB0C7, B4C370A919F60497 + 9: 0DEB30A31351B13D7B, 00ABC82DC5F3A1AF + 10: 8D3897B2CBE323D6EE1C, 7A2D15627CA1441B + 11: DBC002C817DEBFB419F94B, D8EB87F86D6ACDEF + 12: 17048E2976FA85AA849E9A80, 229FCD1C9D1E3B9C + 13: 30B989EF646544885A478AC198, C1B7EB4F799105C8 + 14: 5C2E12A7F118A08D6FD585F9C839, C358679FEE6FE7D7 + 15: 8D1A1E888BBB8648E638C4E74E11B8, 685E006C441448B8 + 16: 93AE906B8BE4EAC8ED6D8F48F04A7AFF, 71DD7AF752FE28FB + +EAX-3des (24 byte key) + 0: , 8914311BB990B725 + 1: D8, 2094EDC5D03E54B1 + 2: FEE5, 781CFB0EBE3895CA + 3: DECF5E, 59918E8A5C4B459B + 4: BD583AAD, 2013BEEBEEA795A1 + 5: 2BC01C6C78, 0B1134DBBEAB5D3F + 6: 4D5EAF01A895, AB4D17516ECBA50A + 7: AF229F90614480, D3113C0A9D133CD4 + 8: BCA6F375DF4568E0, 8E9EAEC8E77786BC + 9: 575F34219E6DD8DB4C, B40C75139E5D1860 + 10: A199B8AC433B615EC96F, 774AF803698ADE3D + 11: 718A2975DD9A872A68AE10, 3B9460F849CBA7FB + 12: AB38E148180F6E2FFBB96F91, E3EE3B8FC50DADBC + 13: EB10E0233507459D4A6C29EE80, 8D90B46BB1EAB27E + 14: EB48559C320DFB056C37458E19B5, 9315F0C4AF8500EB + 15: 9E8C73EADA105749B5D8D97392EDC3, 2E749EE66C1E6A16 + 16: 600FA4149AF252C87B828C780AEFF8BC, 33D7D11DCDC19936 + +EAX-cast5 (8 byte key) + 0: , 382FB8F7E9F69FDC + 1: 99, 20DA959849B3F7AB + 2: C54B, D05547C6AFA3484A + 3: 579836, AAA92B2321FC50C5 + 4: FEB7AE55, 639EDF01C4FB965D + 5: EA8A6023FA, 01274B3ED5CE102C + 6: B7C4E995121F, 712BFE27CAFF6DDE + 7: F44236660B0004, FAC51D1DF8EC7093 + 8: 01CD7E3D0BF29E8A, 049C47A45D868D0B + 9: DAB170493DFD6E0365, 6F3AEDD9A3ECF4FD + 10: 82C9EEC4803D9CD11FA8, 32683C0A9128C6EA + 11: 324AC59E87B244ECE0F32F, F6B095AAB49353CF + 12: DBDDAB11D02C9CA5843C406E, EA728FC46DDD3B04 + 13: D67376C2A4AD92E7DD80E39303, CAF72B7E7C237EB3 + 14: F2B9BBEF08036C2982C6DDD06918, 70A29D780C22752C + 15: 96E3D9141F8EBF520540C2BC9A9C23, CEFC86A1CD48203D + 16: 70CABBA983179106AE7FCD5F1F31D5C3, BF7F9168F4F82F56 + +EAX-noekeon (16 byte key) + 0: , 556805EEA595CFB9A30FAD196103D7FD + 1: F5, 0A7DAEDFB656526CEF4DDBA8087A227A + 2: 7B8C, 249895D79962D5B4D18FE07366281B72 + 3: ACFF15, DCC489D24832EB106F576AE6B6EB957A + 4: 08ADE7DB, 0D3215999E9960EDAB29B78744C7F139 + 5: 66139213F6, 505E1E7141D043E903C26EE0959EEECD + 6: 078B79F880A8, 35B7EB326A55E50332866EEDB682EC20 + 7: 2809E34D9667D4, FFDEC555F68524A09A6ABACA372077D9 + 8: 93D267DE1EC635D3, 4FF3561990A56E4B374618722EF850FF + 9: F377A4D93FF32F4A51, 91D4070423A90FC54D305169C03F49ED + 10: 6244B717E082993EB7A1, 2E3A8A354AFA9473667ED7FDD46BE9FC + 11: E917559625D25E6E5F2EDA, 19295C37A70314CC9A1D11FDE8D23C92 + 12: 1E6DF2EE112A893AB14DFA92, 12C4A89D4CD65F8116A03A135AFD3701 + 13: 47B18CD762E011770E203CF605, 434909A97E118B20D3AEDC79AFE33A9E + 14: 72D9A1A7DA6F33D5E0B927F9F32C, 779C23714FCAA2B2321EC7FB5B03E222 + 15: DA8B830FFCB3DB274807F780D33240, EDC2F1C8A401F328A53392597730B007 + 16: B53DD2BB840AD933D36A7B5FFDCCFBBB, 4EC0E6D1F916BF633869239B672B37A1 + 17: 42936BB9A936C30408660855F4F47F3314, F0DAA6DDA15585E1697ABBB4790B15B5 + 18: 00372E47F5BA016F1B2A1E680B76AB02052A, CDBF3D241BF7FF96D3DFBEDDB872E901 + 19: 8AA236B0C8BEF6F67A97C2DF90628F6E5838FF, 731DCD61F7F26004C03519F9500EA824 + 20: 55338647812FC9D86CBDDCED7120268A4D43F8BA, 0E61B3C835CAD95FD49FEF002C014E72 + 21: 435820B28E52154B47A04D5E635D8FE37FA47FC985, F6A96DCE4917E8D7C610923627E80970 + 22: 0D30C15B6FEB4A48B14DD15D41A4B25D442AA677B25C, 28E15CCB74AE992C68BDDC8D87802050 + 23: D9D701F9AD6B0E13D2CDDA15A5194E7CE8BD2C02137391, 2DB9A15884E9C996C3D6B5BDA44B9598 + 24: E2390AC5CE10CCFBC72106A52C7F180CB477E3C193CBACA8, 22D3F7DCD6947EA4E78DF57A8E1A9A59 + 25: ADEFB7D9500658D34996AF6BE6336CD78891064EA1DB8E9785, F239D67D039A15C620A7CD4BE4796B3F + 26: 89964C90ABF54A6DF9F13C3681E70C702D80A17BE79F8160F30E, 6336F729ECE1ED7368669D75B7E2DCBA + 27: 576B2813CECDA4F905BD5D58349EF070FF41B7EB6BB2B01B061B0B, 125324CBF2ACF1011A44A99A11EC8AFC + 28: 430B957481748519A60494F0B5F698F34B1A8235B00AC0D1F0A4442E, 1E80A7FCEBBB8E1E12D6831906154485 + 29: E781BFE5FCDE0BFC056CC86C4A0B9DD3B815BE8CA678204CF47289B5B5, 190D5AAA9EC1CB4CC86FACE53BF1201B + 30: 78BFAC07A9B7B2AE9329BF9F9BF18A1A49DD9587001EFCA00E9AD9752764, 4FB5ECBEEB0995C150EBC66508FA19C1 + 31: 7D6C20694109DE21F7955855A8FF832347518DD496C2A114DF142C68ACDEAA, B25D4BB34056DC091A7A3950D46C32EC + 32: 3E1E4395DEC1AFEA9212B95F37E679B6E2D14DF23C5DE49018C2C8038CC4AD45, 9A6DE7BD41A21918AD504490EF4E581D + +EAX-skipjack (10 byte key) + 0: , 85F74B6AFFB10ACD + 1: 3F, 604DF8BDD98A0B3F + 2: EA87, 792374FE07588BF9 + 3: 0169CA, 489AB8AF69DA3306 + 4: A7AC3EB1, 428DAF508E24B583 + 5: AA9028D5B3, C0A44EDA71FB2C86 + 6: DA97BA88A061, DA2EC34077F42585 + 7: 7E25FAA41CEBC8, 36D4987551E06D5B + 8: F662DA6C9001CBFE, B7DEF76680C316A9 + 9: 6D3F73EC716E1DA897, 5F0F83BAE4D3513B + 10: 2A300F585BEE9C889743, F4756C24DEB72A9C + 11: 80518B010DD77C82D19106, 50FF5CAA365F4A70 + 12: 6E579A2173C861B6F37B4CD3, 81E3E5ABBA8F0292 + 13: 5B04829880A72C38871C7021F3, 6B26F463708A3294 + 14: 934177878E9A9A9FB4DEB3895922, EBC1C32F0A2A3E96 + 15: 07AF486D1C458AAB2DBF13C3243FAD, 87288E41A9E64089 + 16: 84059283DF9A2A8563E7AF69235F26DF, 351652A0DBCE9D6E +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/etc/whirlgen.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,91 @@ +#include <stdio.h> + +unsigned E[16] = { 1, 0xb, 9, 0xc, 0xd, 6, 0xf, 3, 0xe, 8, 7, 4, 0xa, 2, 5, 0 }; +unsigned Ei[16]; +unsigned R[16] = { 7, 0xc, 0xb, 0xd, 0xe, 4, 9, 0xf, 6, 3, 8, 0xa, 2, 5, 1, 0 }; +unsigned cir[8][8] = { + {1, 1, 4, 1, 8, 5, 2, 9 }, +}; + + +unsigned gf_mul(unsigned a, unsigned b) +{ + unsigned r; + + r = 0; + while (a) { + if (a & 1) r ^= b; + a >>= 1; + b = (b << 1) ^ (b & 0x80 ? 0x11d : 0x00); + } + return r; +} + +unsigned sbox(unsigned x) +{ + unsigned a, b, w; + + a = x >> 4; + b = x & 15; + + a = E[a]; b = Ei[b]; + w = a ^ b; w = R[w]; + a = E[a ^ w]; b = Ei[b ^ w]; + + + return (a << 4) | b; +} + +int main(void) +{ + unsigned x, y; + + for (x = 0; x < 16; x++) Ei[E[x]] = x; + +// for (x = 0; x < 16; x++) printf("%2x ", sbox(x)); + for (y = 1; y < 8; y++) { + for (x = 0; x < 8; x++) { + cir[y][x] = cir[y-1][(x-1)&7]; + } + } + +/* + printf("\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) printf("%2d ", cir[y][x]); + printf("\n"); + } +*/ + + for (y = 0; y < 8; y++) { + printf("static const ulong64 sbox%d[] = {\n", y); + for (x = 0; x < 256; ) { + printf("CONST64(0x%02x%02x%02x%02x%02x%02x%02x%02x)", + gf_mul(sbox(x), cir[y][0]), + gf_mul(sbox(x), cir[y][1]), + gf_mul(sbox(x), cir[y][2]), + gf_mul(sbox(x), cir[y][3]), + gf_mul(sbox(x), cir[y][4]), + gf_mul(sbox(x), cir[y][5]), + gf_mul(sbox(x), cir[y][6]), + gf_mul(sbox(x), cir[y][7])); + if (x < 255) printf(", "); + if (!(++x & 3)) printf("\n"); + } + printf("};\n\n"); + } + + printf("static const ulong64 cont[] = {\n"); + for (y = 0; y <= 10; y++) { + printf("CONST64(0x"); + for (x = 0; x < 8; x++) { + printf("%02x", sbox((8*y + x)&255)); + } + printf("),\n"); + } + printf("};\n\n"); + return 0; + +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/etc/whirltest.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main(void) +{ + char buf[4096]; + int x; + + while (fgets(buf, sizeof(buf)-2, stdin) != NULL) { + for (x = 0; x < 128; ) { + printf("0x%c%c, ", buf[x], buf[x+1]); + if (!((x += 2) & 31)) printf("\n"); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/hash_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1736 @@ +Hash Test Vectors: + +These are the hashes of nn bytes '00 01 02 03 .. (nn-1)' + +Hash: tiger + 0: 3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3 + 1: 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6 + 2: 65B0E1EA36CA17EDE2F055E67EAD67B1C282A11A5BA3A8E0 + 3: AB7FB8D21CE3D8D9BB5F1AF1F2FA0D3C277906160DB8D226 + 4: FE2E9D43F74B199D91B9291D73CCFCA0BEA5F068FBA244FF + 5: 3DF6D672FE9DAAB21523EB04705D8A8B72B78B00AD465D1C + 6: E05724353FE29957C3E8DEBAA21D0C2DD49CCA22191D5AD3 + 7: 4056DDBF82AE74AB56720DEAF079ACA2F076ED046D044DE5 + 8: 801FB9BE1A9AC7337A81345B3845E4E7C13AF1FBADB73723 + 9: 430156547A82492CA859385304748F65F2D4A7E2664AE2B1 + 10: FC435137CD652D720A11EDF47ABE4680BA4AD5BD810C9835 + 11: 20A8143DF47F5715FA0905FE6F9D1D2B5B2D4E26FA98930B + 12: E4A2063019FBC034DEB01E2A95296042319CBC039DA69A91 + 13: B5F0FA570C4CD69A3C68448BE42C865BDF77ED68B93875E7 + 14: 802BE6EA2CE86A0B371F2354944B19CB3231AF7FB4F00FF8 + 15: D7C08863B5E5E3D69B5404A116315A698E128EBAF8636B70 + 16: 5C5288CB0E4E533056BA5293440D9BE6F3C461233BF1ED51 + 17: 88D3A94F3820E4087DA69D8BBE2CF415466063709C450C4D + 18: C07B4B155F9F75805D9D087087FCDD28D08A9D022192447E + 19: EE473E569FF3E092CF8996B31CE665EA7D61520D42E27395 + 20: E13DAE8098139CFCEA755D2060F107E3C7581EDF9F4B3B85 + 21: B48A9C09F26B379AA28FBC750B50CEF69D0D0EE37FF765F7 + 22: 574A01456373014F4179CDA14541E2E3C5A1CDDA9F9D071C + 23: F2E2831E5BB4AF05914C4BA61BB8D600D1EF071C5DF02269 + 24: B7808A5B6258CBE718EDA938978C69D3FFC45A222E9DBF4C + 25: D8E4E076DDE78950D51EAC9F97D2D1916A0910465D45A55C + 26: 4EDECFAAE1DE98B7E056E64CA24003422BBE6F048129B24C + 27: 0DE283B5A4953EAAEC6F3FDE50D7875C8EE57FA79BDC70FC + 28: ECDD4BA1936DB9E6F83E2BD7F39D23927A1A17B2D52A8649 + 29: BE11893460E49659F7DF3FB3BD5E3E9A319F85FD3496E26C + 30: AEC0DA0F2CC0646325CC03319A0E080F68B46B33F81920D6 + 31: 8824FD39984F6A52FFFF19016E27C594921452086373F2EE + 32: 8B6592AFBB02E227AA451B5CFDC821B84245D34B96BF4F13 + 33: 960DF9C349EC6619FF37E3F0F4832E19CC6A4E4D68962651 + 34: F4E2B7AA72BC7D6E0CF6DA1094BEEFAA9C55610327C62900 + 35: 05FD1B80CA4C7C14FE5BF0ACBD0EA3DAE498DC391DCF2277 + 36: C5E95F953898C68355B591507BB714F0E5DAB9989D083900 + 37: B2D4E286CF7EA8AB6ECD650C9E48CA23497EADE55485DB1E + 38: 9D51657E11C54FFDF205DBB435097A2BC6F93C4BE8D6180B + 39: 3C6AE3911356A343AE3113735F07FCFB5E046ACD47B00FBB + 40: 664342CDECC825ED340A7FFE2E57107DD0B5F24C24B2C3F0 + 41: 4EF7FCA13CE684D81DE4F566D2897CEB407FBB3DDE81FD64 + 42: 54689FECED63F297B13CD494B85E686680F4F78DE7EC81D5 + 43: AF434BDBDC7EF90BE03E40A033F16E8A57B41840E1E8AB59 + 44: A32DB678F44905C18968F5D898CA7992EBE2E4CC3318B96C + 45: DEE9D519A12ACFB8A0935A368D6E6C75EEEEE6F2B0D5D191 + 46: CBC74863472D1C9D23C526F4908BD4D4234E00CBCC99A9E9 + 47: 6C228A1D4871E802E035C9BB16C5187354841FB6BE3C69B6 + 48: CAA755C55AA869E633CB3C6D93A561944AC7418154E2B0F0 + 49: A6835F7C0C6CA8F4A45787BAFA77478AE9ADDBEFBC3052D3 + 50: E406755957EC21BA6A64B5D3AAF31749CF98DF92F1B1FFE0 + 51: 0C2D4A44A803DBA99B7A467553C9293B46A538558BD77DD4 + 52: F04F011B09D275A185528CC040EB719649C8471A87B259B3 + 53: 3DA8B57FF52FCAE7C32636EC6C80708189CED8113C5CDE1E + 54: 6C6C88B8E18DF5CB22EDB61A2D3ED74741A708BC46576FB7 + 55: 2D48EE2BF85DE234754BECF3C6F5B0E62988B5BF24AEA5BB + 56: 0D17702DDCA078ED1CC51B95DF29EA1053CE97F69395C613 + 57: 9D8C2AD327DE43D5782D5F20881F4A8C433BA19AFC8C15AD + 58: 227BA419B760D9D10DBB09585EDD475AC2734FD4539F8275 + 59: 2F5220A828EF94E327BD51D4DF5C58609F8A93B9FE01FFF6 + 60: 0EED9F91E1A33A50B8E913DBA0B5E248D263E1FC72C6A449 + 61: 766B707E999FF3C51EE01168513BA0DCEFEAB222DD1F69F6 + 62: 85E6710694E7C36A2340DA6A371C0560450F3D44D35AD98C + 63: D401F9B13D39C24477C0AE6971C705C63C067F29508C29C9 + 64: 212DF89C57155270344ACCB19027B0B26B104FA0FBBE0FE4 + 65: 3BEDE767AA4A7507DBEFF83D1BC33F67EBA9C64945066227 + 66: 79FED1FB9F17C4980108E8605C10D9E176AC8FE4F6A65064 + 67: 48D9B7622AB7F8968ED926255F78E8CE461E4C9162FFE8B7 + 68: 6638C83837297B3F53B0F824C087D9A0B8D9FC6265683B8F + 69: 174421CF6D331FF51924F8946E8244555C9020D38E31B6DB + 70: 03E42AFB5FFF9B9C3794A3DBEC99FA7E3F7305EF07BD29EF + 71: CCAFC68D4B3ED889DC9F28CB9225808A40AA8E0D5CA343FF + 72: E824F93B4022011886EFC54539D4D5D51863ADA329FB4E22 + 73: 7CF0DC01B326687530F42040BA0D0CE93174455E8A990D14 + 74: 7A8E619479F4F5C418EC041806850E6723CA56AFBC3D32CC + 75: 083C5CA90F4B296C42040559C8296149D4EEBAB5EF2CB82D + 76: 3581B7AC32FA8A0986FD14F277FB106E112B92D18CD689BD + 77: 258E822D9CC1ECA8B55D925BA361BA2D9FC27AF181F138B4 + 78: A86C1E88A64515FA281A462D467458231494F16E835DF873 + 79: 76E7F06FE9B8B388DB012F8B4BE2FB343F95913EDDE47A27 + 80: 00278B4E5690E729EC7118B5BF63C9D1EB1268960893CA75 + 81: 8DE70E64A31BA1AF4F5C23CF774CCA32FE952D76C3FDD1B7 + 82: BBEA72C840749BABAF1415FEAC343411B89515B87848A09A + 83: C6C3CCAC1B338DF117A61ECF9A280E9BA709784C72B76771 + 84: AE9813EF4429EAE73EA9FDB5E23D263AF1BB87928CF5F048 + 85: 68647CD7BFFB8E530D28C86685A8D2F657EE4CD64EDD7E66 + 86: AA8C35B0E746AF56435F6C711AD0423966EA459087409713 + 87: AAD5C0D5E980B29BC88985C544717B81F58CDB923A3468E0 + 88: F60929D14781DE44EA607AAFC0D25FA1B6EF3C6AA0F8B3D7 + 89: C48087DC75EC43A54A593F24E1B359BB75C581A65C3170D0 + 90: 11D1372FBDFD9FF514611AB20D31BA62F18856C8D6AE3AD7 + 91: F2A8076B9017EDADEED41F409C9E32EB3BC090EAE89F855D + 92: 702FA47E5BD35E344B5B87C0082106337206CADD3D4D5014 + 93: B9E03FED752A560C3B0365EDF5BFC4DC7EAC5E4BBB93738D + 94: 3C84C52BF51077A5819F56E5A5C1C06209181579393220C7 + 95: F8ECCA28A525594E138B55C06617A063DF74FE3469D98381 + 96: 1081C3BAEEC0ADF4980C2EA6593B0906DCBEDE4805754774 + 97: B5152E39DE0BFE8982D783FC4F0CB7160EB2D69F6F3B3E5B + 98: 6A6B760BFB1965C72AC793F9C02FA21B0F1C34BD2640BB6B + 99: 1E6DCBFA8BA8D96C29101768A6A39433D5AD5A50E0970730 +100: 733222D3A033351FAFD68C5CE8A4D833BA7420D44103CB6B +101: E4CD7DA59B215F1DEAA8FBBA850F2C1A7F4C3D495FE6804A +102: 7BE78C790713545754D4C78A9318ACA4AA058C5C23540131 +103: B71C3809A504BE2F57AE9E25BDCC3921DC665C65289EA55A +104: 2B8CA39977535EB692EFBF0DECDA8971A8604F7FCBAE75DD +105: 3CC48B51E4C5DE4F0C2ABE0BE6EE4B63CC564A87C01943CD +106: 157ACDF7B59FC25966F9783207554364882840E7251ED6C1 +107: DEA1CFAECF18D3611CCD0517131A16DDBC97A12902DD8BAB +108: 2AD2E990BCF6481284DF44B961632687C2E64DFAE2AE16C2 +109: 838F3A3B28A50A12B5707490A66080DCFA0230E583B6EB14 +110: C8B20315121CDFB3A91BC0EDF11886F283CF6C480F498627 +111: 2B0FB04F100BE9AD51B7D64C76651BAB4B7D31D1D9195711 +112: B6495B6256FF464EC409A4098B622E8BDBB1003411854FD7 +113: 1741A789472E20E1CC89869A2477E4F2807C22182EA5B221 +114: 07ADC82CB3F27389A12B6B9C2B268BDDFD1D9478D9EDA0D7 +115: D9BD6760FB819A8A3CEE75303F8208FCA3E138B517DAB934 +116: 9FCF21A9236C2C12861FD20F1FB15A187CD7EE7821F72BE7 +117: 73D165769B34DA6F151464E61115D0E09A66F8D0FA049726 +118: 74580BFA88EEA03C0EAE722F81997E400D9CC25FA0311DFA +119: E3C6A369820E267C938D276A858928040C7C25A826501DC7 +120: C20AD90DB0B8BEE0335D069259991060969EEC9F939E4CA7 +121: F3746F4CD6A19CC137C5FCC8F60A4C0A7F56D97190B7A9C2 +122: 63A3B79EAF3DF35180960465059C0ADEE06D45179A56284F +123: 606AFD833D082628D58672403EE6DB348E6F68D8CD1947F8 +124: 7567EA8E10CBF312F8478B7C51D87B00B6CF3DE82B03DCE7 +125: DBCDC2B9B8589F6C7616B55B059B3B3E38D97A9E6DF1F29A +126: 15D9909F8D69689E7E78A0DB928194A59623E7253AA9D400 +127: DE39589DCC0C654867943801946B9888B347526279CA15BD +128: 34FA7C74EE67C1F92C0BE1CFD4B2F46A14FFB999604925F6 + +Hash: md2 + 0: 8350E5A3E24C153DF2275C9F80692773 + 1: EE8DBAE3BC62BDC94EA63F69C1BC26C9 + 2: 1EAA4F494D81BC570FED4440EF3AC1C3 + 3: 54CDB6D1BF893171E7814DB84DF63A3A + 4: F71A82F8083CD9ABA3D0D651E2577EDA + 5: 2F708334DBD1FE8F71CEE77E54B470F9 + 6: E014DF2DF43498495056E7A437476A34 + 7: 9C410644446400B0F2C1B4697C443E19 + 8: 0944DEC40367AC855117012204018C9F + 9: CE8A6E797AC79D82D2C6D151F740CB33 + 10: 06DB4C310570268754114F747E1F0946 + 11: 9F323D5FC6DA86307BEBC0371A733787 + 12: 3C1C7E741794D3D4022DE17FCE72B283 + 13: 035D71AA96F782A9EB8D431E431672EE + 14: 7ABE4067ED6CA42C79B542829434559C + 15: 5E8D0D6F6F8E07C226AE9DD32609035A + 16: 2B1632FF487D6C98AA3773B9D3FCD2AB + 17: D3D894482F7541BC0948B19842B479D9 + 18: CFE6B872AC98304524CC6A88B6C45881 + 19: 1573DD015C8629DE9664CA0721473888 + 20: ACFE2D3BB3CCAD8AEF6E37D0D8FBD634 + 21: F5F83499AA172BE8344F7F39BA708AAA + 22: 1D1C71FF6321B685D26F7FA620DA6C22 + 23: 4D7E74B6C8321775A34F7EFF38AAE5DF + 24: 351A988C86AC5A10D0AB8E9071795181 + 25: 970F511C12E9CCD526EFF8574CF1467F + 26: 0A68F53A476F7499EF79278A4EE8DAA3 + 27: D458CF9C8CD0ABA23BD9A8C5ABE495CE + 28: C8002E85C3AD9B8B4AFD23378165C54B + 29: 0B4788B157ED150A34D0E6E96BB4789C + 30: B14F4E31DE09281E07248A17939BE5B9 + 31: 803EEB99231526D6A33C8D4FCA537A6F + 32: 51FE5D6637D2F0F09E48CE2A7F5030EA + +Hash: md4 + 0: 31D6CFE0D16AE931B73C59D7E0C089C0 + 1: 47C61A0FA8738BA77308A8A600F88E4B + 2: 9E7A1DDE4D280E7F389018A5CCC3ABF2 + 3: E9A4DB2923FAF634CBB12CC1F8AC5C66 + 4: DF8FA069C6121801FFC539DADD33FCB9 + 5: 4B3511308F7E71BF6462CF18F1184C61 + 6: 075582A51F87682919E733C84C9FD998 + 7: 20DDA7535A464D13E1763BA61BDC12AC + 8: 66AE1E305BED186780BB60328D3CCBC5 + 9: 503E90BF2375627262E58D90177220F8 + 10: AEC6B48C10659E3D6E18A2CDE8F8D3A0 + 11: 45EFB3704B6684B0750E3DEDBB2BCDA9 + 12: 7C9443DBCD858138E32604E0D288F7B8 + 13: 95E5B93F4EA79C082BA1745D3026D70A + 14: C913D5DE0BBD1C2F2838E46363732D97 + 15: ABE357BDC413C82C8BBAA380C39CB5F9 + 16: 22F840370EBB1DDBEA4FA3A40243391E + 17: 0A289FEC69AF967988FA40C47960060B + 18: B63D3ADF13B509C95C088F909A0B356E + 19: 36E8E07E3202E6F4F7E885853C9735C7 + 20: 1D363AFD1208A7B8BD486D51AEBFAEB8 + 21: 75E36A5445AD72CF5BF47301EBED1FDF + 22: DA7979688F48A6606D86C762DF0D8850 + 23: 6ACB325CE624372873CC01A4AA053F8E + 24: 94F9BFD6503DBDC58C163E33504B7EDB + 25: 3702CB296784290FC46B82445BF7EB17 + 26: 903510251E7A00415EA21B6AC268A92D + 27: 6DF08DB9C33C86CFE8DAF5E5BB865ECE + 28: C29C5223D89A6589DE9253AF050D3449 + 29: 16B935ACC3EC6C016CA1BBF727C272B9 + 30: 644C01B157A24584B02A32119A424C01 + 31: 4A3C6C73634759420C419426F7D43E67 + 32: 7BD627A6B82FF3D797FFF130D8956391 + 33: 811A69D6A8AFE3C4FE5B4EFD73804F6E + 34: 721BE5F4BDDED885BFF842868F62F4ED + 35: 76956871B22D5BECAD3E9A459B4A448B + 36: 4F2CF372771A13B4C0C1A589F0EDCF87 + 37: 084AFBAE8D22DF83CC760A61138E560A + 38: E1CA123EBA05CC4899731A593833F372 + 39: 9D9E277FA61993C018C1C61AE09588BC + 40: 85E0D0316F0B76578948810039EDE2BA + 41: 27736345D0F2B0A1A9576D17C47D0202 + 42: DC9F788BE7C97BB5E0D2DD49B9F1D2DC + 43: 27F1A9A0D166C495493877DF06E9C104 + 44: D1ACA7951866F58773CD4AFA3D2F5C2E + 45: 5204BE3729BD7D318EA8127BED82D5CC + 46: 10258B7939D81F5F8E0EA70EE6500B08 + 47: 4E699952169098ED3084DC2EEE7BC488 + 48: DF6ED8D604512088FCEAFB21808BF7D0 + 49: 904D0667C94C9C981D59BE80DEEEE628 + 50: D83483A47B64D74F9DED5278EE462404 + 51: 490EC8799A9DE3BDE8708DAF68E6888E + 52: 443E4D2D5F800C22D818927A29A38490 + 53: 48E82AA772E111FCBE393177F3123963 + 54: B72685D042162D5F30472281278C42F7 + 55: CC8A7F2BD608E3EEECB7F121D13BEA55 + 56: B8E94B6408BBFA6EC9805BF21BC05CBD + 57: 6AEC85410412FF54078A9FC72A55ACE5 + 58: 3E69F792BE88478883E46E867F3C93EB + 59: 3B057FC41BA700F0E46740B8FF391F52 + 60: 3E3C6DF9500BFF8404486A3AEFC6F16D + 61: F5AD65BA970ACBBB8335F9C0B9D7139F + 62: 75D45F8E48406E32ABF94D07FF9B9C84 + 63: 54BA4472FCD03E99CF28F90EED9F2AE0 + 64: 2DE6578F0E7898FA17ACD84B79685D3A + 65: 3A4F2CA37EEBDF6DC99A6155517B74FC + 66: E19DC463C01E1B712B9415202A2B5505 + 67: 61D8AA0838DEAEEADE2F26156AF58761 + 68: BE294AFF81BFEA3159564B8B61844EFE + 69: BB943319320EE7B3A029D7BCD101F92F + 70: 36239791A7BE33AD46F668B51D724481 + 71: 21DCC9A32031428B7B02F68E1450A0F3 + 72: 95C1B0832575E21982B17CCCCAF54556 + 73: 24939E25985A3B5620B19D7889E5E153 + 74: 3029C8B005386705FE7E4CBAA060E987 + 75: E8BD97C5C1A0CC9AD1F1BEB3913B22FF + 76: 808EBCA0B0E6FD1B30E4BA499C05EF9B + 77: 55BD20AB87DE2E536DDE22286D0922D9 + 78: 2B2E45FA5628F29DA06462378D17DD12 + 79: B90F1709241EF59F78666AEBB3D5607C + 80: 37854275343F079BCE1639C84D74AE1C + 81: 444AB5A4F39B765C5D67BB433D4CF0B1 + 82: 7E30CFA6363F9AC96607783710E151B9 + 83: 9D9252DFFB2D5023CFE34873EA6C43AE + 84: 49A70634AFCED27DC2DF2EB079F7A1E6 + 85: 4C976C9EF13716CCB468D82BD8C56FE2 + 86: 4EB382D16DDC18C31E6DBAC6CA83247D + 87: B16112D0FF3C6A8ADB19C13DF742F5D1 + 88: F703DC6100AE23D194E01EAC433CF28B + 89: A6527B1B907218063BF196AA91C73F47 + 90: 61F1A1E947F3F542FCF85AC758BA5D14 + 91: 12ADDEDCE418E9444AE34A40353ED0EB + 92: D1C35142C475D44A52CEB0A8FAEA7AAB + 93: 1F89912C1FC59AAB53C983B035661269 + 94: 2E7E19A4A6635AB5958DDA70B415EB06 + 95: B700B6739C0AF162D246AF07284A1AE8 + 96: E2B95AC9F876A38D33CCBBD7FA92D67E + 97: AEB4849953750A10BB236BAC8D5AB487 + 98: 82D738AF18FD4B26FFF61377EE921E62 + 99: 0E1451640E59CE0461A46934F174E237 +100: AE06EA64074E8C07116563E8E0893BDC +101: 562DCEB678FBFAB24141E591FFD471B1 +102: 7DD6C3C2884E483E8CA572C471B2D812 +103: 2A4C8E4EC2672C1D54A8DA8F32F04783 +104: 2BFED22E8810A4658060B95B0ADB60BC +105: 214D8F2DD099BAB68EC17189BFF8A8EF +106: 98E4EB29797C8E631CD4317AF422FB05 +107: 241A0F826F359A21CA0E6D9154D1E291 +108: A3398C0118A3605E7A7794B8DF7CA152 +109: 5B0A6FC8721F14EB8A03E9A5D87F173B +110: D93ABEC3EBD5672350C3C36F8FB00E53 +111: 659905751D1F614A78ECBB56D4398D06 +112: 594691B38126E028352DA5B28ADFD416 +113: 7533FBD1FD58C85D54A712EF218A9D53 +114: 654796E7D2F9F2C2D166F23B5AB18812 +115: 5D25B604FB75727AE7EBFF980F54D96A +116: 426A7709CD61EB6ECF4034EC83E073EC +117: 62E21CA2F8E39C03BFF56C8265ACB60A +118: B7C9DAAA89A29F2805DEDE790DCB9575 +119: 9C1067170940CE8F8E4745D362675FAB +120: C5BB35660E3D0A286A96EA3AA4922B3C +121: 8F3B6351623A0E482B57525474DC703A +122: CCC34CC280340681CA5117477DD86AE8 +123: 2F5FB6B41301F87A0490035DE4C1BB99 +124: A16E28DB3F331091E928F9AE3F1ACEB6 +125: 7D2259C98085B9BF7F5E36B29DF8384A +126: BDDA1266FF3E8FFBA1DE1B2759B58BCC +127: 2067886DA4BDE10A94B971CD740B0AAB +128: E1275970EB67D2D996E6E658270AA149 + +Hash: md5 + 0: D41D8CD98F00B204E9800998ECF8427E + 1: 93B885ADFE0DA089CDF634904FD59F71 + 2: 441077CC9E57554DD476BDFB8B8B8102 + 3: B95F67F61EBB03619622D798F45FC2D3 + 4: 37B59AFD592725F9305E484A5D7F5168 + 5: D05374DC381D9B52806446A71C8E79B1 + 6: D15AE53931880FD7B724DD7888B4B4ED + 7: 9AA461E1ECA4086F9230AA49C90B0C61 + 8: 3677509751CCF61539174D2B9635A7BF + 9: A6E7D3B46FDFAF0BDE2A1F832A00D2DE + 10: C56BD5480F6E5413CB62A0AD9666613A + 11: 5B86FA8AD8F4357EA417214182177BE8 + 12: 50A73D7013E9803E3B20888F8FCAFB15 + 13: B20D4797E23EEA3EA5778970D2E226F3 + 14: AA541E601B7B9DDD0504D19866350D4E + 15: 58B7CE493AC99C66058538DACB1E3C94 + 16: 1AC1EF01E96CAF1BE0D329331A4FC2A8 + 17: 1BDD36B0A024C90DB383512607293692 + 18: 633AB81AEA5942052B794524E1A28477 + 19: 2D325313EB5DF436C078435FA0F5EFF1 + 20: 1549D1AAE20214E065AB4B76AAAC89A8 + 21: 7E437C81824D3982E70C88B5DA8EA94B + 22: 2F5F7E7216832AE19C353023618A35A8 + 23: 6535E52506C27EAA1033891FF4F3A74E + 24: 8BD9C8EFBBAC58748951CA5A45CFD386 + 25: D983C63BF41853056787FE1BB764DBFF + 26: B4F24C1219FB00D081C4020C56263451 + 27: B0AE6708C5E1BE10668F57D3916CF423 + 28: BA7BB5AD4DBA5BDE028703007969CB25 + 29: EA880E16EAC1B1488AFF8A25D11D6271 + 30: C7172F0903C4919EB232F18AB7A30C42 + 31: E9E77893BA926E732F483282F416FFAC + 32: B4FFCB23737CEC315A4A4D1AA2A620CE + 33: 5506A276A0A9ACC3093F9169C73CF8C5 + 34: E5A849897D9CC0B25B286C1F0BFB50E3 + 35: F54FA30EA7B26D3E11C54D3C8451BCF0 + 36: 07602FE0229E486957081A49E3F06F83 + 37: 7C4BBA98253CA834BF9ED43FD8B2F959 + 38: CF8DF427548BBFDB1E11143FDF008B85 + 39: 1431A6895A8F435755395F9BA83E76BF + 40: 30DD5E4CAE35BA892CC66D7736723980 + 41: 8EE247A1063931BEDAF4C2FA3E4E261A + 42: C32CEEE2D2245DF8589F94FCDA0C9F2C + 43: F25FA0E071D1F1CDC6632C6B673BCCD5 + 44: 370491B643E97577F4F74BD88576D1EC + 45: B292BF16E3AAFAF41F19C921068214F8 + 46: 52921AAE5CCC9B6E8E45853419D0C80F + 47: F1375BE31969155EF76F04741CD861D7 + 48: 04605CA542B2D82B9886A4B4B9ACFB1C + 49: FA887BA0FA491FAAACBB82BC5FEFCD5B + 50: 06470E932AD7C7CEDF548B5CCB9D4806 + 51: AD130B245E2DD894267CB0DDC532D169 + 52: A9EEB95053682248608E97D79E89CA82 + 53: CC26A3DC608268B98ECD1F3946C4B718 + 54: 33DD62A2DF6538DAF1CF821D9CDE61F9 + 55: 6912EE65FFF2D9F9CE2508CDDF8BCDA0 + 56: 51FDD1ACDA72405DFDFA03FCB85896D7 + 57: 5320EF4C17EF34A0CF2DB763338D25EB + 58: 9F4F41B5CDE885F94CFC0E06E78F929D + 59: E39965BC00ECACD90FD875F77EFF499A + 60: 63ED72093AE09E2C8553EE069E63D702 + 61: 0D08FC14AC5BAA37792377355DBAD0AE + 62: F3CDFFE2E160A061754A06DAFCFD688B + 63: 48A6295221902E8E0938F773A7185E72 + 64: B2D3F56BC197FD985D5965079B5E7148 + 65: 8BD7053801C768420FAF816FADBA971C + 66: E58B3261A467F02BA51B215C013DF4C3 + 67: 73062234B55754C3383480D5EF70DCE5 + 68: F752EBD79A813EF27C35BED69E2EE69F + 69: 10907846EB89EF5DC5D4935A09DAD0E7 + 70: 5F1F5F64B84400FB9AD6D8ECD9C142A0 + 71: 3157D7BB98A202B50CF0C437AA216C39 + 72: 70E7ADE70281B0AFCB1D4ED13EFC2E25 + 73: 0BB96A503B1626C9AB16C1291C663E75 + 74: 5BED4126B3C973F685FCF92A738D4DAB + 75: 7523C240F2A44E86DD22504CA49F098D + 76: 6710949ED8AE17C44FB77496BEDCB2AB + 77: 4A4C43373B9E40035E6E40CBA227CE0B + 78: 91977CBCC32CDEAEC7A0FA24BB948D6A + 79: A6A0F1373CF3DBEE116DF2738D6F544D + 80: 761F6D007F6E5C64C8D161A5CED4E0AA + 81: D44EA4D5A7074B88883A82F2B4CFBE67 + 82: 3097EDA5666E2B2723E8949FCFF2F244 + 83: AB247A3D9BC600F594D5A6C50B80583F + 84: B229430E3DB2DFDD13AA1DA1BAC14D5C + 85: BEFEF62987C6DCDF24FEBD0BB7CD3678 + 86: BFC3E5C7C461500FF085A66548378E0E + 87: A5712194537C75F0DD5A5AB3E9EBAF03 + 88: 8DAAC097E9044B85B75999D6C3BCCD24 + 89: B8124DF21129685597C53A3F606FFD28 + 90: 8FBC4D795C22D958248582A8DF7332ED + 91: 36D217135DB136B2BDF1617D7E9C79CE + 92: 1B3E6271A3A4B663C509A1255027CA99 + 93: A25F596574031FF9C34314C1B1F6BF34 + 94: ACA7017E5BB62BFDD5BBFDED78C8987A + 95: 8129E53A694ADD0560B1534B32FE5912 + 96: DA0E48224106C7535A4CD8DB2AC7B8E3 + 97: CBD4ACE3D766D8E44F63E0DE8F110F04 + 98: BDC17A0EF2777512CB402C90E9D13E31 + 99: 47695AD6AF968D6F1CDD2D8C5C87A466 +100: 7ACEDD1A84A4CFCB6E7A16003242945E +101: 225489D3D073AC705F7B3AD358EABAB2 +102: 301DA87A7B2EC27514C3A2789D5DBE49 +103: 16222C503718F1420958133C330FE3F8 +104: D778CE7F642AA23355948477DA4CC11C +105: E873C37F8977E200A594B815E1A87EF3 +106: E8F8F41528D4F855D8FDF4055BBABE2F +107: CACF3D3D1E7D21C97D265F64D9864B75 +108: 6BF48F161EFF9F7005BD6667F30A5C27 +109: 42E7BB8E780B3B26616ECBCACE81FA1A +110: 225AFD8EC21F86F66211ADF54AFC2E86 +111: 4FAD3AB7D8546851EC1BB63EA7E6F5A8 +112: D1FEC2AC3715E791CA5F489F300381B3 +113: F62807C995735B44699BB8179100CE87 +114: 54050B090344E3284F390806FF716371 +115: 50482241280543B88F7AF3FC13D65C65 +116: 4C36F27D4786FE2FB8CAAC690B6D62F7 +117: 5A0EDF0B97977EE5AFB3D185B64FB610 +118: 4541055C6675B614D27C537C3BB15675 +119: 1C772251899A7FF007400B888D6B2042 +120: B7BA1EFC6022E9ED272F00B8831E26E6 +121: B0B2D719A838DB877B6D6571A39A1CDC +122: 800AA956EC16F603ECDBA66C2DC6E4CF +123: 8827D2778287C58A242ACD4C549BEB31 +124: CFBC5AA0B61103C1A982D8927B26F575 +125: A1F5B691F74F566A2BE1765731084F8A +126: 80749BE03F5724FA4CA0AEF8909379B7 +127: 8402B21E7BC7906493BAE0DAC017F1F9 +128: 37EFF01866BA3F538421B30B7CBEFCAC + +Hash: sha1 + 0: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 + 1: 5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F + 2: 3F29546453678B855931C174A97D6C0894B8F546 + 3: 0C7A623FD2BBC05B06423BE359E4021D36E721AD + 4: A02A05B025B928C039CF1AE7E8EE04E7C190C0DB + 5: 1CF251472D59F8FADEB3AB258E90999D8491BE19 + 6: 868460D98D09D8BBB93D7B6CDD15CC7FBEC676B9 + 7: 6DC86F11B8CDBE879BF8BA3832499C2F93C729BA + 8: 67423EBFA8454F19AC6F4686D6C0DC731A3DDD6B + 9: 63BF60C7105A07A2B125BBF89E61ABDABC6978C2 + 10: 494179714A6CD627239DFEDEDF2DE9EF994CAF03 + 11: 2C7E7C384F7829694282B1E3A6216DEF8082D055 + 12: CFF9611CB9AA422A16D9BEEE3A75319CE5395912 + 13: E51F9799C4A21BBA255CF473BAF95A89E1B86180 + 14: F741644BA6E1BCF5FEE6D3C1B6177B78468ECE99 + 15: FB1D9241F67827CE6DD7AC55F1E3C4E4F50CAA03 + 16: 56178B86A57FAC22899A9964185C2CC96E7DA589 + 17: 0A0315EC7B1E22A79FC862EDF79BDA2FC01669E3 + 18: 32AF8A619C2566222BB0BA0689DABCC480C381D5 + 19: D35B5AFBC48A696897C084E6E71AAE67C7CD9417 + 20: 602C63D2F3D13CA3206CDF204CDE24E7D8F4266C + 21: A3C6FBE5C13E8B41FADC204C0CF26F3F214189F4 + 22: 25E480E9E0CA2B610105CD1424B8A35F63FB3981 + 23: 45412D51D3CA7BCF452D1612720EE88F9D2427C3 + 24: ED6A95036E3E046931597A457DB7A78B7309C4C0 + 25: B4FE0256D346700783420E08A4A6F7992B1E36C9 + 26: 33E1799E98280E5A9ACE5509477A2048607C5537 + 27: CF193837F6DE43F8E38000ACFCF764FA8D8FDE22 + 28: 7C8DE247DDA83599AF2EC2EE2D29E20583DAC34B + 29: F38A076F70613FC251C4D21E6435AD08341A8A99 + 30: DCD68E6174BD74BA180DA047A7345E8D111F85FD + 31: 43BBACB5F62A0482CBDB564171B04365CA6E27C0 + 32: AE5BD8EFEA5322C4D9986D06680A781392F9A642 + 33: EB90BCE364635C4C23B49F493F0043579BC85C17 + 34: 2942C7AFA65444C43D0592D0DC73CA71DB729205 + 35: ABF726F5FDA729FB7F3F0484D7C94B3107AA02AE + 36: 75DB4F6BCC05A781DDA9D17C46717286DD53654B + 37: A82CB42D89DAF5FBC1D4A48476229C495782F98D + 38: FC1A69683744AF823CD69E8A1E3F460591714028 + 39: DC68DB44B48521B0700A864896A00E17777AEA83 + 40: CC9AD99E917042381B0F99588896CBF236AA8ED3 + 41: EC7A68484A749C7065C6B746F9C465DCB414F370 + 42: C627C449DEFF14AE7ED807293D30846F061DA5B8 + 43: 4782F2A19B6DBB0882D656DE86C3D21A7317F768 + 44: 02D4EED99E7307BEA39AF5330BF7FB388D48B496 + 45: B3D99B9D90A69E50FD4365704F5AB2EAB7BC9763 + 46: 9B1C07176BB227F73E8A4E173071D39302061DE2 + 47: D79097DDAC552A6E02A52CE7AAF494D2D73B2557 + 48: DF7F23B160E75B9BAE5EA1E62B43A5A34A260127 + 49: F598F3780D8C374D97957B9B62D56106E9E0B2D2 + 50: 0BD98598F9AB29C1359EF5460A206DD1370515E3 + 51: E6C320834F69D81689E1ECD5ABC808D49D9C4E07 + 52: FD5EE7588CD129E12B886974621FD29FACC78E19 + 53: 2A9C28EF61EB536D3BBDA64AD95A132554BE3D6B + 54: CFAE6D86A767B9C700B5081A54265FB2FE0F6FD9 + 55: 8AE2D46729CFE68FF927AF5EEC9C7D1B66D65AC2 + 56: 636E2EC698DAC903498E648BD2F3AF641D3C88CB + 57: 7CB1330F35244B57437539253304EA78A6B7C443 + 58: 2E780486F64BC91FBFA2785EC1CA5C9E3CC07939 + 59: 4A7713D44E97D9F09AE1D786199C58AE2BFAF3EB + 60: C98714B16F92C8A770E9FC229DF834D1688E282F + 61: AACE3DD6F54A2A255ABA920F5FFC8CF04B85A69A + 62: CF8563896A3B0A0775985D8289444C4BBC478DA7 + 63: 6D942DA0C4392B123528F2905C713A3CE28364BD + 64: C6138D514FFA2135BFCE0ED0B8FAC65669917EC7 + 65: 69BD728AD6E13CD76FF19751FDE427B00E395746 + 66: CE705B7C60D46E7E36FE073DB8822698579CA410 + 67: C717EBBF6A2BF1BB33DA6257352D5085BEE218B3 + 68: 86151D140AAFC9A4B5877D3FBB49014FE5906E57 + 69: 7446B5A6BBCC58BC9662451A0A747D7D031F9A7D + 70: C24887924F92ADAC5AE367995D12691C662B7362 + 71: 5AF83CFD42D61967778889CA911CFB6C14339BA7 + 72: 587D4F6E6B4E21343423E434679009CBD3D24DCF + 73: AC65DD946C5CC432D4D624CAEB53C7363F96B7AF + 74: FA71E70750674C0F6B4AA19D0BE717B2936C83FD + 75: C9EFE6DD0A019315F73F3962DE38B6C848A1705B + 76: D1D05649B952C8F6EB016BE08FE1544AAC5D5925 + 77: CC3081AC1D695BAE51CFD5B44B9FB3A230733CC3 + 78: EB9DE332558953792687D9A7F598B5D84BF0A46B + 79: 39DE5EFDC92E3D3678F24D2CF545BA4D172D003D + 80: 399DBC9F721E44A992A0DEF42D999B32AF449ADC + 81: 996A2817C8ACBC667E1C4C27B8F4E9952736DD7A + 82: 3EF8189CE1BCC0D65AA182B1A81534635EDFDF2B + 83: D676714C6A6FF4E17A60C0511C25AA8B164FA606 + 84: 4DB6E3381E1B9290267C1539E1053793C8B81FA1 + 85: 3A34D35B0296FE4D83EDA39B742A9D8F4B13A958 + 86: 54F3B45304EF1287F54B877FCCE3285E154F9D6C + 87: B1EA96216E025377AB5AA845238FC8BC65DD60E1 + 88: BC6C7488145485DEDE1AE1D43B594F0046BCDA0F + 89: 3D9A0619ECF88C84CE86213E9AA91D9A252CBC32 + 90: 92CCAA0B4CE89E2BD80A61B9BAFD5AC58AB7B588 + 91: 3EB326B5BF4440FB3A88E3DCB05C1DB5EA01AC5C + 92: 989C63E819B13D4CADFB33F8DEAFBC57C1992A12 + 93: AE944552C20CF16F07A5C357713832C9D72D0C6B + 94: 46723E982569A1E2D9EDCED5498FC1F46F7D63FC + 95: 3BC5DAE7907C83A0693F87FD8372EFDD1DF53E09 + 96: 96D281BA44EB21ECFB1663C8AC5752C48686A927 + 97: FA0EF18178880A72B51C26555C10F5210DAB4390 + 98: 0C7ECAC32B8ED6D9835D381BF069568722A276E1 + 99: 649E44ECBA85C0938EC09229CEE4BB69388EC642 +100: 1E6634BFAEBC0348298105923D0F26E47AA33FF5 +101: AF2AF2734BB2BAA288940CB62109F4849DAA347F +102: 22D14BC045CC9A3794C99BEEE7ABE278BF24D6D8 +103: C3164CCBED75B82ED3F59F4A47FE09B256025549 +104: C27B5BC7CD24DE4913614A769A442E9CC9FB0E08 +105: F44D48D98CAC77522FF6B9E1B9CBB8489E58E588 +106: EA19A71FFBEC9572F6CD65523ACAF865EC05AB52 +107: CDA0EB9D310247BD1E8B3EA10D9B9DEFF6FBABA9 +108: 449DFCE971B9D65D69FBC72940E9A885E8DDE9CE +109: 96EEBB6B95A9DA99C58190CBD77CD6FBCF638A79 +110: 670F7A869E90CE86E0A18232A9D4B1F97C1C77D0 +111: BC544E24573D592290FDAFF8ECF3F7F2B00CD483 +112: E4CE142D09A84A8645338DD6535CBFAAF800D320 +113: 1C26461E26EB697CCC36A98714EE70CAAA87A84E +114: 51C5B1C25A71FF00394A84AB48B5733C8955551E +115: 84803504181C0AE33A511C49AF5015A5B1892BFD +116: 7CC8BCA120C2635ABFEA82DD203112B5C7E165DA +117: 44E2519A529D7261F1BEBEDC8ED95E1182CAE0DC +118: 2A81372DA39C1DF4251539A9922717B7CF5F0334 +119: 41C89D06001BAB4AB78736B44EFE7CE18CE6AE08 +120: D3DBD653BD8597B7475321B60A36891278E6A04A +121: 3723F8AB857804F89F80970E9FC88CF8F890ADC2 +122: D031C9FB7AF0A461241E539E10DB62ED28F7033B +123: E0B550438E794B65D89B9EE5C8F836AE737DECF0 +124: FB3998281C31D1A8EEA2EA737AFFD0B4D6AB6AC2 +125: 7A914D8B86A534581AA71EC61912BA3F5B478698 +126: A271F71547442DEA7B2EDF65CD5FBD5C751710AA +127: 89D7312A903F65CD2B3E34A975E55DBEA9033353 +128: E6434BC401F98603D7EDA504790C98C67385D535 + +Hash: sha224 + 0: D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F + 1: FFF9292B4201617BDC4D3053FCE02734166A683D7D858A7F5F59B073 + 2: 00AC60F30E9BD1956F914C8E5125B69DCC31A179734E6A85B3F702BA + 3: E615202185AABE2ACA924BEC29E5A12384F8339EAE4E64C9CBA9F1DA + 4: D70DA0705EAE42A5C596D92F331DDA2421B4E14F8B3035FB73B8B700 + 5: 98029CB458A39A16355963922D32DACD9439F90E9FD106D42A0D123C + 6: 7D92E7F1CAD1818ED1D13AB41F04EBABFE1FEF6BB4CBEEBAC34C29BC + 7: DDD5BABB1B05D8BCCD644ADC393A9E2303C850DA31922C4DA07574F9 + 8: 4C07070802E21052FB0295AC0571CAEDF219143ADAE0627E2850EDAA + 9: 5D3CA3BFE738D33F841069ADF6DD79B987351CE580ACA23326B3A7E7 + 10: 6B5373C535A4FA5D56D6C4953575CE64968031BB019B909F8F2DB904 + 11: 767D0CDC11079BA8DCA276DF5C4B85507DE67DCE47EDA4CD9196D312 + 12: 02C513977B6242D2FAAC094CAE3C247C6E2745F8A71494A60535A2EA + 13: 1F39482310E2209C10A88C7FD7FC1FD567F36789808C37D30045A82B + 14: 55BA81EBA644183AB2460C234BB95ABDA898E980BA976584E2977231 + 15: 2522E2B35A835436C80A122E4676DE64690C81440D42DBDA40EF2151 + 16: 529D656A8BC413FEF58DA82E1BF0308DCFE0429DCD80687E69C94633 + 17: A153F81C68D9FFFD4DE0AB9111C2FA86E8EDCA9B294376083077A135 + 18: 1EC706AEB2227B263A105EDBE2562E0521C96420DA4558012327661B + 19: 4904ADADF19D088911EE0EFD20A9AB511F2786C8FD43F1E5E8BE2AC6 + 20: 6CE245C296289A32F661986FF1C80E893BBD35EB0B182EDC14AB3A7D + 21: 33831C459A43CBF8BEB6DD50039750F1EA3688A7EAEF68CB2F095E16 + 22: EB4BC2EA1F7146E8274A96E874585C401256FB921FFC7E935DDC7FFF + 23: 09A266C98019B6B2A4318FBEDBEA5481AF01F0AD2AD16F09991A3C3A + 24: 7AF2814CD6105473EE530F2B3DAE992ABB6C801428F33430501F09A6 + 25: C5BD6127243049C4D5E9E3B391E12BDA86DC7A9856910A757004486F + 26: FCA06DDE2DCD212E6C1C11BB22B18B4F5582202655DFB9B6C9960C57 + 27: 0851998120F8CE47482DA5B2EB21BADF73C9F145921EEFD33459D49F + 28: ED36A2092538C5D4769917953E7355A13072DDAD8A6E5E2AF1DE96F6 + 29: 2C4A89C05BFD09B7068BAFDA37B0314EFCE02AFAE1B2C25DCE337326 + 30: 1D552A4D06BB8A0827BFE8DA2B6EE56ADBD17CE4810908D572076F6E + 31: 997D180912E0655445B07259278AAAD424633F5FF6BD0AFECD4F15DA + 32: 71446EA93381BA091F94AFCDC5B938323290A1A027C22A75E88A04D0 + 33: F77087D6F4AE34E88C62597CEC06220F4C694D2E0EB704820035AE6A + 34: 64EE78B0A6C116380A4C16F24489C1E94A578E558453537A9819A2E6 + 35: F39C1C862FDC9AB4ACFA50FE283CB7595C608F8C521BB7898CF71D34 + 36: DB482A26C9488A963359D145914612E34B821CC6CDC11113B73BDE2F + 37: C7C45F3AA5EEDE664D6CCD510F628D4DC3C67F93973FE05B0163CA13 + 38: 7F230E3E597845DB9F8D61B44740968FF55F2DF28CA538A68927F130 + 39: EA52362A9C66B6A5FF3B642FCFEBBF54F793B088D29E6840D7A5CF56 + 40: 84B064EF9C13F1ED54AD0B8FC0CC28F9BCE5009500E1CD92CA2BAE04 + 41: A2702281BD63CA745553CB18693DD70AC9A70CD73C01783727707C97 + 42: 89231FCFFC7022DF20B1846285FAACE44AFCC677685DA55EE02D94EA + 43: 4C5B01C50907D097DDBF0923B885A26B58DFF5761C1AEDFB8D5353F5 + 44: 84E0CF33A7E1C0EAA46F37E99CE5C8B292E81AD61318796D1A9A90C3 + 45: 27E59A0B6E7B9125D4CAA658810AE5054CE40A9A0A0FFE6E36435EBC + 46: C7F21E2B4C89B2A6E64D92F93FC4146EB5886503C1231EE6924B4E13 + 47: 653CAFF50E077A855992990F0C5F89C75FA18D1CC147F685AF2EA993 + 48: 6A7BDEA7E456D5339B7D9C244E246AD65B18BA95E0518E201AAA7889 + 49: 837ADE7F298F8159E6E2408751B0C480648CB6FD6D26C551983F3176 + 50: BEEF3F6AC40A9DED345BE41242BB2CF924B457A45CACC68379B1DC4A + 51: 6D2908EB3B6C8952346E0B65B9406D949B5A340123DB83B151DF5F81 + 52: 9E75A1D6B4A4D1A9F5AA6F8A48AFD6F3FD360D2D8723B53DBB63208E + 53: 436E3BFE94A39359CDF47D35395D34C0435018C88B4E96E68C22645A + 54: C209DF2E99E03D679FBA9E14AAF958AC1B0A22076BB3B532A0D7F092 + 55: 8991DFBA74284E04DC7581C7C3E4068FF6CB7A63733361429834BB56 + 56: 2B2CD637C16AD7290BB067AD7D8FD04E204FA43A84366AFC7130F4EF + 57: E87F5BC938C3B981C197D4B163C635A5049FAC81C4C6467E1251BE48 + 58: FD9BDAF5CC288A603D1623651D5BA3B8801D1602B0B9221C0B48435D + 59: 87F207D9D870EDD7DA61753473A51FC386E2792A3861F949BEA05CFE + 60: C9EFF79F4412CE49296C082DC777118F92C9AC4136D4EB32621E942C + 61: DDBC76D25D9819693F3597D6F09044F8D6CCBD12F081156F1090AF7D + 62: 6411AD13AA3654302BAC8E2BFD1CE76F37E3B3394014BBE260062CFC + 63: 049E8DD7EAB3378CE9F823BFB569E5B270235D4B7F9623606971998F + 64: C37B88A3522DBF7AC30D1C68EA397AC11D4773571AED01DDAB73531E + 65: 114B5FD665736A96585C5D5837D35250AED73C725252CBF7F8B121F6 + 66: 7D9B844CAAC9EC93AE2159ED3D336C55396216DAC6AC5DC5DECC11C9 + 67: E1C799109DEEA117F68DD1826B38B514E1D265F11A8B60B24630FF8E + 68: 029A0D024B6C0B63E1586F3D34111727E37D49CA12E7F520FA91A926 + 69: 2EA94F04A72C770A98E2A495D886EE674B7D0FB987B7B5C2217A8773 + 70: FAF445688FFCA34ED783F948B8F74578503D4845836CAF69DBD5EB51 + 71: 91EC59AC7C98F9DFB869E11C80027F8A4D311324597E6FC6135224D3 + 72: 190DFC9C7BDD954E415E543F99B00B5110ED6A12182BFFDCAA77D8B9 + 73: 8C3AA805FA75625476F3267C211B1DDA52E1810B058EF804E34BEE58 + 74: BFD0E517E4A340A4E0EF1AC306EE2C6DD1288C77531EF0FD5ACB73FA + 75: C621A18D7E09976296CBC39761B020E7E346042FC735FDF106148F3F + 76: 27EE5F7E3FE49EAEC0AE0A93FD971EDF0304A4C0513BCF43424C95A2 + 77: BD9D42F293DA572219F08D4A38081D203E44F612EEDEF93CE0DAF6D4 + 78: 374CFB6FB12768717EFED2681718C11B22588C429DB9C71AFB5EB562 + 79: 1CFB1037FC3943559E9F913183DB71392CD4BC68CDFD47D7DEC9C9AD + 80: 2537E015D5945E0541BC48320AE4DFF7FEAB911227AE0D579DA1CD05 + 81: 012B34E1A530B6889E87863A59645EE4FFEB292A33815D2CE11918EA + 82: 5242DD4DFEE389E668D8FF78DA9B2D85AAE12D0C220E8D1BADBBA845 + 83: 4813D70E1D6BB6232CD9257B5132FDBA05E1A4A858E237C303CFA052 + 84: 0530BBA43AE6393655F21F7EEA67F8E8E819BA225AED78CA8BDE075F + 85: 4F7EAF4A9D0000B0E957DFE46DB304EBB2664A32AF4142EC74BE18D8 + 86: 68CF23B9DC4DC3430835B484648CBF126940AF6BAE51431A66D7F0E6 + 87: A093D2119C7076259F194F107077061C61C792DC5326C3A4D3A63BA6 + 88: F4E883F7FD12ACD36E3891986E4D7FF03F3E150F09CD4FB58A023A04 + 89: 0816862C59CE35E0D78834A221D3BABE21987FDAA81F20ED61D9DA84 + 90: F415933677BB364C589722E30B958F2BEF8670A10F1F5082F79FDB4F + 91: E40C5632490BB8DAD2283B6DBDCA870F4B5AB4271C61127DE999BDF0 + 92: B2D4E6CD7AFC35A475620EA1446B9024D767890B8593AB50275F370D + 93: 948616FD7828F09E8A57F986589948085D18EC3550E0ADA8E0127665 + 94: 2B115E930333A355A82F074EF261DE6BB2942D9DD64F98BA12D92DDE + 95: 6EEAB864B5AD618CDB1AE79C7B1DE31020966A02350AEF71088E6876 + 96: 676AD81F213E037F3C9BA2310F49DDDA4D6476C28A8EFC0046D3F55C + 97: 03A28C9068BC10A6FD87A1E53F00415F8CE994C968DD9CFF60D6B0A2 + 98: 01D91D084F400C591EDD750B66EC2482C834CE0E140A37E6E142CFEC + 99: BCAD899E7C771764CB91FF60AD79BFD629F4803A05FCBCC24E8F3E79 +100: 6E08215B5470DDEB67E44A494E52E259A9C2C4FBED4AF5DC6DB3E92A +101: E5C45BED6F8BFC487FF7190B108AF5C5B66F6D55D365B5A1BA156914 +102: 0DB55D83B38D42D229CA42D001B09758B5F3F032109F2F999C553655 +103: AD4DF1AF973A2747568A1B8DEF15E34A350A93F45BA84596580D11F0 +104: D4905849C8C4EA32159A431B52BAAC092F90037093E200A0C46611F9 +105: A936D0AA091B827BAD86644C94603068AB34A5B59E29D1E3BAB13039 +106: 46D214E9FA8C877C2791CC8E6716868713CB5B677CC4D838242C9B18 +107: AE8D3EB227AA3558101D5E5A2BF6C862C9F7297A31A3DF24E4502257 +108: 4462C366B10326D4FEF46E71930BCF93713F7D45FAC9963520FF5FE8 +109: 05EFC35781E413ECBCC763AE13D5A37C159CE5CCEE6EAA1CFF7CA516 +110: CDDBA09D7FE081E7A39C4017B3EDF7A9138D1CB857559BA9AD2C939E +111: 1AEEF583C448A9AE00FBC931B50BC0DA5BB8323E616B11076CEE8B44 +112: 01E5ABF50619B5C2078E754EDDEDCF4DE8D31185A2219313CB91A8C9 +113: B7FF114CA77757CAD67801E6761AF20F4CBB8328AEF290F77EB612C3 +114: 08F43DF4547732424AC7D0390AD8AB3D4978826462446D13B2B468D6 +115: AC3799ED09E3BD9E770FD3A0073E371FE9A3D4E3D464C3A7023CC72D +116: 795F160C275FF6B575031D4053BA1D1C32744D09F005B3BF10BDD1F7 +117: D2EFD4AC8ABA33151D0399E2893769A6D8BBFBA7B128388BFA65B841 +118: F85910F64FEE2B8F91DEC8064F75CB97E1FFC895AEE912DD3945F839 +119: 762F18C0DF65C3D0EA64126C8A6E51DB4425E76D4D969ED0F83899BE +120: D022DEB78772A77E8B91D68F90CA1F636E8FE047AE219434CED18EEF +121: A802D8B618A503352CDBCC1FBEF04EA36499EA72D0E32D314CAF83E5 +122: 6DE1088DD95C9535849294A8635A44084BA36E4EEF81C6D67B98CE90 +123: 6AA11591302A30EFACF874F40AA017F8545D3D9EA68D479965AC0B3E +124: 3288A475A4817D2E42830C709C1DC18A4BBD59DBD903B43CA702F275 +125: CCEEE7F6EFA60B2F2CE1090FB929D6068F7EE301E7A84072FD163F7E +126: A45B0FCFAC3F05279B7E8278AED93E37B225E6A997664F92C7555447 +127: 554C9C3F7E92B80F4121E00CC147535D377EAEB4FB1FA8E25C7F81C1 +128: 67D88DA33FD632D8742424791DFACE672FF59D597FE38B3F2A998386 + +Hash: sha256 + 0: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 + 1: 6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D + 2: B413F47D13EE2FE6C845B2EE141AF81DE858DF4EC549A58B7970BB96645BC8D2 + 3: AE4B3280E56E2FAF83F414A6E3DABE9D5FBE18976544C05FED121ACCB85B53FC + 4: 054EDEC1D0211F624FED0CBCA9D4F9400B0E491C43742AF2C5B0ABEBF0C990D8 + 5: 08BB5E5D6EAAC1049EDE0893D30ED022B1A4D9B5B48DB414871F51C9CB35283D + 6: 17E88DB187AFD62C16E5DEBF3E6527CD006BC012BC90B51A810CD80C2D511F43 + 7: 57355AC3303C148F11AEF7CB179456B9232CDE33A818DFDA2C2FCB9325749A6B + 8: 8A851FF82EE7048AD09EC3847F1DDF44944104D2CBD17EF4E3DB22C6785A0D45 + 9: F8348E0B1DF00833CBBBD08F07ABDECC10C0EFB78829D7828C62A7F36D0CC549 + 10: 1F825AA2F0020EF7CF91DFA30DA4668D791C5D4824FC8E41354B89EC05795AB3 + 11: 78A6273103D17C39A0B6126E226CEC70E33337F4BC6A38067401B54A33E78EAD + 12: FFF3A9BCDD37363D703C1C4F9512533686157868F0D4F16A0F02D0F1DA24F9A2 + 13: 86EBA947D50C2C01570FE1BB5CA552958DABBDBB59B0657F0F26E21FF011E5C7 + 14: AB107F1BD632D3C3F5C724A99D024F7FAA033F33C07696384B604BFE78AC352D + 15: 7071FC3188FDE7E7E500D4768F1784BEDE1A22E991648DCAB9DC3219ACFF1D4C + 16: BE45CB2605BF36BEBDE684841A28F0FD43C69850A3DCE5FEDBA69928EE3A8991 + 17: 3E5718FEA51A8F3F5BACA61C77AFAB473C1810F8B9DB330273B4011CE92C787E + 18: 7A096CC12702BCFA647EE070D4F3BA4C2D1D715B484B55B825D0EDBA6545803B + 19: 5F9A753613D87B8A17302373C4AEE56FAA310D3B24B6AE1862D673AA22E1790F + 20: E7AEBF577F60412F0312D442C70A1FA6148C090BF5BAB404CAEC29482AE779E8 + 21: 75AEE9DCC9FBE7DDC9394F5BC5D38D9F5AD361F0520F7CEAB59616E38F5950B5 + 22: 22CB4DF00CDDD6067AD5CFA2BBA9857F21A06843E1A6E39AD1A68CB9A45AB8B7 + 23: F6A954A68555187D88CD9A026940D15AB2A7E24C7517D21CEEB028E93C96F318 + 24: 1D64ADD2A6388367C9BC2D1F1B384B069A6EF382CDAAA89771DD103E28613A25 + 25: B729CE724D9A48D3884DBFCBEE1D3793D922B29FA9D639E7290AF4978263772B + 26: B858DA80D8A57DC546905FD147612EBDDD3C9188620405D058F9EE5AB1E6BC52 + 27: D78750726155A89C9131D0ECF2704B973B8710865BF9E831845DE4F2DCBC19DA + 28: DC27F8E8EE2D08A2BCCBB2DBD6C8E07FFBA194101FC3458C34DED55F72C0971A + 29: D09BEA65DFF48928A14B79741DE3274B646F55AC898B71A66FA3EAE2D9FACD77 + 30: F2192584B67DA35DFC26F743E5F53BB0376046F899DC6DABD5E7B541AE86C32F + 31: 4F23C2CA8C5C962E50CD31E221BFB6D0ADCA19111DCA8E0C62598FF146DD19C4 + 32: 630DCD2966C4336691125448BBB25B4FF412A49C732DB2C8ABC1B8581BD710DD + 33: 5D8FCFEFA9AEEB711FB8ED1E4B7D5C8A9BAFA46E8E76E68AA18ADCE5A10DF6AB + 34: 14CDBF171499F86BD18B262243D669067EFBDBB5431A48289CF02F2B5448B3D4 + 35: F12DD12340CB84E4D0D9958D62BE7C59BB8F7243A7420FD043177AC542A26AAA + 36: 5D7E2D9B1DCBC85E7C890036A2CF2F9FE7B66554F2DF08CEC6AA9C0A25C99C21 + 37: F4D285F47A1E4959A445EA6528E5DF3EFAB041FA15AAD94DB1E2600B3F395518 + 38: A2FD0E15D72C9D18F383E40016F9DDC706673C54252084285AAA47A812552577 + 39: 4ABA23AEA5E2A91B7807CF3026CDD10A1C38533CE55332683D4CCB88456E0703 + 40: 5FAA4EEC3611556812C2D74B437C8C49ADD3F910F10063D801441F7D75CD5E3B + 41: 753629A6117F5A25D338DFF10F4DD3D07E63EECC2EAF8EABE773F6399706FE67 + 42: 40A1ED73B46030C8D7E88682078C5AB1AE5A2E524E066E8C8743C484DE0E21E5 + 43: C033843682818C475E187D260D5E2EDF0469862DFA3BB0C116F6816A29EDBF60 + 44: 17619EC4250EF65F083E2314EF30AF796B6F1198D0FDDFBB0F272930BF9BB991 + 45: A8E960C769A9508D098451E3D74DD5A2AC6C861EB0341AE94E9FC273597278C9 + 46: 8EBFEB2E3A159E9F39AD7CC040E6678DADE70D4F59A67D529FA76AF301AB2946 + 47: EF8A7781A95C32FA02EBF511EDA3DC6E273BE59CB0F9E20A4F84D54F41427791 + 48: 4DBDC2B2B62CB00749785BC84202236DBC3777D74660611B8E58812F0CFDE6C3 + 49: 7509FE148E2C426ED16C990F22FE8116905C82C561756E723F63223ACE0E147E + 50: A622E13829E488422EE72A5FC92CB11D25C3D0F185A1384B8138DF5074C983BF + 51: 3309847CEE454B4F99DCFE8FDC5511A7BA168CE0B6E5684EF73F9030D009B8B5 + 52: C4C6540A15FC140A784056FE6D9E13566FB614ECB2D9AC0331E264C386442ACD + 53: 90962CC12AE9CDAE32D7C33C4B93194B11FAC835942EE41B98770C6141C66795 + 54: 675F28ACC0B90A72D1C3A570FE83AC565555DB358CF01826DC8EEFB2BF7CA0F3 + 55: 463EB28E72F82E0A96C0A4CC53690C571281131F672AA229E0D45AE59B598B59 + 56: DA2AE4D6B36748F2A318F23E7AB1DFDF45ACDC9D049BD80E59DE82A60895F562 + 57: 2FE741AF801CC238602AC0EC6A7B0C3A8A87C7FC7D7F02A3FE03D1C12EAC4D8F + 58: E03B18640C635B338A92B82CCE4FF072F9F1ABA9AC5261EE1340F592F35C0499 + 59: BD2DE8F5DD15C73F68DFD26A614080C2E323B2B51B1B5ED9D7933E535D223BDA + 60: 0DDDE28E40838EF6F9853E887F597D6ADB5F40EB35D5763C52E1E64D8BA3BFFF + 61: 4B5C2783C91CECCB7C839213BCBB6A902D7FE8C2EC866877A51F433EA17F3E85 + 62: C89DA82CBCD76DDF220E4E9091019B9866FFDA72BEE30DE1EFFE6C99701A2221 + 63: 29AF2686FD53374A36B0846694CC342177E428D1647515F078784D69CDB9E488 + 64: FDEAB9ACF3710362BD2658CDC9A29E8F9C757FCF9811603A8C447CD1D9151108 + 65: 4BFD2C8B6F1EEC7A2AFEB48B934EE4B2694182027E6D0FC075074F2FABB31781 + 66: B6DFD259F6E0D07DEB658A88148F8253F9BBBB74DDD6DB3EDBE159A56BC35073 + 67: 8FA5913B62847D42BB4B464E00A72C612D2AB0DF2AF0B9A96AF8D323FA509077 + 68: 7DED979C0153EBB9EF28A15A314D0B27B41C4F8EED700B54974B48EB3ECAF91C + 69: 1CF3AA651DCF35DBFE296E770AD7EBC4E00BCCCD0224DB296183DC952D0008C9 + 70: 5767D69A906D4860DB9079EB7E90AB4A543E5CB032FCE846554AEF6CEB600E1D + 71: 8189E3D54767D51E8D1942659A9E2905F9EC3AE72860C16A66E75B8CC9BD2087 + 72: 107DE2BC788E11029F7851F8E1B0B5AFB4E34379C709FC840689EBD3D1F51B5B + 73: 169F6F093A9BE82FEBE1A6A4471425697EC25D5040B472C5B1822AEEA2625988 + 74: 2087EBD358AE3EA2A092FC19C2DFEE57C5F0860296BC7B057C14E1227C5CB9D1 + 75: 182AB56F7739E43CEE0B9BA1E92C4B2A81B088705516A5243910159744F21BE9 + 76: 081F6C68899A48A1BE455A55416104921D2FE4BDAE696F4B72F9D9626A47915E + 77: 5CE02376CC256861B78F87E34783814BA1AEC6D09AB500D579ED8EE95C8AFCC8 + 78: B93E407404E3E95F20FD647365E0E7F46AFABE9AF1FF083AF996135E00D54009 + 79: E81FA832B37BE8ED8F79DA29987AA4D61310DCB14B2859DEDF8FB1DAA2541FD3 + 80: C56705FEA5B110B8DC63688533CED21167E628017387C885423B835A55EDD5EF + 81: C2226285D08A245A17058ED2D24AD095B714F608AE364FDDF119E0A7DF890540 + 82: F9C270DA8793221A6809AC685FDD4F5387E0FE1EE6AAF01C74F1E0A719621614 + 83: E69BEFD6EF7F685C36E343AC1702D87AD6A0E4AC8C0D5C521D04AAD4EF0B7458 + 84: 4E3033562AD74A7D43EB5FF5FC2382622C6307CB10E245AD62DA77C4C63CB178 + 85: 2EA17629472564A59E5EB845A2CDD04F442DF2FF26BCC866E400F77158D612A1 + 86: B90223DF74DD49A8A1461F340F2D7A90F96903CCBB5BC3C74EA3658FC8948B20 + 87: E0209F42B927EC9C0F6D6A76007ED540E9BDD6E427B3368A1EA6C5E7565972DD + 88: 10D9BD424114319C0999ADF6288F74060CD8918EF1228827A6269B2BF0F0880C + 89: 7D1978A65AC94DBBCDC62E3D81850299FE157DD9B7BD9E01B170156210D2815A + 90: E052DFF9E1C94AAA49556F86FAD55029A4875839FDA57F5005F4C4403876B256 + 91: 58D29459B2130A2E151252D408B95E6DAC424C564062EB911CC76440CB926CA0 + 92: 4E4530C392316F598E1BD07F32166380A8F712A33A48E9EB4247131EC5DC05D3 + 93: A09C9D3E42342C7DEA44EDB4AEB48CF6727CACD8032A12CF77A25829FC249D32 + 94: EB978D0F1AC03CE5C3510B5F4A16073A7A2BDC15C4AB7777DCF01030CC316667 + 95: 7D1905A3ACE827EA1AC51C4FA08C281ED3BE87E7F4E928D696BFDE35C8F2DC0F + 96: 08359B108FA567F5DCF319FA3434DA6ABBC1D595F426372666447F09CC5A87DC + 97: A7B3830FFAB0F2BBABBEF6DF0B169A7917008BF238880BBF8C20B8E000077312 + 98: B4F5D9B1555994C5EBAEBD82918D560A3BF82962A171A1614E7551939E943366 + 99: 014ECAEA1B378900F1212898C6DDB01565D81AF1D0EF78DF5E28D46E9CAF7CFC +100: BCE0AFF19CF5AA6A7469A30D61D04E4376E4BBF6381052EE9E7F33925C954D52 +101: 4565D7B898CCEA3139AD260F9273115F806B30079D7683218C4E3ECD43AF3B33 +102: DDADEB660FE8902C9FB2DB9B6CF237C9CE5B31753398085C4367EB5910B9CC13 +103: C15A8928131F6687DD10F3C115DDF8D7C8F2DF7E18D12C08C4FD16F666CE60BA +104: AE8E3D799B1353A39815F90ECEEBEFA265CC448FE39FAF2008CB20784CB2DF9F +105: 98545371A3D9981ABE5AB4A32A1D7B2FADD9801D89DA52A94A4F78A42740D21C +106: 6323DCE2F8B3A04DCEA8D205602348C40403CB200C677EB1A1C0FE37EDB6EB2F +107: 8150F7C5DA910D709FF02DDF85DD293C6A2672633DE8CDA30F2E0AA58B14B0C4 +108: 44D21DB70716BD7644CB0D819FA6791805EBC526EA32996A60E41DC753FCFAFC +109: B9B7C375CCA45DB19466EBD0FE7C9E147948CC42C1C90F0579728CFB2651956D +110: A47A551B01E55AAAA015531A4FA26A666F1EBD4BA4573898DE712B8B5E0CA7E9 +111: 60780E9451BDC43CF4530FFC95CBB0C4EB24DAE2C39F55F334D679E076C08065 +112: 09373F127D34E61DBBAA8BC4499C87074F2DDB10E1B465F506D7D70A15011979 +113: 13AAA9B5FB739CDB0E2AF99D9AC0A409390ADC4D1CB9B41F1EF94F8552060E92 +114: 5B0A32F1219524F5D72B00BA1A1B1C09A05FF10C83BB7A86042E42988F2AFC06 +115: 32796A0A246EA67EB785EDA2E045192B9D6E40B9FE2047B21EF0CEE929039651 +116: DA9AB8930992A9F65ECCEC4C310882CAB428A708E6C899181046A8C73AF00855 +117: 9C94557382C966753C8CAB0957EAEDBE1D737B5FCB35C56C220DDD36F8A2D351 +118: D32AB00929CB935B79D44E74C5A745DB460FF794DEA3B79BE40C1CC5CF5388EF +119: DA18797ED7C3A777F0847F429724A2D8CD5138E6ED2895C3FA1A6D39D18F7EC6 +120: F52B23DB1FBB6DED89EF42A23CE0C8922C45F25C50B568A93BF1C075420BBB7C +121: 335A461692B30BBA1D647CC71604E88E676C90E4C22455D0B8C83F4BD7C8AC9B +122: 3D08C4D7BDDA7EC922B0741DF357DE46E7BD102F9AB7A5C67624AB58DA6D9D75 +123: CC63BE92E3A900CD067DA89473B61B40579B54EF54F8305C2FFCC893743792E9 +124: 865447FC4FAE01471F2FC973BFB448DE00217521EF02E3214D5177EA89C3EF31 +125: 3DAA582F9563601E290F3CD6D304BFF7E25A9EE42A34FFBAC5CF2BF40134E0D4 +126: 5DDA7CB7C2282A55676F8AD5C448092F4A9EBD65338B07ED224FCD7B6C73F5EF +127: 92CA0FA6651EE2F97B884B7246A562FA71250FEDEFE5EBF270D31C546BFEA976 +128: 471FB943AA23C511F6F72F8D1652D9C880CFA392AD80503120547703E56A2BE5 + +Hash: sha384 + 0: 38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B + 1: BEC021B4F368E3069134E012C2B4307083D3A9BDD206E24E5F0D86E13D6636655933EC2B413465966817A9C208A11717 + 2: 5D13BB39A64C4EE16E0E8D2E1C13EC4731FF1AC69652C072D0CDC355EB9E0EC41B08AEF3DD6FE0541E9FA9E3DCC80F7B + 3: 4F895854C1A4FC5AA2E0456EAF8D0ECAA70C196BD901153861D76B8FA3CD95CEEA29EAB6A279F8B08437703CE0B4B91A + 4: 80AE432E757826025095CA1FA4F89C06C8BA6754B1D883A8E31A1E65FCFB820BD74ACFACA3D939A574EA408A74162D1D + 5: 561C16404A1B592406301780C0C2DF6AA0555F504F35BFBEAC810AE36A343B776858C5E0DE56BB79607A34D2F67108F2 + 6: 79F4738706FCE9650AC60266675C3CD07298B09923850D525604D040E6E448ADC7DC22780D7E1B95BFEAA86A678E4552 + 7: E6CE1896C9783A70AC4C90276CC37B37687D7E30C753975762F961AE37118D9A610242716E8359EFC4975AA98C632DCF + 8: CFB18F81F4BB672B03214F1FEDE456F882A0DE40120212A1FEBA8FDC48F763C86ACBBFB684D34B70F99F4D8D81FE3A28 + 9: D075AE1178210804635AC02C656309311527FC8190835C8AD8196577C3332AF4D87F056023F235DB893C69AA87B0CFB9 + 10: 182E95266ADFF49059E706C61483478FE0688150C8D08B95FAB5CFDE961F12D903AAF44104AF4CE72BA6A4BF20302B2E + 11: 89BFCF569AE4AF718510DA78C67414109F5739BB5C40D51C9C8C50E2B2CEE86F2F80C8B9D68F7C01201A0714572FE602 + 12: B635441A3721CF190B39D23703C5B77018FF1A56C94F8252EE95C217E3477F093E8EC65C6AE767179A7872C8DB9B2141 + 13: 48DEBF56626CC86DFA47AD6FDEC73FD182434621DA8BC6DB23AFF067BC36DC8244D3071B1F57DE4B716F63D9820DFB23 + 14: 58475B7CF93FECCB2C02B588F1552A359E7EE9AC45D9AE50B2D7C22021466677D70EF24EFA5C492515164458E9A24744 + 15: 0AA75534F0F58756A01E3366F78E7611BC7F432364C649C3F50547F7BCA3E5489531B8AB129495FEAC834FF0A0B45DB6 + 16: C81DF98D9E6DE9B858A1E6EBA0F1A3A399D98C441E67E1062601806485BB89125EFD54CC78DF5FBCEABC93CD7C7BA13B + 17: FDD3C4C0F87EEC0CADD73028A06B01E67696C7E04960936B30C73F004CF6B595D644533F8B473C8E63B02D593A64B041 + 18: 445E4CCA1A03480D149F38014C14D28DF8288F2C6CFF047F45D4F2580AE85EFFB3BE009C9D2ACC54B51467F83A09FBE2 + 19: 8305DC56172245B82AEDCE7F9C7DC88C0E62CBF835A2AA133EB579F415FFD15BABBC30BB98E55DFDA0F9E80275C92BC4 + 20: 8A48240E1C85E80651EDDC88599273444839A952CACA2BEF4400576E65B1EB6C19C47A3067B63AF7CDC4238ADB9A8DAD + 21: 8F2F7669C27A7CB1CF7A84A2C4F050D7141852D8B429291956B85E2DB5287741A3104E7E99CA5D23A5EEA59A68A4DDB1 + 22: 32CF04AE2A4A326FDE2FBB887F47FB7A2C486E56088D85B45F0C7587591F44797FE0A67E36F571809695E05F254884B2 + 23: 713A04A3A6BA8D2FD821F1CDF9FACAF42795E4247C9A26F0ADC5E0E6AACBAFFD8F4E02563733C6BDF1A863A787949B35 + 24: 35D8A5AA0DC9AB4C9A4C62B36E0E1013977C198B05CF6B92CEA25C08309DAFD282AA9A4862958593C06BA46919EA8019 + 25: D3FB60C2E981A5C82F1B1BCB3D4D7AF62C9A32A9F0D87E0532C9D3AAC083D70133EFF63A1E2CCB87360BF032C25FE9E1 + 26: B119F9AC74E58BD081E24C0CC1E090012C192996EED67A8ECA33794FE7E1920E26C0EFAEB866EB5AB82FCA3188A3B05A + 27: 5B29543AB0F76F246B7FDE6E8E5D3DF6017A39342BB08351A4EF609AE00A91ACB7C5D0487B3760B34CEF326F63C84572 + 28: F8E1FAA657BF829C9D2E4811805238CCCD11F0C1AB7619058241BA5606E7BD5E4816163E6E8E82E62A43CB4943A41006 + 29: 0855B919786B5E5C87B85A6C17A46C550B2BA81B3724389088E2B54BA89D82B8F9841FF442DA5DB8D54C9B2AC108DC3C + 30: 7DEF8CAB7C80CEF90FB38989ABEF6F1A5EC18379681E484A1B4DB6624818D2E486FB9C245C1F0DDD85A846D4268344B1 + 31: 04AAA180C2CD24F0FB150B1AA360F445344150DCA13E1ABB8117D42E25DF7FE29246D9F00C7473D20CEC32A71E64E1F5 + 32: E7112491FAEEFD57786DA73F367B25A6F5769F5C98FA7B704D8D37747724A647371989E8B0FE8D3CB23F9EEDD528456B + 33: EA27126D0B96E00E428943EA94F4B03FD22D56C4FF4636EED139D027E6D45EF57AB86093A7342B3B3851FD3BFD1DDA23 + 34: B2BD337A4BDD48D25A5E3FCE3E0948EC67829B835A8E3DD0D9F4881D10C766369B079028C6060B7263603288D8FA4BBA + 35: A9E940504AE6B137BB1BC88CE3A9AE53DCB63AFDFE5FA0C652003A921F582C08662425C7FBD5B1E1422E39E645D4A757 + 36: F033150D7464D49A076C7D4BB9E2A5488132786CB4851A4C81DA5B0FCE66D775D3C1766094AD6CA9482DD9539F28ED9A + 37: E64D999E7258ABBB4CFF6F74AF7D6A1E9B044C17E1ACE0FC61B29E7732763755A9C1D3A380B080AD968D2228DB731DE7 + 38: 9030D47B57ABEA93B51162556FF352DA61FDF501132A9FD94E6CB56690E7A805CDB290FB4ADE36BF90A53F20922C9B6E + 39: 4473396BB0461EDB4712880810A3F7252725AD4FD6092021A40559F453A1C63ACFFA8A02C85CC8DB86560323DA0A0FD9 + 40: 095FDD130278B3C8F574D17283611E4D6199EA63A0F1599E01ED070CD0B115296FE353477582BF279D622355C89A23E4 + 41: 7EE600CEE8437531C6A5BEC313D53371F9B56425D5662C104624D83D51111E5C9F4B83000B8A3EF150E04AEDCF67C237 + 42: 676D2BD2500BC527DCB51968FE8742E40D2965047478E69155AAB9201E0C9B0F6BA9BE85C4734B0DD556B5FA7608BE83 + 43: 09F5FE433D1FB8F62A76E5654B54CB6A9EF505D2465A49DCB9669EAC9A30B2532505E4500F842EC9FBE79A382C8C2F4D + 44: 075821CA8C547E66AD94F4C4ADF866A2A7554E08D2B0F0B3576801773EDC85DF76107E6912904E9757EBA753A77CD0FF + 45: 2172C22E7E48BD0B4A73FF02803D6FCE776CECBD95DFC43CA0763A0B375D57030000B12E59F9CDE81DE58E17489B2C41 + 46: B9A15689BA4F41BE46855775B46A5DB9D6826E0CBDBC3B292DA6D57B2A179A3D393A8E1B55DE79438E5221580C604EAD + 47: EBFA57C946831E2E370A6B1BE46E27C95C512297499B8BD15722622178E00599DEEADD48F1B4B08EB649A137805CB786 + 48: 25866C8288F9FA319FA9AA2470B4FC2595DFFA9154E607444EA3247E81D74A2AE0957D6B7E050F8C96AA7577BEDCABB5 + 49: 3D28682B90022C873CEC78C3A47FD45B5124E49ED07E2F0FB41A112A63AACC9E7614ADBB007D129C0673B08C51210839 + 50: F76D9B7ED868085905AE806CFC5C6DE994999E379922AC003D53F00B65467AACEF3929392F1F2F56C621D2F552544A22 + 51: 324951FA2432B63D1765C21F98325BC4AE2FFB25F411047C53ED5A3D550B50E2B8F6E79BBE65F2C686A5132E5B982AC7 + 52: 320CB033AD533AF8EDB3E664E34BB85B2327AFCFC583CE9202C0B11F16425A58FD895D7435E8953F9506A25DE7BE6EF3 + 53: 6065D55530ED8339B09D7A4D9CB1919004F69ED9D6B119E78E1C39C7AD2AAC029A3F266F7E48350966B845C4D7D92A72 + 54: EB6E866BDC0B5089301D89B870B75056ABA6D5FA6C7406A8D6D97CE5175102479647D3F93325A2CB648A3F40CCE38542 + 55: DCEDB6B590EDB4EFA849C801E6B6490657A5C1E64F69269F5F63C9267F6223DE24CEA7AAA6B267D9BCECC15147B6C875 + 56: 7B9132D597B8873AD55BBC30F18ED3F2C9F340E7DE69FB5774056C71A06D9BC2B14137E9E1C68B6B645FED28B188249D + 57: 0901B1E5B13FCE000486BDA64FBE45C79FCE15F38A4DDD9335A521D98829D267ABCCD84284BEF1EA3C2D4E4687C6D3B8 + 58: 4A9375DBAA878E2C1C7BFB977989E6D39CC00F890ADC425F7084AE3761BAEFCB9384C8B9EB3ADD4C3C838A6D560DF788 + 59: 908682C3E0D97A4943063EA9DD0A0F55EFCA203ACA3004010D3D7EF94593592729B523EAAE4160C3EA2241EBA236FD65 + 60: 24586F75A43A08D6CF116B87B86CC43300FC4132523CC4824B7FBB3F54A5B41C7D598B40639B25A99732D575A5CFD355 + 61: 7B4CFB73E247E941570E70C7308ACC5166F123187F003B1CAA9BCD17DDA8ED5535ACAE443C9ADE93C5567090EACE29AA + 62: E97EF4578822DDC79AF60514A188F8C719E4133B58E5EB134261AA7E89C402EA7219129A06B395E5E1D2738AC23FC876 + 63: DD66B519F51A925814407A449C60B34C553D7652D41783EE903A810A4C9F833B8181C91C7F12283EACD6A5F8A2639DDF + 64: 9F2C9EB7116B3D7A4BA84A74A4D4EFF8A5EFCF54B6D7B662693C38577914C73A214766F0A175339BB0895A863824FC0A + 65: 14B0A9FFCE149426BF5045FFC24C057451D2473186DEB4F150117B855911A7641651FB1E15DF406EB373D71151C46F25 + 66: 286505FF7A9EF81224988A8FF1E423A2AD21F6B339E91B89F7F1540F14CC9A603952564539167465CA70FF0B523BECF9 + 67: 8CAB08A79BA16F3D7CBEB942C7D8676F8D0295B5FAA01F3C850DC4B5FE913AF00F2E938BE0B442187B135BEF1A36C34C + 68: 4D12FFBCE2E770ECA1104BD2F29C65FE95534E390A138C30CB0ECB6436A971116D82C6321D2EA2C0A735AF34E5E3E3B2 + 69: F8617A35FE9116A719441F82F21C79B8868E5FFFC2EA737FDC821246DB7610E9868D870575F19B29F2FD259D9242A497 + 70: 932FC435B590B1E1D49C34EB3B627DAD5476216518250B1FBFE772476437872B8DA6CAF6D2F33CE7AF8648D956CF717F + 71: 3F63DF48C2D87CEB2168BEFBF6B857A415D8BFB7062251E8E1AB0487483EEBDE5E8E8B8B0E3AD81ED4AB15E81FD5E448 + 72: 4A71E4E737DE74F78E72ECB9DDB580EA5AC96E5BBD5E52E11D4A41AB3B8303E3AF3458A8AD89B39CD9F4A6D5DB3C9E2A + 73: CAC3A81A98103BBF08C440F6C8F61AC010DF8AC05FDA77E2ED8660AB73A978B9428BA0458A5C64DFCE35D87F0DAA2A6F + 74: 6E5D162C60A451B6257781FA0E36B3BDD9BC42A7BCFEAEB75C18E541A4DE00967E6BF575CB32374C1E9FE7B36D92048B + 75: 04DDFD71893D0F4AD2A0B672A057ED2795D6811AEAFDB7136BC8C20A55DABB3AE4B62B8A2C722C1F53E18FFA5771610F + 76: 555D5B51C2EA17659516A67D31CE2CB302979F80BD7056908C1A152403FD902EAEBABDD066AB3F7834E7213A6CE99EEB + 77: 44797CE4FEC66B26B52A4249C2B267AF891C912E55221EDB6CAFC4E2F022A40E8231931DF0B19321D5CCB2AB8A4F256A + 78: 51D7AC85289FE7E4D9431414B2BF3760BE65FEDD1A0B34BED0E1562A73495EE10971B5141835DB454C865039154BEA15 + 79: 2E31DAE50A484B7E11E2E621D0552803791E07279752E09EDF4C884EF24C79C33D9572AE0DE6E0B6A20271F1F7AB98FF + 80: DDC65ED22CAE4D159D35E129A1602D8FA50D7AA53E209B0D5442BB121DB0D5D102441054B2B321675F3722669FECD06E + 81: 200E0BC495311E2FE524A1579490D843011A592E4E9B927DEB0727E5481898C557CB2941F18AF0F2725A1B19DE045BA5 + 82: 561E1875B31DEAEC4DB2FF5BFA7856A6F0ABE1294CDCCA1DA12CCB1786D9556881A768ABAE50F7243921ACF993AAF18C + 83: F6B88007732D5B9F75209F9FE107B9917010D5960184FD239854AB4611CC788D1455B113A5565A87326B3CE6CA190DB8 + 84: B4E703169169B07AC61E76A75ED4AACEE4115F6A43842BF136B514824A05F5C5ADB68F2E525D8C9E8BDB20D3BCA21155 + 85: F72E2083B296EB7468C97749D3AA1B08F418EBCD9A2E5CB4117C5A034BBEA5E2004EE1E43E26A98E4F25AD4306AF3A57 + 86: B1DE9ED0D5E5F7FDCDF530041D7320CA7376A64590F6679971F84061C42AA03F0B07C7EBCB806EC8380D9FF0E182293F + 87: 30ACC02AECEA9B91F3C6BB0F4CA8EEA1B84A0BA6BBB8F7749FD29C9BE5C5E28AFAE5A33617DFE3FC28CE3A78D1A19CDD + 88: 5B2DABAF662B86DC4B1DF6A2EBDEB5CFF1F63C65ACE5E1237DB507DD3FA2C27FF46517B0FCD6F32F25DCD55ACDC07FA0 + 89: 33BE80B29355AB16AA0F05A45A8DC15A5EF7F9FEE60BCBE05E106BF6FA0F196BFD9CBB8D79298360F760DA7B05135F83 + 90: 048C648A525FAB61CF81E087047044130E407B71DDD27293119689C8516B19DDC4F276E3B4E93E6AB80A79BB2700DE68 + 91: BF18EA9E00E6C2262D802FB66E04FFA21DC5C13640BBF27B2C22592DE4AFE31C18147E6EBD2D45669C36F9432494A000 + 92: 0A1A114981A785C399E2B21871A532B2A747FC67B4DAA287C14F2F449FC6F7C6925DB5E884E6E041D08BF6BC69295124 + 93: AC6705C373300FCC09A291CFF1834401FC30FAD512569848A05171AA02426B7034EA2E4777AAC2DDFF48089226A4884C + 94: B7B08352FF8988C0FFE3FE0E27278F068BDC88AECBA8D7ACD8919850D7400A2C0A0A8519B264F61102290C9AAAD3C2DD + 95: 8F78C56A93B3DC69ECC5827F8D591195FB683A9951175754926A8E19F81FF859DC1904DE12BC8482A760E998552D28E6 + 96: E606004ECDC6878B5EC15F4554017CCF962E92CC6EAEBE4997BA34EC0E53C67D564C8461C013701A401FE347EC0F721E + 97: AB7D7116F436ECB13ED2EC42347DDF902E0FD766EA8978CF93625F56B2164E2E630D6383EB03602A8DF27F28F580E3C7 + 98: D716BE6974E46F19A606486BE576AC6E250AAE6AC2ACE7CA9A924C874790E6B4C94670FD884A6EF770EC5E5F3F264306 + 99: 746EEE51375E6695BC4B66190172DC6E86C18E144267C7B0133D6C2ECE05F75B862E4C4EA5F813DD927D60C46E2C554F +100: 3D20E33BA4D52A8C374878F1A624A907132264D0C831C64FC51ED8E1CDB75D11C3FC78D4C3CFBF99D7F0BEA9829B725C +101: FE6A6EBBE30EEA13CE04B1C8FA4199331B77566D2AF420D4EACEDCF22C23B3D7AD2313175389A0765AD60A79C0AA85C4 +102: 1806469C58C028D7FBE80F219DD45333D440A824032778DEFC0A89CF704D40745F0F449F7DF82D228E1718391C85F318 +103: 20CD15E37F6371020B78579210FFD7756B42BD01EB829C1320C59AC382781AC4224439F1F820E215EE907091EE4F028B +104: 7967636E73E440EF1F8751441ADE0F4D169167AC270949A758FE0FFE0B90C2773435623160E4BEA5F23DBE0678E95ED2 +105: 754F6D73A11693E07A2E5F05FBE13514C52F04F904131E0544202354D30917C333DC649FF7C33557005BB19B64DB777D +106: 358D83F883166A6D2972C63F2A46EF893D2FF0F577A53830B3B8E2CB28D1EFE8405084C145EE4E0BEE5DFA9AEF739263 +107: D74B6FD707BCEC9419F032A9C21A7C79CD38F42D564057CDB956485FC5C2ACAECE9D86BE8E12B9181018EA7871343147 +108: A517359A64226F2D08B65203593F3427DD42852476A7609C7F6423C304FBA6EA83981470B8CF171F71BF02F688BB2448 +109: 62162975F98C8ED1B74ADE5B2325EC3D185F7BF8D9DE6C08BB3AB052E54C28399AABE2BE4295CBE12003A03924D4EE3F +110: 8F1E4237FBB668D2705FA6964FF50014F54AB6346A7DECC8DBAA282B51803DE20F9090E7AF2E6B40FD8A138AFE25E1BC +111: F5F9FE110D809D34029DE262A01B208356CAEC6E054C7F926B2591F6C9780579D4B59F5578C6F531A84F158A33660CEF +112: 33BA080EC0CCB378E4E95FED3B26C23AA1A280476E007519EE47F60CD9C5C8A65D627259A9AA2FD33CA06D3C14EE5548 +113: F14FC73C4192759B70993DC35FBEE193A60A98DBD1F8B2421AFA253DEC63015A0D6B75FB50F9F9A5F7FB8E7241540699 +114: 72B9E34E0E655DCD7D9C288D11839A4FD96292F76F69BFB2E7D4F848E498B842CD4ED6486E77E30C603D218144AEEFB7 +115: D71CBD531B25BA65E319954E5AA670C8055406A595D006F0DCEE11AFAAF735CB1615EBAB4CC98061645FB70F31CDD9AA +116: 1F4398793AE7B2C4975AB102BC054DCEECB238DE4307B5DC54F6D7C20E066F638A782E33441533276DF9DB1AD0EAA75A +117: CCD908195016DC596A78C6C10C92EF6F272C6251F3C40B2E7DAD3A4538BF3FF585D4E44035B49EC397D1476E9DD28D02 +118: A8A26DDB23032BBD4432AC857383A5DE280202B21CE173D864E19C4A52984E159BDD006D95605A4682458137FE6B71BF +119: 0C8D3031D85CEFA23A09E13CE03623F0E648A030E43700C82AA1C8AA7E3EA9CECEF3029A23815AD940CC39ADB7747D2F +120: 0577AD6090B2A39FFA1C4A25436F9E958890C55A5B23CF8CEE8195A5984316D81D6CF0B5916C0AD8B1F512FB39826C6D +121: A5E7C31DCDEC53D8898DCB27D52A5C1774115D8DB163543A330AB502FE31D6017FA4BA4C65ADE0CD911972C5A1B7739D +122: 2785C149B798E41E6ED600DDA5257E2F31484BA4D14D35C8353BA4BB3BFB47F6E2CD9B64C940E3C1F83AA4587DC29CAA +123: 977756EEF1A7C1D4CA31A8E6936E7B8884968A22F2846F20B38F247345B1CCD47405040F727BBE2E0FFCD159206F5E87 +124: 9E4811F182E5D6734EA097FCBC77892EC48F09DBA138AD5A5ABFE67F2E88AB61B0A3ECB29028B5528180191754231765 +125: E964C5CC45E8356DCE9FFFE715D01AEB3935D644DC9C2603ACD175A04E8924DD84A4D88A1384D6BAA8AB3F7F7D52D122 +126: 764EB963850537E57D0969C9914355C5AA67AA9722644569B7F50E20DA8461CC9C6CA5958ABE10F5469E4DC1ED27619F +127: D5FCFE2FCF6B3EF375EDE37C8123D9B78065FECC1D55197E2F7721E6E9A93D0BA4D7FD15F9B96DEA2744DF24141BA2EF +128: CA2385773319124534111A36D0581FC3F00815E907034B90CFF9C3A861E126A741D5DFCFF65A417B6D7296863AC0EC17 +129: EF49AE5B9AD51433D00323528D81EA8D2E4D2B507DBD9F1CB84F952B66249A788B1C89FCDB77A0DB9F1FEB901D47FC73 +130: D9B681BA08EC0D0598DD3A2A37F909D01A231D22DA52216126534402A58A072DB35FDAE555B99159894BC823F9DACFE7 +131: 961E792C94027A091DF880A713ECBCA94E7699FA392CCA3E4B9988CB95DD46C894AB6CFA3DE91236188F7A372B1C60C0 +132: 779C845CED9623B6558577C06C6F22768E4A01CED2A9722CB8788FCCA89E0B5CC6A8925533FD097F635997A9C191D59F +133: F8A6FA1C730483AE488191E5863AB3DAB4BBDA1722710E519A2B2455273E78A382C60DB0D21E3B497EF9EEB2780AB384 +134: 1DAA34486981474A57029F0B1FF5150A144CEC7939A5D0C3D7DDDC4F471225D98E83E8A0DE880036F1A265E24CA1E674 +135: 769694D69D701764BCF81C053E2899B232344506C08A39DEDE3D838F85870818C3A8CD2DBC8695EDAF8FE34B4A5CC35D +136: 97E29E4AE7C7E461196C1D698B5D1186822BB66ACA3B3E062A3AE07DB9DD0FED83A345014D3E5AD89E9046606AD2CEE7 +137: 6B57593EE18186573F92273A9B722F9FD77A4A512164FE3756BC2D9F665768016EB2766C46D473A103D7D7090073271F +138: 35235261C522612958048B7FB8E48F96462D2B8B52AB2455C7C142E442E4CF643B367ED466A30BA97D91C1C8C0070E05 +139: 67004A5E74598981A79984B2662FFF8C8F49F8FD13C8A841F68DBA18DF68015E9C1EF38D6522D44F89DBFEA8AF48D2D0 +140: 8ACD05F9738BBB176E50C7419A05C8200E1BA84B5797032E025ED4B55D7A61CEC4CE3662432A4E0BA938D8C9143D5254 +141: 9963300C0CE5F2D39C2B899E47988BFA914D2EA2DBB972C15B3CBC414E41DF3A2FE793597243D46CFF937F41C0D83136 +142: FBEE0F5E072237D19170999D02BB95F6F8F48FD0596A982A4FA2D1273872226398DF57A63E1ACCCF6343415DF387D89E +143: 32A65099C47EAE3BCD0F68645845C0171417385B15DB5E5F7BB5AD965F66C98CDC39B7534198AF70AD5739C8A2F2B8DA +144: E936DBA2CED7F65DE3450BA7ADBE1030D7AEFAFCCE0CBA94E671422790B45B49918319A90FAA7692780CAB4301D9833A +145: 1E20D13B4D71ACBDBD5D2AA129E98929510C795119EA8A07EC63917114315E2756B45E7AE42E1A44C5E410ECBEFB3661 +146: 02A0571C5C3076CACE7F061BDB108D7CD9C7EA51D0FBF1D00F202A0B5C87F22CE687D1CB15F798ED164CAF1CECF92CF2 +147: EA07C4A1DF1E5CB26DC7A7BC76FE518890FB8C424AF3B1C76B37AB21445D9F7FBAB73C7DB35E85337A8F7A0D55121F34 +148: 7829712876378DF986A63E4616DCA38DBE8833B14760168897AA808B96D8FFA4460CA3C1A9B674A0FC13E0625537C45A +149: A7CBB3CD50AA663BD2C4520CCEEF123F7D314870806291DA26A59C003D041E46E6B563670F27BECC5F838A273D349AFC +150: C14E7F70D28E17D3546EB40EE96D239CA5EF7EBBBD0DE64B964C145A5F2980D408A6AC248D651E4583E25093042EA286 +151: 19F87BFFBFF4B1E195612F41E67E1D4CD0393E73FEDAC1C36550C2B1A7323D3E7D747EAAB9844F45F150F8DF0FB72E80 +152: 6BFA3BC29FFF3A92FEC377AF8508D4823F4E87072D6F2F16370B7DD30789A944EE5721EFDA7ABFD47A512EA2D4984BC0 +153: EE10FDDE70EB0A11462DC00860AC4756B21C83BFF0066C431B17BA57CCBB9ED018E8058CB9EA44CC11952C3C9BD15F09 +154: E6A72B9D2A0FFCA41C3122C767A6FD9CFA04CB5B1D1D94B79A0B2C592A584F731CA0523AEA8F2DBA35FDEF74CAF165EC +155: 59118A53C4479070DC728D94BA36D211F4ED5D35F1B69E4DFC0543F07326F982D2B81DDB020F2CACCAF1E5E9832624E3 +156: 63778B7830A3AB7421912A52B3CE9303A53C2A6655291042F428691A633FB9FF173937A8D8F59B21F72D490F39A9AC06 +157: A702F15D9483BB767FC6BE9C3BFC64732277CE936AEBADE4022B24B4822BD1B0FA1213AACF7B4506BF8F330FB7643955 +158: A3FBEA92041484F7F46B380462C5114B0243A79FEED89ECF8E6D8306D60DBEBDC5FF1578EE7E94B5527EFC5707D2B7D3 +159: 1EAEA2602E0B6B328D008A5325C5D4F9DFF7AB9BB5D36816D3EBFEE733BE664E35170506667BF5A24D00222EBC5DCDCD +160: 92E4D41594E15628BEF06CA61E644D2A686C113BF8E3F9A8CD2CD8261B11D01B081EF2941D5182E565B70C566D461B23 +161: 2F08DAAA98DE6DB4E85B81E32C651D88075DE18B7F9C3F633BE1F29C89F24968525B1B357DE80C6EA8D9570E003C75DE +162: 5DF64E7960C755D40BE78F0BB7C1A185DF8E505F0B421BE23563472843E3B5CFC7DA0F40908BF56C6F3A6244581C1DE6 +163: DABB5DCBC32FE7298C811CE22025E9B1C0B87DA5E7931CC3614E3EE39112206DD8422A5504F11599436B806C9108B01B +164: 31AE27382E330115E009474FB5AC750A278B79EFF63755E323E3478B0761E5E946DA6D2436DC44ADE9F4578A8FBA9896 +165: 6804CF0314E455F499E73BBDF4FAA22CA49020330E74C55B1CF4A2D2F4C57D7149B41916002B2852ECFA0713BA91A094 +166: 7FAD2AB0972D8059D4306F0B63F25D9ACBBD8FD95EC8199CFA89D4E227EEDE6052AF0C53C703C7E319047DC5734C9F4C +167: 4635E654950B173D3EC81A8212C1E65605C85835CFAD8607C829786855636A660D6C3045FF17663DE465BF2B152879E2 +168: B40764D8F066C897C3A8FE54BF21DA294C6B3F1B35255F68C8AB325AB3B94EE8AE2E5173936C17FDC95C9B7C3D3D3A58 +169: EE7E424C550F79BA82043245C3B7D0AC32A41B876988C322B9997D87F0A0A1FB8263726B953B43B4616285A239994936 +170: 627DCEEACB27F39552AB683330A67A316B2F53842BCE8056FCF3988702955E3BA72FDEEAC2CDB53F13627858C1BBC51F +171: DD13F3B3E9C79958B20D1986650A79CEE1343F9957FBEEDE18B2FB5E543E3B8839EDF7A57EFD818129C4F00F505D2112 +172: 0A7061C0FBF1EE8CCB0F4A1D0DCAF2F200291AC06830F0E38D05E1CA2429A2BF57DE5BF8DED5A7CECC3A4748FBCB880E +173: 3635AEA9152337FBFA4C2824C5499B9F3FD32061297C4121FB0A44CDF5D3C8D4C6EFD760A0BF076DBD1801C416949A9C +174: F9C58AF2259C719B0B852FC68299AC9F17A802B49B34CBF5FBEB85DB3C68767CC34DAE2CCB536FF90BAE49FDDEC0CFE4 +175: 3541EB8602A4C84545F4476749EAD54E4542C4358CC78CA5B7C8B6BCD9E9A3E649CCB243FE0B3D02930CF1CB7A507FFD +176: 4AA26C2565531A52811D30A1C59152BDE4C61AE2CEAFEF9642E7076EC44C7EBD50F1D1853761B4097D985DFE6878A701 +177: 32F1DD0B4AF205B4891E2F43D772EB5E4A5EA3658106FDC8B8CEEBD2D502F8048B583610A419E1A60020C8C2A5A02FC8 +178: DA7403FE3C3D3139893522C5DC8E4F615D36A0F7B7B8AAF150D1337C8DFE70311544E54880D1C575D664E9AF979984D9 +179: 39F8450D4A946ABC6FCA804AE11935CDE846D999BCFF3091F1E6944EAEAD504F77139A919F915D34DACC13757CCE0157 +180: 45CC03085CC3278B8337096BEDFE6F1D645994690660F23A358C4EC728EBAFD6966C487B9492DE217C17823B16589852 +181: A2150F3BA3349E3AA0ED97B1A02A58F31EB5731012393EC68846D95465F3B787C272852B6945B1CC0FC2B3BE999E0E46 +182: BF9392B085B3C5FFBDE70A3FB64AAB36E39BDE4816F1C9B2A608269336906303F7DFC15F4701D3FAFA5D7A8BFE316A1B +183: 21BDA179D5B80FA6B9444AB1D1F7E06F89F670DA4A038E7E83E8A63CEDD44AB6C1D069D12C6F538B45022EF3160D396D +184: B4216CDE6BC1C27A5C1EA9AC79E85776740F93440AE438D4D9CF51BE8A83AD44565586FBFB58DD743782724A440218E8 +185: 5C3D5C00381BCCF77FC2103C262F373592FE34C2B2895F54BCFD1F9B3C87026288130822B2B451D716FA9D4D7FCC93F5 +186: B927E3777D4BE05FA85D0CB707FB00F08C576777840634531795CD3D6818F192789977AD6425018025E10F5892FFE708 +187: 9C6976E1EDFAEDC32378C8D2758D1B0C5B287C500442EC5D19560BC87C75FD2A7379A3E64ADC1421B7410D1ADD6456BB +188: 9C20482AB71BBD8E985D7891499DB526BCAAE11D2A42DD72FFED664D7BF7F254C2F8DDA2E340690FB83E1F5C58378B72 +189: 7899D5AF410188A3D0D0B12D52437313D786CE7959FC4D194D6A3ACA85729B60ABBDC58AC40731B9E833505156BEFE24 +190: 4F958FD1841D2B790A199EE3358F4DCEEC64CB34D0886EA91AA5E38F8600FBE13DEE4D6A55AC1273B3730CC62A3611B7 +191: 66572F61FE6C34B440AC00C8D3992B9CDE3FC465FCBB193CB7716B53E8032C743718D4F8245D94A22A9AE125795589E0 +192: E7AD49861960D1460A77F4F363341ADC2207E205302957250612C7E903802AF5C9423414C52F4C1AD55CC1C8B2922EF8 +193: 62BE3AA3A9D08CB41F2CA3ABCCB96E2E91A248E569FF58F58C8BECDDA5B4B25FF46BB30EB37999E6131D944CF3253302 +194: 3E082F7DBDF5BBA5F52CC870F2C6E9C63DFCD5D547B183F3FFBE392BF0A1F8F4970CA21E5B9B4306792C138D6B2056C3 +195: 5CC36277225DA2EDCC6CB603EDE9C629E5DA823E6D233AB7833F70FEA2878B2F8D08F361BD5B4C7609577329784D87DD +196: 9555EEEE1EE60EE981CED3FB6BF74699E5383436ACC283BDA0F9F6FFE20561ECE75ECE2C5A82C0A158C071A3BA59CF58 +197: 0B975D2ABD0551BA987680C4890F80DF93AF2292FDD1E47322560B0AD3BDD38A67D3A78497D78B3C38DA597846C5159D +198: 016CE0B8AD1628C7FBA358EEBB7C3667FA93566086B99F20EA6F87FBACB320E7BCEEBABF0008550A59AC1E6C3B4478DD +199: 3D138114480946A2AA1E2B78948B6BFEA95F53BD8BED81ECCE166062A67FD111933A696E6FFFBFCBDDF71041955C98A0 +200: 7EA4BB2534C67036F49DE7BEB5FE8A2478DF04FF3FEF40A9CD4923999A590E9912DF1297217CE1A021AA2FB1013498B8 +201: 80C399C975ADDAB12FA20B3C3D04F25218DFEB678B5A87F9963A462F5474732C7C5FAFE0EBBBAA94662789CC10C9AACB +202: C27E28A5B6C7BFBC7ED372B5BD2555EF1370FD96043753015B3FB9AF31D41E7189D4FA8860B183703560A298D90B6E75 +203: B792B021B3FA904B5948AFB4E56BD4C40119AC79E57EB24C32A7BF0A1A889313D816997E35F2CA192B34D2FF9B05ED9A +204: 7828C6235E2B8AC46E4BCD7F7C7554EA81B5BFC046133EEFA0C4E64AAAAD7115B04EE09E33CB4EA1FF476960C64D9A36 +205: 06678F9A2F238953A8D6646F859FCC3BB0C29BABA669D7F891142C2C3A0BAC1220200B4EFF8C17F5D79E261128C58248 +206: 0FD4448A47B6620FE90551A9AA06DD991AB13DBD2AF18A4F17AE4A9A24D9A83E7653D5F5A2C54633C42ACCB0E5915A35 +207: AABBB8857DE60BDBB21742DE7ACF7EB8D9180D5D0AED23B7F708F09006C6FC56CE85DB87D9642CB909038E70C15C1574 +208: E1BF933A4F32AF56C929911284F9B05B79F0216EF3A150483D74B2D4DCD78885190EB1601A320150C860168221C6BA49 +209: 9074B187372B0535738D4606AA0478BECB5251EAEC961699C2795FC028D641D60230532C8F6A096FEF419A46B0DB87FC +210: A63532A684A1851050E2861F7AB94296D131F768A94AB0019A941734E13842EBE8AB1F42DB4D0A84E261CB4707C74290 +211: DDFD64103308F0537ABD8D4F2209D8920CB42FA9ECBC93318D438C1493FE11B6134DDFF95DBE3FC6B8AA31F833E305A6 +212: 044ED56EF3129D29243665545A59FDC12412E137E1F55A543AACE511F9F86CD3202E3D24807B0FC878BA76223EDC6F42 +213: 2E470AB58A76690755AE6643D615039E767B84AE9E68480DD937913C44AC2350A27FDB45D6FADC242BD5F84809D59E2A +214: EC0ABAC477B5AD5F6B11DB4B699283FD4668D84C2BA7F8DF90A5BF83C0E1E224623F0D2BB3F2DC6EAAC5E41436035D58 +215: 9FEBB6C1604914837F6D00F9AE23A3459DEDCFD81EF755B96A3CC1F63E4CD2E67F5AC2605E594DCD2610F4962EA6C277 +216: 3873BF1A102F1609A624F1A096E420CC459C02590600808F7DA5E3FD49F5B491269C1116A2AC74185A3105B5E9606126 +217: CD7E8C16B59BCEE5888DC7FFC28E65B72570B26F3A0C85885BBCE81E5A6B63D781F953E497399DCB506E8C4F5E237169 +218: 3D24BC91A4932BF6D631EB7698549B03E7F3930662B8527EC122FC2C7AA41E330862102557F480273864FF9B06628BB2 +219: F0B21BC919A3C6089BE3CB7CE10B55D76E31552E759F0465086A89D1FA435E2671928AC329ED7B3D7C1D7121C158BABE +220: B32F9A1FD8A97E6E8E701371BF1A017078B26C3F4C58E342ED455B2557BDA16EAFAC00AEAC1ED7328C65D7C1E227FB83 +221: 5468F1B9192244C738EC20FA979F746CF6929FC48F69C79F43E46859AA022CC42E65203CE7CF77A039402093A1552EC0 +222: A58151FE3211C27651693B55E67CDE0E886BB0D8F2B6D9066615124CF1DA403DFA014C6F19C1B10DE7D3BBDBD0AB9880 +223: FE73FD3276463D27AE6A9F54877CD9BD3410C4A40381D25F5A915194538CA8C4F4B6154ECB9CE8B1B7E23953DC64F664 +224: 0D4EA680BA7CCBB9D88C09F6DAA6BC655BDB0B2A1C8C3DE0BE895328027794E223A45969AE594C7A21FABD5C92BA6530 +225: E6DC0E64DC804FEF91563B550A83BE7ABD50F51D3BFFA785A428EF9436775DD7E3A589793CB2717DC6BAD8B531CFC922 +226: DE168B8F03C0CE8143FD14BD2D294476FBE8DA85B09BF26C5D846E2D19957F87D6FE150B278EA4B3BCD36AE52D251FE5 +227: F34472A4DF2D3B529CE56E9D2A721A839DB05DB7B66BE8AB7202B024DEFD46ACF493973DD1FE88D8EF6E70673914DAA9 +228: 1F5E8FFB4678B3889E7FEB2288358A5F1377A97F76674A8D3E5EF39D185D02F6A1FB60E43BCC79C31E6974B37E74E50F +229: 190AFF1D363C413BEE16C78C544AFD20678C7B1141D3917B6942E4D1486EDBCEE90EDE8A50E441219ED3B11BEFA09F18 +230: 66BB67FC2BDC1D5E8E4366958804F459AA689E04D5FCAFA8CA222656D568B23E976086E2BBAD979EA0973AAA1FADEB8A +231: 0E14C70C02205AA29303D24D6491CC84B648EEB80AE9CC2A0997B7BB646ED32C69D2AE41C0DC007AFCEC514D7B04BCD6 +232: E38C413F3FC12764415F39A9F3638AA1204D3E818A43CF2EDD9F2CE01936D36C6720CF5BE8ABA362F92AEC81386A4800 +233: C3ED0B3697A84B388AA83DFF8EAA65F5BB12EF00315AD462F1F6D85D410D021BC32E77ADC763A254F7D9F1FB6EEEF1F3 +234: 8DC2C3F8C13C43709AAEBD408A679CEC524DA8C8F4157DA4BE551EFD687A395B33577728EB73EB498ECD0AD2487058E8 +235: 8AE817F2056903661E4EBF37D7293200D8BEE7AE0CADEA671E4987624A43712FD2C392E37C17D8E81EAEEBEE8E96653F +236: 9A622BC18F3A09C8BC1C8603B55260BADF32AE7ABD8DCB6CDD980C5E7A5B8A38C6D287A63FE88567BB9B0481743C06D9 +237: B74C6303DDF9F0AD7CBEE923F7F7F1C7FA52C84EF609F2BBCC07B9911C12F3D1A9BD818A9F36EBB40D4B400AA4D0FDC1 +238: 5B1AD3420ED592FA3D593435CA6EBC700583AC5E3CA2876887E5F190EC2109A1E6DD06AFC6C9D7ED0E8B0272B7F9114E +239: 2556CF077A788C49BB6D600F4A3CEE635C4443832D169F761537AFEE2980742B9F34AFBC87F598DD0AEDC4A826ED6A73 +240: D64769AD58F5A338669B935F3431E5BEF31667D0A2437BFF78F1E5275075F434FFF675F9833EA04AC4E5C2E2C2C99B8C +241: 3264CAD70D24B53CEC95269B980DAB85A30D24CF8BDBD68F0FF8A45C6208F05723A4B3270CD095FB8B2D9A4167FB3D3B +242: 4D564117E87700C69AFE5A4D90FF50DEF8A54A9BF19382E4290290D2BEE101355EBB2DFB2A9D6D044A6D12D6DDF7BDBE +243: 6AAD71FA5D5D7B63FEA64D94E211155B01F8C9E4B3D86C3B9C014CA4BB6C668037C4739A082F37B2EC5FF6D85F0A58FF +244: B36D529E55B5CF0FD3273F204F798E21DF533BE466AD1AF35EF80082132640493FD89A6CF41CA68AED066E93181A9EEA +245: 78814E883A27D6ED3A5B122260059CC00D31B8A0E933F3C377BB99EF33F47B13B6AD825B740784BEBDD9917879C2DAEF +246: A7978D0C79070B208F070241867476AE622EA887D26B0F6703FA8A455F411649D8919E6E12C540C59DF60CA9C05684CC +247: BDC3E02D31DB1EB7F04CD9FB8876AA9C7CB1852BD3BD62F56E062E216BE648A34FD327B84E3B6339F44697470711F661 +248: 9135E6D4B1E2356C3DE16A85E4AF57243CF6861DFB6C53CA13D9481371AEE285B75DCCAFC1A64499F1B2CBE4A3CD82C8 +249: D1F9BAA4007BAD437509DB6F6DCA22086CB786026553244A6F480C3A6488F7E26C416C6AE85874477BB5563BA0AECF2E +250: 49E5B7521794B6C73004BADF3D039F4185BE9BF8499FB08B9C8FDA2186B6C4BCD280AE2D2051C6775C19ECF1C776ACF6 +251: A7534C1716B59AB1C7AF3DF0AE32F22CD02A1823F61B318F36DFB536B8EF4515116A099F8DED19B00EE7B2D243539960 +252: 0F01FB323FADD9380A5E4EE6371E8BDF6FFB1F70C4D4A1B5E8BC9B281582AE0531AB354EA9F58A96568826F6172FC75C +253: 145C9D3926904D8418B75C8D645D43AF651684AE7FAD885AB46141B9EAD2D9727731F44D5AAA0204395E020D1B52DA96 +254: F663682EF7FA3F300DFF0B4D9C0D2D126F2BBC164F3B88C8A2207C3799464ED2086CDD324C1E88DAA6EF2D53CF7C190B +255: 98D7AC796C4CFB5D98A1C323656A4BE8AFAAAD168E5EE72B6B7A3FA3260461A043E27243120D41584B58F1AE4463121A +256: FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5 + +Hash: sha512 + 0: CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E + 1: B8244D028981D693AF7B456AF8EFA4CAD63D282E19FF14942C246E50D9351D22704A802A71C3580B6370DE4CEB293C324A8423342557D4E5C38438F0E36910EE + 2: 80536C6170DD8626DC081AF148D39EC2FD5D090CC578A76647E7903FD34BD02E4333ECE57B0E24FF116F43429B6FF541834BD40EF0C8D3563ACEF5ED0FD254B8 + 3: 8081DA5F9C1E3D0E1AA16F604D5E5064543CFF5D7BACE2BB312252461E151B3FE0F034EA8DC1DACFF3361A892D625FBE1B614CDA265F87A473C24B0FA1D91DFD + 4: 4EC54B09E2B209DDB9A678522BB451740C513F488CB27A0883630718571745141920036AEBDB78C0B4CD783A4A6EECC937A40C6104E427512D709A634B412F60 + 5: B7B70A0B14D7FA213C6CCD3CBFFC8BB8F8E11A85F1113B0EB26A00208F2B9B3A1DD4AAF39962861E16AB062274342A1CE1F9DBA3654F36FC338245589F296C28 + 6: 2F3831BCCC94CF061BCFA5F8C23C1429D26E3BC6B76EDAD93D9025CB91C903AF6CF9C935DC37193C04C2C66E7D9DE17C358284418218AFEA2160147AAA912F4C + 7: B7C0B47F42F7202BF7D28D6834BEE365FC01CE3F0C8C8DF24B4D940406C2E9C230BA88854E946EBCD786C18C748969FDF012362B7C96400604B6058950FEAAD4 + 8: 8A414C5860CF1BE7BC8531442F69A65EF2ECF0B7CAD9994BCB407097EB74CCB92E93AABD24BDE60331123B4D900684CA7BE6027099D4946BF537F4D6C6DF3D82 + 9: 8B5E5E7FB6530CCE1BFFFD1B1AA338D3282E8483319BF028BB674BB6AEB8200DA389647E3D8631503DC5C487BBFA7D074584493615B036849E0242610EA4758F + 10: 0F89EE1FCB7B0A4F7809D1267A029719004C5A5E5EC323A7C3523A20974F9A3F202F56FADBA4CD9E8D654AB9F2E96DC5C795EA176FA20EDE8D854C342F903533 + 11: 8FFAEE0CCCC162851FAF051AE38667EEFD423C0164C50055F8ADE00AFC3705E3CDEB9900004B0E426CA66AB63AA3B99B075273F44FD37C22A3555C6FD1F37CCB + 12: BA51B2A9DA2F26FE81FC3EE11524255937EC6BEC48835EB437C598C55674E15AA50F88922DE7584332A5E4D24787090CB14DFC3ABDB39C55AEDF6EE108F95354 + 13: B6E30A4016029486F9205C5D141344F885B3DE2468EDFB0B870545F1775CE82597C2A40462F385C957790C20822D9E920EF1AE230878D6B23F221B0182879CCC + 14: 79D76024A31CDBE54CA951D264C46E78F6F5AC5DCD018BAF89AA586333BE82B2D5CA2BC64B99CA2A99D95A984F2DC0D6C07E7C96059DD346BB3296ADE3AA33C0 + 15: 4236736D08F26244E75B51614091CC2C2907D5DD162F8497B14D58D0D954A777C8397549BEE468F30E480252D9B893175DF7D2BF415A128CCC79407D9D5FA536 + 16: DAA295BEED4E2EE94C24015B56AF626B4F21EF9F44F2B3D40FC41C90900A6BF1B4867C43C57CDA54D1B6FD4869B3F23CED5E0BA3C05D0B1680DF4EC7D0762403 + 17: 7B9AE840AAB8BEE45B038CE398D15A8679DB92D0BA46FA67D1B8177986E41EACDE915C6552FC2AF8678425B8BE81B57E0F7EEADCC93B56C58DFC38B4D33BF25D + 18: 0EF6A8C19E19A466DBA3139E2A401175BEB9EE01FB56A8FC11A3E53B345F2327959F6DAACF0CE6121987D2491251DCF550C95F6026F93A1D96A0F4164CB1C642 + 19: D6221AACC88CE14EB7DE0F15F2260EBF4294D9AC3D75B87465EF7AF9570C959077860EBBC5C8153000507CE1E39AED5D007F2286210EFFD26A118966ED15C143 + 20: C9AC4561A7503FAB9C6B71C843AF6911438550BCDF4881EEC18DDA06E4D8B820CCA9521DFA9EF47298CCF6308FE4C4F2F5E34DFEC2ACB78FBDC04D2EF0A5A09E + 21: 73C5D58B05E1E6FCE4299F8D9294681416BC3785F51E402DCEDC0E30C0671DD48321A0248CCC13389A012B52513F1B5BBF820E91EB4F616928183485B4F1EB22 + 22: AB1725C57427DDF93B34AAC62C26F3FF1E49CAD30DD41AE7B5FCE23894245E7E889E0FCA5EC076F247DC7E929D72FB965B45688E57D8CD54212714A17480BE0E + 23: 456F6757A82F0589040996BF88F28E61317C358135A9AB6E96E22F5CA68E2A6438D13D176B01157ACA1FEEDCE3C1A6D5C3A9B1D5A471691917392FB94D0834F7 + 24: 5330241E6F01A49B21AB0D01A9C76AD662E97A325BF8E24C4EB82C6F3B7D2538ADD98F62307F36F900F3934861B80FC9844B761BE15460A1B102C26CF0410E83 + 25: D8DDA603DC21C20A6DD3C6A4F380C297679F035D27BBA82554D02E1F95ECA2EB20496164F96DC4B84B9BB0942B96A3796AFF6125BB9E8711E2674B440176E91A + 26: 81E5A3AF460DD2881353D006AF37478C58AFFF16022441226FB04439783DA920D09FD03E19F45BC82F82735FBF4F2E5F588F11AFDB87B69DB91123CBF05F7F2F + 27: 25AECF7D241EE54E668DDD345582DB777F9F631B9D2432CE4D32119BEA3968D9FA3E184B135364DF62247AB74BA7B86AC3542F63D9F18653D86B9B47944AB96A + 28: 8A372F722A922E29CF5CB22BDABC6D284364F376DA355CA65BE36DAE2FA6F0335744CEFA9089DE55D331AE64E9B2F1037E73608B03B978758A20A012924AB235 + 29: D57C54ABB87AD2D518790B81230DA336F551A0D89A57D0A3CFE2F4ACC55B4B210261CD1482BC436F62D3FC96D1536B82A2E93E9A3DB5CD0F1822EEACF307460C + 30: 6092F1E76F04A5926F6FCD149B18DC9DBE8581BDE6D2A1468145280463472B636C711FF61F5CCA84FD2F044697BD1DD18340B3ED0A131F4BBA35F839A2DD9E0B + 31: 0674A3CDF5F7C18C1B7524C87C36037F3D0267512D11E052F453DBC097CFD52BC331950880CF904656C70758B2E25E21FE2C7E0462E861112A2DC9D0636BBAFC + 32: 3D94EEA49C580AEF816935762BE049559D6D1440DEDE12E6A125F1841FFF8E6FA9D71862A3E5746B571BE3D187B0041046F52EBD850C7CBD5FDE8EE38473B649 + 33: 301F1CD7B25B097AE4C79A97E92BCE359D1289F6754E76B71E7617A06E7783A3CC30F5290209BDA3E6AF239D0DC0F3D1CD4C5E866F4C5C3209EABBD7AAFB8058 + 34: A8C7114B292CC6F46D73824CB073CAEB23EB1ED5EBB37F064A0A76AD452D936D1DF41433FFA337C3F7CD53F5CC00658ED0633252B69DE192E61D9F002B0F133D + 35: D2F92068E07C9AD0572693CF546FE75070E574807C02F5483A31B8CB2105CA55CC6AADAAFE74977F581CE90F43E2AB48260BD7E273D4A83C442EC4871CD88AAC + 36: 1A4133CDFA6CC518387D392814029744D6FA71122EBDFB70059512B89469CDB9D9B5E45900E99E67DBA54B4708036298A94835751EF583149F06AB272B2BA355 + 37: D30DE790B4905717C956A95F60D9ED5948F9E509BA27607E1C5C8FFE35ACD83F719AE04D63364C0BCB72BA529AC79C321ADDFBF7AECF7CA3CAC840A372E6F6CB + 38: A25F5D4BFFBC5F0E3D5CACC3A91870866D8C2D22573556C9B9FA0D24E1D68C55EB42726B1895DF8E5E870DA33755DDBBAC130AF2D96D84DD0D57761D25FDB64F + 39: F44001A74D0B087AF2A143B778DCDEC1554BCE5992C9672E3D0F6704D022CA1E78F087543569CB99D249B820E683138A2DDC5DC178D585167FDD269D17396A89 + 40: 692F36EB114060FD04CD38555025251DF985DDF681A0636FBD290EFEA6FCAC5226859373F3E10E8CB07AB5343547EB0A543C18420D70527D2BBD90040F8DAA52 + 41: 4B1CEF875A025624398CD06DB876EF9AB34FDB1B6A75A07CCB591D9B20EA66E24BAF323911B5CE8B67904945A36C28630B36129939D23D26218610CB049D7AED + 42: DB3E80F11517AB797265829371F245A7A0A384E36A8D43E72852C8D47F8CE37A178475EEF44CE8BDEE5AB054F47EED502E76D49B9F4A5AA392077ED1E6F43EC1 + 43: BD08551AEA7759911B37E9D45748219B47C4EC17A2D2A306D9B8FDF982A9E3106BDC1ACF3F47D383B6D16E85910BBA08128E35EE578E7C55F2E9B9B59F611298 + 44: 3BD8A709DB9A4E0B874B113564B11EAF8270AD1DA3A9236DBB16F58F43285070344962394C2231B3917401924A3F688150B9A9ED3B410547DE3F56450739592C + 45: D0206C8577202C617592B47AE178DA867AC7DAAE4E65B912C771C5FB09585FBD10C36782064E83ACE749BE27045508D544532B628F67DF00A6B7DBA9775D3E06 + 46: 745083E5994158A0FEE4D849012F43A822D19F068AFB327B372A7A8BFE8347E579DD29424EC95319BF75A24B4DB4280D9C16CEBFF5D930D61D34909061A478AE + 47: 3527A5E1E5E5953EC57F309C6513C34405531603372BA0DFD5725E68B9510E5090CC6B317B2E7359D2ABD5ADD353AE1435B85535EB5B0B8F2E09D4DD1BAF3C8B + 48: 622BE417916F1B0E9CE8C952171B11B6D2E2932D6197CC17431B9FFDF03FD0ADB69B08DEDAEBDD0F94812BC2C670C894D65165B31D2F2879532F2C14453E6A0E + 49: C2EBDADE0368F1DEBE44F8E1B77E66BC1C25E7F0FCED7784D615811E2C01192DBC21253E10709D0BEEE746DE6EF93CF65AA39BA29551E11F602ADDD27B196019 + 50: 5ACE0640F0DCB25871E1925F96BAB48162D692BA134C9C7052A37FDFA4895B90AC56C7FB0E7FAF155D147A467839500D980E9D4ED1CC96661177ACF0BA8D4167 + 51: 5D43600C04E52BF6524CDCB9DAD89B1C7563912E7C7E2CA3D34B27B3C1D07D85D35EBB7A65AF0434155AFA3102A580AD557468CC23EEA1E151BFD4EA817FC5B2 + 52: 38D7538AC3E51DDFB6724F57B29A5E46D15A8C08FB29D15FB0681A4315B03FD6747B85D0EB2B9E5FCEC709F365DE08D61A1EB363094BF292B5154671D15D61DA + 53: 2DCE13E5882A31F7396D970AE72E89FB59270D78BF7B4579D0855C4E8BA231D23E5566B77E79CCDC1146762DAAA74F49D82F9EFC0D4FCA891E78F9FF86C61300 + 54: 6D7644DB575C5C238DA02CC4259996CF163A3A3B5ECCC4FC62442DDF01AA05EF0C4EDBE3E6D220DF189C984AA55726A4922EFE004832F2D8887F0B8A9267DB40 + 55: 6856647F269C2EE3D8128F0B25427659D880641EF343300DD3CD4679168F58D6527FDA70B4EBC854E2065E172B7D58C1536992C0810599259BA84A2B40C65414 + 56: 8B12B2F6FE400A51D29656E2B8C42A1BBFE6FCF3E425DA430DB05D1A2DDA14790DEE20FA8B22D8762AFFFE4988A5C98A4430D22A17E41E23D90FA61AB75671A9 + 57: 92CB9F2E4EEE07C7B32B06CF4917FBE54365F55247CC9B5BC4478D9FADA52B07D1C302B3959D0CA9A75A629653EA7C245A8FBBA2A265CDA4EA70AC5A860A6F3D + 58: 23417F93C499DF9EAAF1BFD6A62AADBC711BFE56682943DE5D94E0DAC32F732B763BE28C32AD5F01CB95E5B322AEFF8494B111D7CD8BAB50E7C602695EA6FE42 + 59: 4ADFA8837BB499605D38716F8305FD50255DEA2EC4BF3EEB07560B3C93B5E3725C5A598277A32502CD5C8AF6C88D55756DEB03B69CFC278FFE2BFB3CA202B0F6 + 60: 981A245B249111B4CDCD565AE60C9DEB69FDB552B10C932E8D0635685904203C37CC65D674292405DF24A589682B8AA69BD0E16F666652290BD79AC10E3A9B37 + 61: 15DDF1E434A88F27DEDB8435ED837FE4F1F3BFC5B6FD387A98E93D1C83493D326467C7C53EFEEF158F6B9CC2081267D9761A32A5094399754C0FD62F4C72371A + 62: E08026874830E0B911F5CC51B81599A4DC21204F5C9381CB5A0DA8F452EE99D9FF7590B798805C2743822572E6D2E47C2C1F2D428EF3C28D05297BEDC5CAC4EF + 63: 9DC9C5598E55DC42955695320839788E353F1D7F6BA74DF74C80A8A52F463C0697F57F68835D1418F4CE9B6530CD79BD0F4C6F7E13C93FEB1218C0B65C2C0561 + 64: EE4320EBAF3FDB4F2C832B137200C08E235E0FA7BBD0EB1740C7063BA8A0D151DA77E003398E1714A955D475B05E3E950B639503B452EC185DE4229BC4873949 + 65: 02856CEF735F9ACEC6B9E33F0FBC8F9804D2AA54187F382B8AE842E5D3696C07459AAD2A5AED25EA5E117EB1C7BA35DA6A7A8ADCE9E6AFE3AD79E9FA42D5BBA8 + 66: 371DDB96ED5BE6521379457AE8ADD707A866732B629EE00074904D73858F3FAE827D84E503F3779073490B274E29D644D76154FAB18945222289BCA798BA6438 + 67: 96A693A22256D39A0596802319CB7AF997DB4BFE311577E38F8423DE81C567A96775D063471438F0982EFAA6B75B4AB173D9D3B3D4762030B522FA70DCF3B27A + 68: 7D8AB6155AB31F29740042D82788A69E880FC642E600BEDFC89098B9D2F4F98BC11141FD420870958810295100DE66F50C96E1E4F6489DE98F9BF2D4A9AA2237 + 69: CE561F8F679B4EEB1DC97DB0F72632B9DA1C5B5C0292CBF0662CAD981374BF8C9A0BE1355657FB18196F980E6685D52FE601DD45C6B0FBDE7AA5C9D52E7E5973 + 70: 10164CFD162CABC44C56D76D369096D759954074B0547FA7310C3388F0FB6BB2AA295FAF1E22C44CF59959A37EFE317698BC29AA718D57EBC831A14144F4E48F + 71: 658B337A8FA873C73AE4D19992BBAAD10E1325AFB4DC8B5733F870761429B4243A7982AB375E529C1FBE6339A48F9FB9E8FD6A568F9CAFE640E102B9F398A330 + 72: 4EBDFA0E60E1A3E7FEFB8DB424A5C3A52365F325EC7F51389A4955EE3453BBFC94692DEAC3FF6A4E94105C27D632DF26250FF37314C882FDEB65D53534F8A961 + 73: DFE9D2A6B0AD5DA802D695B3B91745852C97B0283D9A033F04D79D2CAD4FDE50048AC7D82BCF8C402B109E785D39FC9FA0203F7CFC620EE43577688BCF3E69BF + 74: F21869E1EAC3774F3878570AF0DB9A94F464373C1A92E097D180A331C9028A18A68BF4624D8E620B2216B03709F03FB6CD10004F77433ED605B0F771161145C5 + 75: F1F928D322E6852301AD6FC901E91F2156A3CEEFA204044DDA3B4B76A63692DAAC479FFC6D83EEE3BE028A1F651D3520758DD395A1B251E6C261B7CCE86D0481 + 76: 37954BB11B0AAA67F803973DDD2709A73B947D0A5FF8DC46C2D3C6918C87069AD0DF907589F3026A94B071E0F00230F00CF74AFE8010C24E489CC8AF9B8BD646 + 77: 140DB04BF46A194E44F07F6ACEE8326573AA0591F8370A79DF320093C45764A2ABAE531E5A742F496544657FADFEDB7F04D4BD74C347AAE237B5EE59921BA87D + 78: 6D0D30BE796B6E1039739BF24CE26D8DB954D25813F8D7F7444617816F93FC7488B71C69D96D77C65007EF6A2BA313AE0739302395F3D9EAB0244E372AB96961 + 79: 2B92E0D915BC7D56215651BC9F769544C55E2A27080EE726AB14FAC0A43AC51CD378EEA356DFA70EEC3C9146E08E98358C61FFFA3D477CCAC35FD6724A44C23C + 80: 2CED9E743D84F8EC5664A99C6DE2238464E61129B3C856A7FD2CE08B185F4D447A829F287870AC5428114A7234E41A78801C19EA5C6246FEFF961DC6A9B55835 + 81: 4462303D052C70DE76296234B72BFF1AF173E7B63D1CC0E26C518D103BF3BA78D9AF4BA88013192CBADAD83801B8FC29D0838A144AA3CB721AC859EEABF019C0 + 82: 880FEF79B74C109F030F3FA6FCB82DCA034528CCA68A23ED1EE4133C10B3E443434A37C436F079F3F3A922A8547549A39854120723791519DBC166936C239AA3 + 83: 12DE996C9DCE152C83BE6C0E69C66633FC4244B412066A5FE7CEAE27BD4A109FEC95332C60E87DF08A1C714D9D2ECF28A8A81F1CDF8BB3CD2CEF71011BF5A5DC + 84: 748405D18FC05F0AF7F61E0CCDDEFD8055D86826038C77F2AB230F7D97C89D0EF09CE82C4352A7491729C9FD704B279449D0DD7D86CD2FA52EB3B5A582DC2057 + 85: 746653CDC44B4C86B29DE5B28254BE9198C0271249F0690615B05F23AC0456DD66CDDD13D2F22924DF530C78FDFD3699E38E29A550E2739A803FD1FFBEB29E59 + 86: CED0B3E4011A6DA0415C51E37996EBBC5041861FD1584E3D948E1D4DBD7F8673EF93910A10797490DD5C62245EE7EC03D7CE8B8C38FAE21EFAC1AE6056AED143 + 87: FD4BE7DCAC6984196FABA1D88D0FFA9F33CAA29FBAB3E38CD3DDA7FBD94866C944F91B405B3EC613044E4AF11BE7187B15D5AFB4067C54FA09215C3BAC4FF080 + 88: 46836D5A579D5158B9F49D6EBE9A43C9F4A55C768869C3D542BB615FDBAEC8DD34FFCC40288567F8C5E9363852EFF44FEF0EFC0904BE178D3F78EA1B61B9E98A + 89: C05B8745D68BB9647E411E5AA1F924C2C9B96E7DDE71D190A3B8709ACC2856ABFF3C2DBD7093B25F81C6B9883D377E721968632FA4D566F7F72E1109BDEF2D74 + 90: 647A0E15CC4BB5EB3333919CC828D68C5352F1FCACE6964F23FCEB46D0D2408AE896D3319B202EC687F3F9E55126C05705FDB909CD8CAC88304A61B69ABCF65C + 91: 2DD1C321E3CFB58C2E883F5DC3D87F01936ABAB3F1F27648B6AE563333E3852BCCBBCBF4822230E8F0A0DFE32AB6D8DE92A2B8B2271E17DEBEEBF00D83046B75 + 92: 38122D8324807E25DC8A74012CA9C0292222604303CE8B66D7329FEA394D85B7BFBE0F656895EBFD26BD60A3B553A6E3E4003276157B31B3A47779E1633D89D9 + 93: 27FFBA5DD09485E141B659E218D2924AB0392163CDE296D4109F3AEFCDB02241CF0952F0A38E2680D5CFA35363391A324E12519B58C04E8ADF0E9C7A8B6E1712 + 94: 69DA55F3BDBB1C7397CB382B7E8075F615794F6F8453313C0933D33656A3BAB07C42FF977850625B11CA302494497B0EF3A51F3D2EC2E4AECD24BBBC661C6513 + 95: EE1270F6FE6223C19AD4814F0549B54C11AE7B43A8F3418B0F7BAC42BB5B093024DD4F3AB0C9AF5FD2025D50D5B8DC3505D8F754F98AC3237344A7C14FA50815 + 96: AD8ED48E056378B1AFCDC0B3D5D3936AC825F96ABE0953E9BB85B00EC16084A4F0BF12A2B0B73F0A29ECB9841A1DC7F003456016203E891ABA1BEE13FFD19BF0 + 97: F6EB6972CB5FB156FA20A93D8695AE1D9DA8BBDECCADBA81123E7ECBE917596B51E4A6CF9E1458D882B76B33AEA8F3286CC7CA1085F09EB3DB9B9263095339A5 + 98: 40C54D468FE760A7094726B9EF12A98A1F0FE5E7112137ECFB3A88DB04B0758EC581603EFDE3610B1D76AA879EC31933CB6AAFA2DFC559C59BA31425B091FFB1 + 99: DD0324C4DCFF798F024A32A13063A05AF673CB5F8F03E08A0D931406C868A86B5071BA711F6DA80D7FD2F7D3CEE1B7DC12EA456A1EBE4CBCB25ABFB27492390E +100: AF216A7122D29D6A7DC7B89C8B41C111E7C9A00781D4A867A1D75110B48A5A9C92A15D1DC2AEABB53B83BCFFC50F44CFDCAE29DC9984C8C84FEBD0189322BE25 +101: 1FD96E1905B024D5FA883B3BF76C00A0235EE6386EABAE4D9602B5C5E5EA81FE3A1DD0D81BFB0F904ABD4DA7FC71EF7A2BBD0DC6A766902021CEB03D2578B204 +102: 31B75B047B1214B915EC56983E284D14C214D567F149EB467A1A324080AA0D80264ED771E2F91104B2642E9A8312C0C001652CF4E55308A870A77ACFA088D7C0 +103: 59B8D11078C8B65C5DF4F39D1C532BDB9C6E8F2EF121B97DC5BBC29CAF76774A7DDCDCE0F3BCCFFD4779E57D9B23102EF596B8B940480079355CDCF7EC52D47C +104: 3F1702458BA7F28460E84A032BA160430126221AB5320AE028387B60AC53DEBC42FD169A23714AAC3009D52BF9F9485C0878C06A98BB42D1568E7D038234AD23 +105: C8DA7ABB93D370CE8BA6F2B58F91ABBF1302F96799544CCABF52D5D1EAC3318AD4EC853EDC99CF86DF9341D6D794B57B68CD1FBC5E37C03AA10297F9828D5D0B +106: E1680FAF315911FB7588AA2F02D5F96A3FB02F60DC3C93117B97E4F00E2CE6862DB06117A6627B14B11B9E4C61BBEEF09134E1684599A370C61721A3B086942B +107: BAEE728FD37CBE1DAB3FD5A922E58111BFBA9BB47E107909FBDEECCB1812DE27D2D87003FC6F9F67977ED592EBFC734470CD1E907858F555F21EAFD6E64F060D +108: 891AFA38F3094E487BADAEBA012F11D3109EF19B858394EECA4C7F0C2E8FFBB3B88A7105C7D73E7252E67BBA518ABB6A312A7B8A11742D31BF53267CF3B09E5B +109: 6E6E3BE3956224A97F813DE55B3594EC5E2F4A43BAB873D902025699AE58FB43DB71DE1DC159E83F7A7EFFC19CA5A03C1EFFD27B026EE9AAAD92D1D58104D3DC +110: 51F2BA331C24541EFEC042CC66398D388348C4FEDC3F77A4DDFDA39752AE2880C68E0465C15B07ABFD93E16BA635AE7CA7D7E144018ADE57607DE8643992F50B +111: A1A111449B198D9B1F538BAD7F3FC1022B3A5B1A5E90A0BC860DE8512746CBC31599E6C834DE3A3235327AF0B51FF57BF7ACF1974A73014D9C3953812EDC7C8D +112: C5FBD731D19D2AE1180F001BE72C2C1AABA1D7B094B3748880E24593B8E117A750E11C1BD867CC2F96DACE8C8B74ABD2D5C4F236BE444E77D30D1916174070B9 +113: 61B2E77DB697DFE5571FFF3ED06BD60C41E1E7B7C08A80DE01CB16526D9A9A52D690DFBE792278A60F6E2B4C57A97C729773F26E258D2393890C985D645F6715 +114: C02CCA2EE8BED9B4AC74438D4E8B39619347922DDA5CAD2BC3EB9E4CFD4FAF7CC7EB9F6B21ECCA2C55CB60D11EC450390EBCFBA18312E49598D2BC52020DA9F4 +115: E528ABD6C315EADE09A981E4861F6148C9DD4F2FCE0EA54CD3E9796F17033A3751FE9A223AA23CDE0E051A10C2BC27C0298BE97CB87C7110667A115B6D30657C +116: 1B0BF23602D272A06BEC3E86FC675E16DFB067B2AB662181315C45733D191137454BA22713B51478B096DC51D3FC7E9730504324655AE8B7BDFC184118933D36 +117: 12D5EBC3016C77ADCD01F1DE3F792C4230DE67C0B50102E03FBF3B6B80BF913CB66C3E72530C644719003DB2FCB15196803812D89761E0B781E8AFED7268A35D +118: A3527C4E62349394274FB15B30BD95FAC27472E1E521514775D2E667A5480C5367DA6EE526AAC8D0D1226C33EDA1358091C93EC6B1B8464739D25AC4795EF175 +119: 43E497279C2CE805903A33B54B746EA92D607F7C4807986C849823B81097A9099B5896AC7CC66DF3A93EDC8A91B6F3971D6C7F5688DAF635737760BD080E27B3 +120: 9636708964C5FF6600510319E07BF3FCFCB1F4058FEC278EFB677964BA1E140C1632505452F802E99BCF09DA3D456DC3868D149A0788A730E49D239CE7415145 +121: D5D17F592D401CB111FA7C34CF5035BC08EF6B2E0D3E64DDAB08430DEEFC8B9C09C20EB4E8F98D8EBCAC6F09AA2C1DBB7C1B3B2EFE792377CA6600F703643700 +122: 0EA053BBE2E72264AE4F54512C621C733120F777D3CF8FCD8A7CC1ABCAECFB9BE93EE821A15D19467D249A27961E474ABFC433B8C7132321198789D5C2A50896 +123: C64291C217E37E754F6F57C1316FCD8A7C2AC2426E86786FFB69797C0645848CAC41DE345FF90B72FCDE918B7CFAEA4D661687E6F737A088E9296EEF4C3B4F31 +124: DEF8A3CD4921127815F4D1650FBF8B3EF16EF724A38045133749B7359FA68BDE3EEBC9CB5190FB6720EE3D24473286FC046DE0646C6C0042EA1968B48FB6BFBD +125: 6F3581DF30AF789E44C7459356E1C248749B4A5A389759DFF37826BD278D293BA2264BB808A71C453E22A2962DD33A9C03338AD060B3783713EBA8CC8B43E2C2 +126: 2681BF910DDFA680B7204037294D00D0FCAEE84A3747F6E302A16704B3B08EFBDA0E57DBB8E61E92348C8D5FC5A59EAB74C77949A74C7740C30412A9FC65BF34 +127: EAB89674FEAA34E27AEBEEFF3C0A4D70070BB872D5E9F186CF1DBBDEE517B6E35724D629FF025A5B07185E911ADA7E3C8ACF830AA0E4F71777BD2D44F504F7F0 +128: 1DFFD5E3ADB71D45D2245939665521AE001A317A03720A45732BA1900CA3B8351FC5C9B4CA513EBA6F80BC7B1D1FDAD4ABD13491CB824D61B08D8C0E1561B3F7 +129: 1D9DA57FBBDAB09AFB3506AB2D223D06109D65C1C8AD197F50138F714BC4C3F2FE5787922639C680ACAD1C651F955990425954CE2CBA0C5CC83F2667D878EB0F +130: 90272B89212C81B9700897F611F13AC1D291C33A437000C1423336B4D962DD39CE23413160F023963E12F4CCF90D2762B31BFC6818EF865E8A7CBF918A94C1DB +131: 325638D30C9F63D7CDBAA689B7AF8D23826BFE8593B361C7042D3293926146C65C2D6092F20DB5068262359860B3E3D502B6034B9EC8E7253A1FBE4B2007B77C +132: A3FEEC20C69CDAF1936795AEB9052DC525A26F5559045FE458D4B24697E260BDAA45BE8C940A06AE39FDC1F9365F32BAD7DE824FE7722A444E469C7BC198B7C1 +133: 3F80B7BFBFC9D45073FDC2ED93F7C19F01E4D49CB912BD2568F248561F9C9ED1B6762270033D9F421C977F8BB8B4A73F9A99D580C0245DD4F64AD35D68C9847E +134: C292EF04844CD7C3E477C2C2FDDEF46FCEF97E5DEA7955FD4F418C7B4114BA0CA2CA230D0F73A585EAAAEA9277D72B83DB74AC5E887439A225C105B0BFB5A38D +135: 9F0DDAB7986DA54E65EF6B536BB4F7BFF468E0F310803DE28D3908492343E4CAA855B8CAC7409E3A8928E63B9C5D1CAEA7A408ED061809DBAE1AB1A67BA1B926 +136: C58867D309CA48AF74B4D7E49ECED514C89FD433F9DD842F9B50FFAA6C7810BEF35348D00D26DCBE28122BA1CE33D4CD00D09BA76F982A598B8F65790368AE59 +137: C8B1D6B4778932BC21EDDBBE4E48F7711D7E97ED5354DCF11BE98E3110510FB007948C288FD2F7AA71B2E41C86330DBBCA2ED472D15B444828C6DF4282815879 +138: F1C0C057C974E4C27E497EEF52A02963D5957EA02C7E1CFE06423048799AAF74475732A7352220A914BF32EBA6A0B6FF28C77D25CC3CA1AFBDA89870F4EB55D7 +139: 092E121F2C7A2621AA36AA9B040EFE4435DD649E3F336BA82788D57B9B164184F5B5BA644DB4076B46FF9F3A6B9F58D775CE94FEB648A372D960471A663B74E1 +140: 406A5382E9A563E60FDE5CC47F52C6DB86CEE271BD3974AC6E274A1B8C5A7EB369A9B7CD312C301F891D4E3A601A80B9CA06303C53CABD5D3B7834DBC5108470 +141: B2D3EFC2390CF7A1093B93C52B76D0DD74BC277F3D67A85F41635F89E923AEBC960B2BDF8A13860CF3083AC3FBA13D4FE5E426F144FC988554E89ED7A0324748 +142: F1F7100636AEEEC8AE93A2CAF1F4852F192E1EC1AF13697765CACE58FB40B9D9AFC3BBE7E52EDCE649F53C1BAF653CA20E75D3E4AD549D05EB33A68DD11E1898 +143: DB604416DFD0A7DC509DBD2C83D5FEDE5E31D641EE6C14390CF599CDC7D841660AC700D3DE4BE35E07006B724B7DD1BAA21EFC3CA6D346B3B858384FF691F913 +144: 87AE00E496649511C3BF947A65805ADB5D237AE8486CBFF01EBE52D5D5062A99DB3434EC22A37DFDB4CBA1A59AF1FA5825EE3DB2A8524BDEAE07F3264989B85A +145: F442BB697D498F2026FA2A5FFFF9AC5ACA0052F6D200E10805104D91BDFC71A3764CE0277009229B9E7C945222BD7C9085163987E4CED02ACC7420A96B0F9587 +146: 1061588877909CAABFA37D4915EEBD6E517B8D3EFD5660F872019050B3C1465F11FC9B44E72610219F3F5F21772933F101D9D58B5C5F79FD7457F95749BF11D5 +147: FBB4C9BD6821A04CF154DCC7A7507A2C655739F3636B69E8183418E2C33D951DE6BFDF2C3CA603694C44DE44057665EA4835281A2773CB8A84965BE02DF1F3E2 +148: 08D54B05F901FE95EA5B56BA19DF9120C66AD004F98BF8FCBDA9DA0874E64978EFC34877B8224A024DE12D7B926B5D83068E8A704EEF0F738A5061E5F8462F54 +149: B79F53A5117503B5A0316F801B8D448079F38CB90CC39BAFD4DFE169E3C931D622AF7E26835C9AD4DB25C0D6A684E7DAC4B88B475663E05601A99EE9FC8922EC +150: 2209CF6BA43F61D7E579651EBBA0890686A9CDC1E045255494DB0BC732C9512ACBF72158D5738FF63B500AADCCBA000D25A521D41AB4EE6D92D38E8077B79C07 +151: 8236F7CFFA68B49BE5C38A7A1BB67B745430D1511A08EF347383C32AAE1EF4AB2E7F63A20C9D8E5CF2198B32B7BC79B470D36BDF12E7263D669FA4AB8605B75F +152: 228BEFE5788090066D493CF87F75C666BC3C75E0B7BC63E80D38340CF9176251C6E185992B244D4A5B1CECFA42128DAE6EC3ED535AFF039769E364048C442DCF +153: 59171D498BF80731E2E35D0A32DA356419E69B8BAA5B1195D690CD8A5B11542087A007D8DE3FD000BFB03A0408C08E92A0C7712924373FD67A65218E4A4E0F68 +154: 4F94A8F6A136E49069C88DFDEA9361B34D68FFC25724F836CCB021BDB74E0AEE9DDFE80B938A5C12B01F0F1CC49C500FE7709C2090F809D9E0256FC93D93122F +155: DE5E17A668F75866262BBB2089C9DD86775100C77974161DF46BE02A9578855E7C81C77263105C473FD1A2D55483063970C0F643CB25AA4B4AB45A40888F61FB +156: 3314001C825DFD2CD1CE08C746F0BE5C451027F0FAA401431AC84FAEA51553EFD9E0646FB7E9B94CBC672DC98FE9870467C176AA648EC72BF61334B13E479E4E +157: 3EE80B1422E3572B46F7CE5841998BD2B6DF3B591FB5E46851B4D54BF572A17DB5963A04EC6AB98BA07C943475AC088B4D201AFD684F30F45C8037400A7C9510 +158: 3743FE18BD6AEF36887EAB7BEBCE36D5D3B69DFC306B58B1E8C6241E81A9D38425BA991A29C3B07D4F4B9C5CC762B2563C9E5A05B199CEA5833D9FA0062D161A +159: 7F9F71B086CC6D6B63052767CCD6D0349C076289F63483241CE105076B7549B3187897D45D7B5FB2147E54F056530347A1F9265E6F37953B5941272A29E2FAC6 +160: E09CBBFD3DDBB24755CBE8E51C8BFF1BFF36E571EE72E6C99DDA6D507AFE3C562D437E8612B50859AD5CD608424DBE625E0162E6CB7B838F20E7B2F93F40ED91 +161: 2E2F91BD5FEB5C79E98ED97C513E17D2D97B02A844780A0190264773C3040A2CF07FCB0E6424B7A0E88C221BA3824C1906FC1647AB40DC13E2D0CC507CBB6BCE +162: 8D4E87F66B3418105CD5583A92A2D2EBE8824E1F9150CB872FD3DA9C93D382C08065C818E1AF9B25875B142E70676D9A525D901EA2142E42D813A221D21EAEF5 +163: 0518E420BB5680B74367F8CFCF7DD32F3AAE009A0067FEC22456CEAD0832BDC2A60D8AA7B0A2FDCB9072C0F1171772BB665C0B28CD184609F63AD53F89597F9C +164: 247197FBCBEE77B8EAF6358F71A49D784CB43FB44D99910B0599E69B29E31C4019E830F322D5A7117A996BDB4D91E5CF323DB354E902E4DAEE8057B3F78ED5B7 +165: 35A7D806AF0C8167D1505B25EDB565E931864C453BF60AD7B6695035D7584E7714E21F377B35A5F3A69878835617B951977C209F5F3C5967B7DD9BEAA75A7CAB +166: CA9B60EA8DA2D0BBF46742E31AE882F5355688B071883F690AE775C4D949DED8077170F26E89A18CFC251662EA8D1FF43F5A5F28E3FB41ADD741AD2E28341A79 +167: A861DC64C745B0F5D3EFB2773C51981A836024BC420B1FCC564E03006163B491126AD8633FADB6DFCB25C2EF92FD82823FE2C7F1161A78C7766B5E21F96BACB8 +168: 1EE6CA0866F227B27678326FEDA4CBF59934AB0EA2E874E9EA233AA5C67141A05C1B4C950044BB6C9B9D146520C2E3779AE44187BE0DC1CC41FA7F72500B249E +169: DA1032057A25DA7EF987A2D7CF28B927D3DBD956979679F5A6BF4EA20FE1080BD8AF2DC8B1C7E236E7601BD82CFD64DFCA7D03A03087475ADD57EADFFEC2CA85 +170: 22E41325474C7C7EE980314D7738947E9CE3A970B2D28BCD69D545D5E795ED50A5A1839021645D000CD4779E181A65974171C15B9B08B349205B87C150688839 +171: 5FC5AD1B8B7622C4D17CCE23679FC7E0CCEBA00C1FD7178245206F866A6BB198F26A05A3D429E2C508DAAC6D0F698FAE6C0DE7FF971EACEEE84813110672F3AB +172: 2264F674AFC9743A46180CE4E4AA6A2BB33D6BF2F62AA14648179400806D718DEE8FE57DA48D88DF5D57B42087BB2FA62F833BFF87B6678606C6336CBCF34B3F +173: 65E9D1187801C74FC23C4F19698F6B93405C681B93A80D23D427D9F2CBFE63F7E2959B2AAD6CD7EF6E987A5FFD585E1BE8E314A1D502FAE80215C5331F8FFC2B +174: E0436B17C2BB096B08698F4CB448287D69322C34814776E0B1B21486A2D5B6906889A5B198FDDF699AB285BDF58783DE7913075F86ADA977DD35FD09AF336E21 +175: 857BE6485722B4BE445B72C7A15A1D0BEE6C7FB2AD541C2B4F0035DFA1EEAA10D4F0BA5A124F985DEFA53D0A0554BB258B2832BC2CB5B7787D812E96A55A93DC +176: 7B2298654B95CD00307D8D983A0079CCCFD89E5788180CAF352B6C965B9BB5153C9DE25C4A0CBB5E578859660696C887280EA378A2E02B7C7F9E6CC635509EBD +177: C7ADECC928EF065C263A97A273CE8CB30485BFC035F2FC02C78AE2AC6B7F7ED20E93897C0994CAB8D584EEF9DD475AA1613159A0C862FF179C67120F6B4C72C7 +178: 041A03CCE6696653ED5F367749AE1AF3C2654E8A9C0E70E467261E60023876C7271CAE545D114C32D38DA75389525CF0CF1FC0FA9A481ECF43FA0B1F61B868F7 +179: E652E4A88EC1A9C4678F8CFDBFB1D758774600255165E2B4DC15F61C18B9ADE14C5ACE7E8AE72D3062B7F1787583C55B14B347F642344E71D6E00FD6F4C56808 +180: 903675FD8C70BEBE9FD0DADAB17A638A2DD8089AE63114E36D28F4C75D951D75B0BCAB5247803551862720713AB45A932DBE141E48E9BF3ED9E76201577DDD43 +181: 6E61016D474D2AC2984E4EAD44ED82B7129B0B7FF0B9AAF5F45CA68B0529A736B846626CEBCAB9E7CE374D744E7A09C51BBBC746D989806F1A00703A002542FA +182: 20085D4717A204E896F10C5F7E1FD429C9AF848FFF608A2C46D3738EE4FFB944381880A7A455FEC6A1A21754D9ECCF3F1390EA22EC17FCFECE2B86E361784045 +183: 37216CA069259BA3244DE3933A3AD5F35712F0AB7B9C81D64000F0B91DD4232B53748B704E7ED0DD682A77D84BAC1B943D2FF7A3DBF5FE33DF455DDB10D11632 +184: 1F2467A57006D96FDC75A8BDAF98907AE72AD330C0418B06513C33D86DDB800AB6A51738DBFDF1C44676038C094EB5F309B5B590EAAADA4DB09FE7590FF04888 +185: C45893F92AC3E3AA3BC86A9ED659797A7C7DB949A66552ABD046DA2AA7DA9E52FF8BA2673CB44B2CB0481D599EC70020B6D5079296F2C19DB162DC8CCD64BAFD +186: 9919574ADE9B8640BB0EF45F98D1DB6FB7242C433D86CF6D4BD67AD14FF15D74A13F796429E312BAC581552E6597BAD2792F31B2488ED300C6118891ADEE9FB1 +187: 034A92D00A172A5F0CE717FC38AB8D68019F500493899401B563845EB604ABE0907749AA830F91B53AA7C89DFFF86664F8B123AFF4721D790A58CC22F36A560C +188: 54714E69859C60B07C7FE34859C855A37A82204D723F1A695F78D7765CE906D109FA6144EBA9E7E7A7D8343A99495E72D160DD468BEFB794D97659B8E2D8F1CE +189: D6CA476F7E68095DFCEF4338BD6466FCA90DF78A17DE9E29111D4645B0DAA0C6E98F156C0EBF9134BC28EF9E0EA67E6D839027DD5CB084E9EBA899DD3413E222 +190: 86EB8C026D6BF090636F01F623CD98B960D08E521E44697F364BC1AE1655B9AD6FC3EA38C929AC9A244D18E697342594F3E7DFE605954579AE4042CA69E65AC3 +191: 1F63EE615E9B809E3661C77B5029C78A92DC4BE3CC4DFD8BBE78DC7B7D990BC717238004969A8B854CBA04B4D9B30AA1A1964264C47F23D9BCDF45C74FFFD918 +192: 0351F475C711D068BE7B0395D65343B5E249FEAA3C3F3B6B87100C50306EF0340F60EF36233F0E6287057EF7BE8634BFC4D46B49E4A8F2CC4839F42F486A16FB +193: 16645F9C0ABBDA602B7436DE3B1C55AAFD1E844057D51EF80A96CBC2FAFF6E3B2706B45069C90A52D779E101793EAF4C9AE85CAD0A5A394164F0BF34C189A2A0 +194: 821E46199F4FEBD9C118D49B1CE9FFE953113EB6E4E33DA9E39C676399A0B3F792C2990A9F75D729E58EF750857C07336526631CBAA5EE0643699C8E7B7EEA13 +195: 64CB83ABF2BB0A94451F2B9C3EDD76E4A15F9D1F9EE32C0607F5E0951084377E484A8259B3C64428293396F78E6674CC3C027CED1BE12F5671D328D131740770 +196: CCC1A68114DF54BF467EC49CB15CE381EBA7E6FF06A93EFC88F442F8A35827D5DC6494A4F39E8423167CC1C3269A3EE6AE68825FE3E2E40EAFB75C8D878FF88B +197: 94D38693F1B1A8F1013544419C5B3BA0CD79B72478A91CF3AD325E4C3CDCE092AB667572233A4F8DFF132401968BC74C553AEEE96D530CA4E5F6D427F9D2C422 +198: EB080E256FA9A5D51C3DF577509B877563958704C0F1DB645F75CE24005D3B12503BDC26FD3A66E8F6882D3491428A4932EED6F5F58532FEAF521BA5FE05B70C +199: 9A43D7D0C42D7B5409963339C9D9805BA59ED8A63DB144165A3C759EB9F5D756E6288308DD2FE460CC50DE26E1A1C1747AA165FE6C8A1FD5B0F7CB1373E28CAC +200: 986058E9895E2C2AB8F9E8CBDF801DB12A44842A56A91D5A4E87B1FC98B293722C4664142E42C3C551FF898646268CD92B84ED230B8C94BED7798D4F27CD7465 +201: 9FCCC4EEF7571A2BEEE06981856228CEDAF3BD412E777F4AE8524B81C373FDBC210795C1E788EE7081BA42EC3FAFACCF2F386A9096AC719E6565B4E384E390E2 +202: E4E8BF0BF40249236FB88C442E6668E3067ED6001189053A3A81EB755798911258E25CACF7282811DD5E5147811844C4B5BF52FC24A6862BCAF9407F2E38EF5D +203: 317ECED703044C1BCE944DDA7114DD1E36244DF6A533790FAADBD0B8DDF1AC0D198B593F0479A038198F4B94AA6ED294168FE0EE800C02E769EE78ED45249945 +204: F5FA1EDDE359173067E463107FCDF00EF227CBBA0EC5EA02EBBABE2C79B12E793B98FD3A90A72BC26240D994F53DED65FE22C6FE87EAFD01B8478D1E8569A882 +205: 6323E2A8E380CE86433D5B8FCC5E02FABA4ED7F9CE5BD194F7CBFA36F65844B61A7BDF8F131CB4B28C56ACFDB99CD84830557C571FD369650B4608376BBE4FDC +206: DC6BDB69D1C6111E280F993635BB59CD6E7B189166DE593B71E194C5F218D67B00EBE0D028E944976D6538DE410C4D86A2B6F272BB94FFA590208C644F99240F +207: 2428590D2043634FB10268435EA90ABD082D45317D2C54D065529F15E180438AB18FE4CCC9129584804EB04EA1CFF646FA881878520BC01AFF392B6D7D9C0369 +208: 1A29341BEF679E5351911809DA190BAB8E665A9375BC2D477742176A70A6BE8ACE4A35645BF8DB97AB9BBAF1F0313004AF8B4CF10ADB26AC0198AB1D45D05C46 +209: 0EF4FCF3B2010921C58056B2BA367B4C09F5325E6AE9AD732AB277281D4BA797A847B1C6A74D81523DEA163AB0E556FB5102C14E8CD94AFBAC0AB0A921BF1A25 +210: 73C65AF2A53E8860BEE63AF0BD8A457B0AC8D3C5D243FBB1BC3D67624727CC175F3CA133B26342C3401D75DCDDDAD9A692D9A2B1264E90CFFD4BB9E6E775DE15 +211: 18D3DE049396E2EA541E15C31C0EF0E0BD90CCC6CA35663856B94F6F18160D616667C55F3ADC1B33E749F60BE50514A4F3BE48ABE2E18FCA10F85ED0266972D5 +212: 34DED45ED26FE224E0C5A66A193C11A2CC0786E61D421034B3BB16175019C95453F20BDE865DEEAC5C2BB5C86544641482B51C4E61D9DDACC238D050CFC35776 +213: 025D211B55974BAF086B139D8FA1AEA75B627CE1AB894D52F8769874557BE5944D27FD4BA3606266BC7F50D1734436C53D4555A1D2DE0DD2AC51D7F2FA373867 +214: 08CD521B1F13440D57001F30BDA0029FD8AA17FF26AFECEFA2CB7EE1812FC79A694ACD0BDA98184154B72FB7CE305FF4897F466CBB3972B4863FC88B3DA52C28 +215: BA3BF464071BDF124034CD122451D3374AACFBBC916C858B93E191006235F4D741564BA1DE70372269C122D360121DD3D427853BA76C6B450BB46F4156EA7524 +216: CB0B3250639B4ED947BE0C83EEF67D370DE76AB901F607F68FBF1BF8ADA15984DDA7BECAA4D7FDD55FBFE479EEE3F5ECC9CDA7BAEDC9DB7D35DC227411DCF20E +217: 8AFA4024BD96BD50323AFDCF92A7F3E7BFB4C927108CF81C01FD378F61C55D850020DBEB88C6528B8FC141C37EA4852481C14902878AFDE51A7F1EA1612D0324 +218: 27057269EEB73333A1A8059D6C9D6FD5AC89EC26500F6F9838CACEC20E93F1713CF5569E820BD80969547D77E56AB0CBF57F03182EF45AC8BDDE114470C6DDEA +219: C79C3D4A4608C7CB4A3D0C14B28CBB96364F44DD8651F36D908AE502E547AD7AD5DFC10DA26CA26C6D9E51CD40F6D7F1BEA0A03358967D867A97333DA8ADF3AF +220: 9DC3B1EF11D85FF8A57330FDF91D5B5AB142FB89A72D880DAE476E020755C2F3B4CA58C9ED36239E8807C059BD66F826EC517B7A44187E7216E48B683B567076 +221: D11A97FB7B967E90C2D39EF42EBE49327CD58EA6977C84275B01698E322DD97024A40FC3EEDD96207310708F737E81B79659A6C7202E96BE7AA34D18D4026F63 +222: C9BD62C0FCE47736ADCD9275B46845E4ECA23B73678693FEB8E21909EB8405D4B057AF2AFFD7E667E047A07E6ACCADC2A58D7360C17689769DB009F0A7795560 +223: 7FAFE6ABE7CB8C109B18A14BC4FC2E4FFEADD55A43AE7DFC58D89B9CCEBB4467FE4CC163FF6EB16C8C71B8EFF12E7891D11D3DA2C6DFA8152DEC52B232267B6B +224: AEC37B2A1157708142BDACFE77E5204174F539D86A12730BBEF6386FCA098AFF2A5C31EA1AB21D3B4537531DDEB27CA9DAEA22F5CC8C9956B2F2595F53BB931C +225: 6B005CC923D9AFF56334CFC7A5E3ECD70E97C4247EB372A3180E7DC5BEBE676E72E2FDFACB74277B70E15D871819626F46661285DB04B3F825C49EEF42391B5E +226: 509B5C993CDF61F8F507A84BBD7D6D7AB090970927400043D39E5F47DC23AC289F5BBF9D3246EDB174D9C5D72BA7A066DC13171EC15FF9508911464F8730D395 +227: 00A05302C3A60E58C4C52847F47379212A918060931A72BC660D88E7BF5599DF6C38DE92452B4823B4725BA3EEE866235CCF4D5903E91714CAA230C6D6EEBE45 +228: C4FA5EFAA31CA205A732FCD5DEBED53C09A4F30C5BD9ADF27F8C1DCD4B2730925BB6AF176E2E680B2BE325F7DDEFBC9EE6C1CBC4F0426ADCB5CBF18D1437EE6C +229: D125006B8107FA63C375A79AAA0EBE82017372B7CC65C3157CE078DDBDAEE8C569BB84FD8490F2D66D15FE73C6881245761AB2B1D4F056637ECA70641745CDA4 +230: 01C7D098DCE4E40A69DE14682587FF2A40BAF9833BDCC6413AB54DB0E64262F290D584CD5B21C6558682C50E1E27BF53A18A16D72ABDE878C3522156C9F04DE3 +231: E863DA51CAE09500F589BE05CAAD5788587E2017907444D76F547D6F30632AC658EEB8585733BBB815D2E19EA046369ED3B81AA773FBFFAC316162389E015A71 +232: FD8232F7B79BDF9CC52FF0D5DE1C565E9D659BF19769096895D182A88028C1CDB7387DD240128A7ECFD2708EBA7E9E3C676D6E2A036E1B993940F5CCDF1A736A +233: 3BF8572CDC7B825CE7F3222A3DB87F1C52FBD1A8229B957ACFEF2047C560567483C479603A3C0B0F1B2DD265BEC257D1A32C651508D7A4DF501BC015657DCAC0 +234: 23FC530B031136A17B8B2FCB55046DE7271312EE3E77851FBDB05F78A294815CB2169079168E07647A2BD5D05C1BC2B1EF1B64B929DAA1F9CE723D448C936FEC +235: 83D10057C7FB494FAAD289B4FE5F093DB2A0C7D79A298173DA735CD5063232BF9E5327A7B4AA795C99F323045790B554476F37EB9D04FE3DF40C047E4113A720 +236: 0AA201EDF4124F421D4515554A1A642E3B9D18C70E09E83A886D6F0CAB0750D9BA1FFEB9C587F3ACAB0D8B9C1D83D789102F0E2A6CFF885C50F485929DF4602D +237: B85CC52981751513B917F58305AFFDDC7D901CB3BB1D1BF5DAB058DEC9B8CDCD2DAE543D73EC6AE0889C9D785F9178D207059D994E1C80706EB28AE65AAA100C +238: 068FED72E55444AE108EEFBDD59A96DA4AEA3D81A6642742C38BBD4EAAEDA6EE21FB8702C2F95152F1F997A5F40F06C54619481F2EC343AD33400913D6FDB4FB +239: CB4C7FD522756D5781AD3A4F590A1D862906B960E7720136CB3FB36B563CAA1EA5689134291FA79C80CCC2B4092B41DF32EBDCB36DBE79DB483440228C1622A8 +240: 6C48466C9F6C07E4AB762C696B7EEB35CFE236FCA73683E5FAB873AC3489B4D2EB3D7AFCCE7E8165DBBF37ADED3B5B0C889C0B7E0F1790A8330D8677429D91A5 +241: 4F663484EFCA758D670147758A5D4D9E5933FE22C0A1DC01F954738FF8310A6515B3EC42094449075ED678C55EE001A4FB91B1081DFAE6AB83860B7B4CC7B4AB +242: 81A70404857420638D72672A2DF5A49D52B9F9F38B385D8C5129D6A2B82A682CFEAFE6509266E4B00F6B6A07341C2F64E4D4F2152583ED143E3DCFB14C1C216F +243: 31F655A1334E1A45584F12A22E03B09E3C69ED0E1D0FD573AD0D56F9C86862299E333ABE78590E97EEAA5C2FB14DC9F34FEF6DDAF6E7A9BFBF68CA6631195CE5 +244: B62C5102F97E5C4D7554790A4CF53A58D3EF44C83142D6E009BD1F6FC8F3A19AA1B89DA8DD9BD1310827A5BF662BE7CAC750C48E6ED91313E940D7D9E5EB9C22 +245: 380023C0BAC4C9524FF6778BE80CDF195E36FCF460E8CF1BF04E5C2FE08E38C35F183FBCDC3726FF26423F351C507279F6258F2319EA1403B6C8A3DCB384AC7F +246: 473FC167C7C4BC40B17DA039EE09FF3DE884879557E40C52C1981AC419CE021A090BBAE014822D05714077008988D74FF151C927AA43E88CD63FF2CCD2012AF4 +247: 006086E61959B1D66C72E754427EAD5E1D6C02D8409F5C32B2F5AE448F54682B504A1ABC0346CCF39BF66A8C7B69081E886B47A7D0B02291462391C95351EE40 +248: 3828B2ED548CFD0B74BB34A1FEAE030E267222198D7E387E7FE3ED503905A25D4C3301A9A47E78372F685B05847062476C507708CDD75580ADB579E4CDC79AA0 +249: C26A7D5BB103EDFEAE2F1201BE58AAC127F69AE378DB04156074E991745D4AA5AAB3BA064407DFDA8D34E573B7EC1F9F37CEF01ADC17FAF393C262A09F2C4736 +250: DCF82307195035A668097514FF1A10E0BF0E802B4945A702D2E17AF6DE1D3D9BA49616DFD16D802054B5219CA37884385E87A713B4EF5C7FCB69661C7F56D5E3 +251: 46049EA0DFA5C49429E15626AF4AF2CE0A9DD2F308B99BA6E6E3F3088250A146870FD0B53228D5A1F1BF9859480E1B7A3D3DA180AEF4D5D41BD2951C4E19426C +252: C0A1FB6C0A65A0D1AF46A5FE86C8A88E8A86F83E36317F435542927C98E74833C887CA3AB5E792CE5E3E21CC6C6AF437349F5A66FAFC4DA79742491C643901F9 +253: DCDD20CD47B7C7D011E9DF7855B08336BD5007C4435208BD3B914D7E503B8399164A155697E68A1B88A0600BDCF847A114D98FB773C81FEC817B92057A6998A9 +254: E2DA07644DAA73B66C1B6FBCDAE7FF28E3B9024F0BC5408FE02C18E3744CF9BD6DD54EA7BFA1F6F3A81C8560FB938FDFF9A38A29853A3A819B58D10213A290EC +255: 15025C9D135861FF5A549DF0BFD6C398FD126613496D4E97627651E68B7B1F80407F187D7978464F0F78BFEEA787600FAAEBBE991EDDB60671CD0CE874F0A744 +256: 1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D + +Hash: rmd128 + 0: CDF26213A150DC3ECB610F18F6B38B46 + 1: F069A435C14A8D4B02A7BBAEE02D0BC3 + 2: 48456EA1CD4C51DD8E1130F625DA4F8D + 3: 6E41F2AE95605779C74CB5ACDFB361CC + 4: 0C7A6C73E99A5C65B12D3EF47ECA9D2B + 5: 3B80361C079D1B67933455D00AB1428E + 6: 0F74C4BFBFC740A027B1D5BB9CAAAFA8 + 7: AA54ED5DA34CE9205B64D138538C0C1F + 8: 08445C3C3E71434DE375CC2071430EBE + 9: 1FE0AE641DEC6F8C172F0E27E9E73B9E + 10: 4E8152B7EA8F7A31D8649A51389260F9 + 11: 0F851C98C2B997C2459B34CCB209E481 + 12: 52D27461FD7E095EE3C6ED43BC24EF23 + 13: E9F3489135F3D90EBBADF9F916C34920 + 14: 36D527B693D6531A5E4E15BDE9E4A670 + 15: 57433A07CC200953B7FD440253D5E476 + 16: 4A91FFF90756026A90A83927066EC911 + 17: 5A247C26BB1BABDF1009B6B4951FD76E + 18: 002DA29AC9F51F065A1E371660BB67BE + 19: CFFED09ACF01DEC9D3891033C0973953 + 20: B78F28AD3460C99D428AF24E2787EFE7 + 21: 5E203157AB6BAC57660F3D25FF615C95 + 22: F128F5DEC3A24AF34AD3E7F3883C8051 + 23: 2E05AF10A6CE9AD1E0C0FBCBF69B1C9E + 24: 67FAFD9A5CEA5D41863D03AF2932C5CF + 25: 5ED7E86651AC4BD0EEA718C773812977 + 26: 6BC74F78256A98761981882C3CF7AAEB + 27: 44CC573B964002D877E79B75E4433E41 + 28: FC02FF53665B52B58DE38784E2C28E92 + 29: BC4D69312DFD24EEA219F29FF2AB2072 + 30: 0355E82F130341EFDD997EBDF4469221 + 31: 453D500D997FC85F6AE16365D83ACC05 + 32: 42DF4C5A3844F00F77ED84E125237113 + 33: E782D7162BB54E735F7B9FDD75A3F14E + 34: 78993013EEEA7B14999DDD3979191D74 + 35: 27BFCEF540F0782E9A28328E8DBEE59B + 36: DCF00356DCD264B7E359F02D7D2CDBB3 + 37: 9EE0BD7F55EBD844A8D114F83B3E8FC3 + 38: 01EF8F3154BA9B9B817AE717FEA00A68 + 39: 4DCBC2AA56D785CE7249761791442BBB + 40: 10282C07B870BCCE0C8DF9E68B4C5DAD + 41: 0757B359AB2D1D121BA01BB345A12A87 + 42: 450AEDEE570A2E9B1A19D5B4747B2AC9 + 43: 2C45713898BD259B10E2352BECFD6DE8 + 44: 3E92731175E510FCD07D28AD47DDA0CE + 45: 6A8E5690AD4AA2180966AC1503A81A18 + 46: 820BE195E2AE85C115BFE3C341567030 + 47: 9C97E1F0E7DA29A0527AC4F59D520100 + 48: E1257842EA15216543BFE84521B9FDC3 + 49: 42BA484CB70A58EB3EB5DA43F1D5D5D1 + 50: 2C674397A81CA35EDF1FE77B442BADD3 + 51: A3E07C012A7C67D2B6557F4A8B4DD031 + 52: F01789A2E0379CE16D87EEDE671171CB + 53: FFF1657EC846507BDECD2DD829DECDA2 + 54: 1673DCE23D430948AB818D47E83BB5CD + 55: 37CEC696967031AB2122155998A07F51 + 56: 320B7D4DE17A731B9BA5CBB48956D605 + 57: 1EB07088E5F563DBC5DD988ACB84B048 + 58: E4DFE704E4C25D06224D2560B4650467 + 59: 6C072AD491BEC80667A6D71D9C8F2FF8 + 60: 53DA8AE3F36FA8F85072A89962F39B76 + 61: 40210D1C7A728A27E1B5F92057DA4765 + 62: A4C4E5F271F3BDD74C560787718E8816 + 63: 4466033447F1E1C9BB107D152BF06051 + 64: 406C6EC2643CCEF38F964864D12C9191 + 65: 19F725CB43B171DFE18EDCB90A9DD900 + 66: EFAC3C9FBF1AB0C0F3601C18FE3F0212 + 67: 9B9BCD32F735EE353D33A657C2292475 + 68: 68F4A4294C640BBE4B1E90FF107E05AC + 69: 3630FD1C9542A56C851140A7D76C0D00 + 70: 21AFDFAACDD8FAB91027A61F8DAB6C91 + 71: 2C7AAC93B6CD1F8E23AAFD49F04C69DF + 72: AE4C5124059CFFB3B823E68FAC8CFB33 + 73: 79E95CB7E752863AA87A7693D0677D89 + 74: 1B491E33A96D9838398A4F624E773DAF + 75: 1F3986FC593D8A8E927C82DFE1F538F8 + 76: CE64F09024A907E76726E29E1364E606 + 77: AC98817981B59789E7C7E9CB9F70FDC3 + 78: 3827B4B077493B289C25EC3E91B36D26 + 79: 75295EED68F750E506C60A780B7F0285 + 80: 4FA47F32992EE6C96C3B96B6A69A6656 + 81: C52E142B7838D731FC036517003FA73E + 82: 3451812871ECD1C09E4A95CDC80369B2 + 83: CB5261A793A55DB33016ED27A35A20F5 + 84: 2D06368ED98E266E81A3C6491BC24890 + 85: 677F6509BDB3D44BCFB088A81BFD96D8 + 86: 6990256193FB0697862AB5A45FFF082E + 87: C88D698EAF83E446C025EA915998EA01 + 88: DB8F672EE8129BF4BCE25704DD57BFA6 + 89: 807F491456D7E28A36AD6E934B053EA8 + 90: BBFD55A483CBD0F9DFE18FEC5070A166 + 91: DF7735106411CC29535664D85ED81603 + 92: 24FE3535DFCC295C2F34F3F88CACDC88 + 93: B80CDE220C4199DE303BC97FEE125048 + 94: 8C252310E9A71C7BC40C3D2011E24EA6 + 95: BBDB705F5660C50C5B0C87CD812B76FD + 96: BD517928591240C7E63C8D9F957F6A4A + 97: 78A534AA0F4250EE83D752F3E6940148 + 98: 3346EDA882F00D6073D133CE609D3B83 + 99: 51EB1D3235CD35A2386E314F815588C1 +100: B4860192E79C1233A08FE595C084315F +101: 79EDBE3E80887B4F741199295347117E +102: A2793EA5F25492D32D315B3923E945D3 +103: E398223EBEFC56D3437AA5FBC5345CA5 +104: D3E6593D69B24069AF0374671E466930 +105: 12D63F5AC48F99BD59EC863B61952C1C +106: CC99A81A22B62A0FCAB4AE889112A8DC +107: CCC82CA5D35A421FFF313F90B9D1A675 +108: 5B4A2912071CC36CEA626F9AAD34F257 +109: D21FC82D78AC98C5DA436388AC9AC6BE +110: C2F22C7C16DD2E1BBFDD2BE7915B869D +111: 2B5AE5D14DC053558A1702959367760B +112: 7A6A3A6553B2C3387BEBE119E80CFB2B +113: 7E2206BCF666B89341CD7615D0291E3E +114: 93D87A658259C7E9FDD0BCDF93A24356 +115: BDBC0B062FA3D743C1B070F2AB43D180 +116: EE0A575AFFC966F58B91BB66CC1E6B6A +117: CC24CF8DF0798ED2CCED077B06AF1BAF +118: CBAE264BB4AE635A15D8FDCF7F9A6852 +119: B879B9BBF61B6F291A8E4645B70EE06D +120: A6F88AD4A16F789A58F178799279B40E +121: 3DCB6B1674608B11F496F45C9828F90C +122: FF34A1C7748C5B5F2F014ADF57241C43 +123: 1A77E2B20ADE5F286705251495AF04BC +124: FD47EE73738626733CC63327D4F5EB7E +125: B9438B50CC80CCE0303244713853A0DA +126: 040BC7876B31E22590F5898068B19859 +127: 16ED82C338495D067BBE1D4AE73345FB +128: FBE1AC0EECF0AA2671A6F25733E9711B + +Hash: rmd160 + 0: 9C1185A5C5E9FC54612808977EE8F548B2258D31 + 1: C81B94933420221A7AC004A90242D8B1D3E5070D + 2: C0C355CA556CFE356ABC0A5595BAB1364BD86444 + 3: 6D8D360567AC2CC8C4EC11DEEDE0ADCACDDA388A + 4: 04DE53FED2BBFA80FA79698B4C5627536FB620A7 + 5: 9538F24F7432E952F030BBA82C9F744365035197 + 6: 817ABE77EBB7EA159AF7BA7DE1EBBF034FE6CAFE + 7: 340835AD791316DE50DDB59838F3EB13F5521228 + 8: 64B7269FA971B162612265C73B9911F53EF43B63 + 9: AFDD1E7F8E39C63DEE7104014AD9EB32B855E0F0 + 10: CD2E472470BE8FD70A306DAEC5C59F485EA43929 + 11: 550844206034AA74E37D813FF29973D3000C1DBF + 12: DC24FD5F309A7BEB9A7CFA7A354F2DB2CBC15AFF + 13: A814B4CBFAD24B7B92AF0E16794A793DC16D10A2 + 14: 6C316617808A930BD29972B1142C0AEC89EF00AC + 15: 3286BABC7C4635FEC52F67CEFF1471E122D50258 + 16: 696C7528A3545E25BEC296E0D39B5F898BEC97F7 + 17: C87DA6F87A65CBCBC4B02BFD6D01E26F8047B5C4 + 18: F1AC2E0951EA5875B71723BA1A2158DB49EE073D + 19: 091A39765126ED406254E7F810F02E0A6124C6A3 + 20: 4002C0305550C5A726705DCF8D3880C54FED0453 + 21: 2B59904E1585334B1298AAE6EAB06526CAE5A232 + 22: 0EF94DF816593728611664F4ED6A0C4DA28C5AA9 + 23: FE7AB8A5B0CA3C86B6524E3333490D0430E9A4A0 + 24: E748023DDA7E4B77DE8A4424744331EBC62A6590 + 25: 96147FE511BC64D9493C795ADE8FC71A78FA8C23 + 26: D81D7D3B46D5BA875EC2604814616230D7A075A1 + 27: E8245E6537FEF146A2CF6AF9BC54472BEE6213F5 + 28: 231CAE27B96A78767A0915A529ADB6B72A8006B6 + 29: 4D6BE5BB6D29A15A259C8B7BD4827EA82F514425 + 30: 3B00599329120E535A5D1A46F35AD03CCA27F9D8 + 31: 2AF4160DADBB84707F7355177A4644E4CF577DFA + 32: E6BABB9619D7A81272711FC546A16B211DD93957 + 33: 1E374AB924A652FA36B395D654D226BF901B6A04 + 34: 67281E2EFADF2EA6211B549426D3A598B5E1F291 + 35: 993464E56DC035716064577245BCE99ED175356B + 36: 298D2CEC0A3887C93501307B51F75BFD5CF0AFEE + 37: 2A0A02BF4D63CC09978EAF3B3B85A4DE8470B025 + 38: 6236F6FE25D5157BA95BF49EEBA8987A6A301D2C + 39: B4DD7121567E8A428F16BBD5A8832FB2EE68BC0A + 40: 5FBE6037F8D8EFAA9A315C070CE3373080244496 + 41: 04D5E112C47EA03BB60CBCEB9FC8ED7D92A68C0A + 42: 658797C7756256C98E04E6718D9F8952F90DA672 + 43: 6A27ECD40BDA4CC81C599DE94D0D2904716FD457 + 44: EF5AC5B8E7A00560E79DB54AAD4B97E996D2745E + 45: E67EE5275910B48F7D248A8B844DBC041257D695 + 46: FFD256BCBBF0F3BB4DF615B4236C147FD09F4F1B + 47: E83A4B18C347F188301DD3AA78265AD3AB3C0311 + 48: 13968583BC017CF0C5043364A42EC0D97E923711 + 49: 39C33EA7C4F393C4DD4B882F73FDDAC2D7FE1EDA + 50: 50B0068D46AA025615053132BB53F88DC062DB2D + 51: 434198200766DB6CF48C993906FEAC2B47224A3F + 52: 004FBC3820002357434D6B8ADCF79BFA6F9E3DD7 + 53: 13F7A8CDDDE021BCA6227EFF1A71DE19AF399B66 + 54: ECAB85CA0C2AABF18F5359F94AAD7578A08AB5EF + 55: 3C86963B3FF646A65AE42996E9664C747CC7E5E6 + 56: EBDD79CFD4FD9949EF8089673D2620427F487CFB + 57: 635B0D05BE254D82503A9E1DB7647DD1B5D5D6BF + 58: BE314B818A657DDEF92DF123FCC17C1DAA851C04 + 59: DCFBF0575A2B3F64B24DC203BDCB46290B21791E + 60: ADA425E87A8DACF9C28B67E8BE4B204A31960004 + 61: 35691DD184E08A80230467ADC6E68599B7295A51 + 62: AD1CAEFC7ABDC90E7877D376957532B7D91D7434 + 63: 6D31D3D634B4A7AA15914C239576EB1956F2D9A4 + 64: 2581F5E9F957B44B0FA24D31996DE47409DD1E0F + 65: 109949B95341EEEA7365E8AC4D0D3883D98F709A + 66: AC745186C82DF8697458326051A6CE7E4E9C1C1A + 67: 5DE50BBB11C62ABE22E7EDC288B7D1B6A1CFCC60 + 68: 7DD54CC4E8C70A4AC55F4C0485A4DFE139253757 + 69: A5E0EFB95E6162F9637D58D3E4836F9661D6A34A + 70: 6C77DE7607A361D22852385E663171148C0499BD + 71: 3467662275B136AF096D84258B17CA5F23BD6397 + 72: 1C56A69A826F95B8971635AA709978A441E75836 + 73: 9094727596F086BA28956A6BB69CCBF3B2B29FA6 + 74: 8C0B6183C33E902C22F17D81D18144ACB7B66FB2 + 75: 24ECF7598894FFBBC7D30FB1EA47092F03C398CA + 76: 6A02FE0041D98AB7AA6916A5245BFBBCF6635C2D + 77: F3021EDB24459533488660512660DDFF7F451C3C + 78: FBB7561C0065C90D7B8182018EAE73A18288E968 + 79: 32784F0E354A20688359B6EE7FD3874714C48677 + 80: 8BFBA0972D36739EA808C37C07F2E320ACB4114D + 81: 74EADA88C8ED0B649FCCC36DE338CB538242FE10 + 82: ED812B77C12856DB371E6F7DDF15A59FEBDD6962 + 83: 27021F491E923CF0B191E13ABCADDAA72586B769 + 84: 47664874218C135C09ED40DFAC26E06733AD02CE + 85: B39E492616FDAF2480F13D6E46CEBECC1FF5CBA5 + 86: DE967F65BF6DF26150AF866FADCA58C45DDC337B + 87: 8F2E2D23CC6A2B52B904032119CE68649406033A + 88: 247FB8B2BD1BDC35D0C07EA10FD9686A19E4723B + 89: 9D1E80D5695569D0DE28587D37103BBB0701E462 + 90: FA5C338E7506AC5418C4FC2C04AA933588892D4A + 91: D6BC93880FEC0163E3F223C8A64BA0879BBB0AED + 92: 8F27EE9C8A923C9698584786B5227CF17F0F557E + 93: 4C10ACF2F404236E2DABED0BB48DDC6D00AC4B16 + 94: D5166CC6B779EB2D45AB3222181064D05FFB5E23 + 95: 13042EB8245A8C5DED69CFCC1F1DB264889CF5CF + 96: 07136FE8CC1A03673891BC614E29BE79EA02D627 + 97: 73C50B2751C502572492C801C28B02C7E9F61B76 + 98: 8BE4B71D50C2D2895B9CA359ECB69F90CDCB1DD5 + 99: 36A669D7C1DA8E23D07B29BD6769DC324EB6D6B3 +100: 8AE5D2E6B1F3A514257F2469B637454931844AEB +101: F16396E005FE5ACC34EB53E6086F477415794BF2 +102: 907CD2922CA5F62F79E17B28AF389A38066E2C9C +103: 62C9351A21A50F2150367F25D4C166C63E771C32 +104: 8809CB529232A0CB22D384B70462B64D93B0EC1A +105: A85E4B4260A836BF0DA50B83BE1080D98CEF8A17 +106: 21D2A0D78435B2590B2C6366439939B9B15246E7 +107: 204FFDFDFCA5D46CCEC5FA96A778BFCBEA70BCE9 +108: 01DC05D6006E12D2F63A8F061B00D18CCA135D41 +109: 30E67D3FC0A0A6D2F257AE24EA8C168A4B0E0F5B +110: 9B9454E2B42908E57403871A64EA5E930F35B70A +111: 9F72DB053BC5370C786E34013FB8DA5958000D5A +112: C1BFA4009BFEAA30ADA4D940FC40F97FFEA3FC39 +113: 26FC30BF64087DC3FA4CA394637D15F73B7687FD +114: 36106E0DF24B7DEF46E9AEAB7CE0D784FE619D9D +115: 0D82262E443C3C56565EE35776F95978E16F1757 +116: B19E6C73E94401020B14ABBF19A15A6F0C9061AF +117: 68ECB5552C7B7B26940A82B6A67B0F4C62EEB871 +118: A834797B79DBB564AE587003EC4B74914A1580C5 +119: AD430B4283203A7B7F338B9D252DFDBF807402BF +120: B89CDC109009F1982C8B34FCA446953584D3F6C4 +121: 8030CC5A4F55566958A5BFCA97CB6F40B9C19279 +122: D0CBD1EA711E2D405DA5ECC2905DD8A3A3E83C37 +123: ACCDC924549D314019C4FD1AAC6AE3CDFB81BC84 +124: 312933643FCAAEBA4DB9BDE6EF7D6EFA70E37399 +125: 47F11AE47E2E693EDC0B06351E935C9B5DA42A35 +126: E4C6AA211767C15E90935DF552E4EEB89F23AD50 +127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E +128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB + +Hash: whirlpool + 0: 19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3 + 1: 4D9444C212955963D425A410176FCCFB74161E6839692B4C11FDE2ED6EB559EFE0560C39A7B61D5A8BCABD6817A3135AF80F342A4942CCAAE745ABDDFB6AFED0 + 2: 2661D03372ED5C961EE23F42ED9498B451030EED2FD01F29178955529B2F8A758F0444087C82AED85540C8217E959EB8CB43EBBBB77A7E0D2980D6406AA2190B + 3: 7314E8035788304E57E68AC9EA89544ACE6D2379035697D91B98B64B105130DC814B67A4B46B4DF6C103016B8F7C7403E0B943F0291ED6909E2219B6E18E89D8 + 4: A6C01D8CB93A5CEC17A9BDD270B24C8EE78686CAFFC454F253D9B8DAD5398E52304CD57F30F2111BE78FD98338DD3A41FD8A45124C940C4A59F270100DD6CB6F + 5: DB22986F9FECA154CCF0E7DAD914AE8C0851E170D116E9B550C39B373F109FD073395C0711745E40233226F96B5FBF6C8EF1D7F8E2E4AF5375821C897EB18514 + 6: 793498B98970BB3CF187B0A28D353AB2EEC8F6CDA12E6D484CBCCDB96B2BFE6B5278CDB38C9BEDAEB59A8404645DBEDFBE1FE54227947E226EDFD36114067F34 + 7: 052A7C4EC5AD200B6B8131F30E97A9A5DA44899E1C6C31BBE078058630D5E208FD6F2F51A796F814F8AD048D759F8DCE442C405D96D6E1B1A197AD908B366E98 + 8: 219B01987262C597603DBC495792F2423E24A4BCD38825A74CEE8ED91D55935296D80E73DB43A78FDD6119233A31DA5940C6E335EB22600729478A20F61A56DD + 9: 4BBB8746D1D754CE91C27F3A6262ACBBFD4A38D100A65ADADD3174ED6EF8F6AD343F0ED2DF28309A6E979E02B12E732A3E70371EF1E0935E8A30B7C55146D9AC + 10: 81BE2AD26A90BF502C9514F46681276F927E916A630FAC442D823FE4D8EDE0FAE2E8384F3C267B56126F0C009BF8689D475C53425322BF8CD7F6C80CD2C725C6 + 11: FCDEAB03C0FAC7939E8478FD152EEC2408D4A6C0D829B55AFCC5184C50706C253676CF68DA3ABC1C1AEEB5822898C5194AC801881B8CBCC8DB15930EAAEE9373 + 12: F943E5CD2DF74699913B25EEF0B08FCA6BAE9E66BC073DF0BD950CA02FF17276F4A28393BCCCF6E567024CBC6C05C94EA912F1B07034AA375009F594B25D9542 + 13: 1260728E085D172EE82065B3F878FE21F550748598E72A40F4FAC3F54B72A99E6B3CFDA7141C7E5BE123757AE4332C8320786408523DFC8655D7E1F7010792B2 + 14: 67EB4E93961EF18A82152DE2882CC5AF4DD1254732A8FC1959147268441A80EAF0E0B68041F7CF013313ACAD044BD440F1E06D3E449D206433F3B52BE2C9E7B9 + 15: 9AB90A3384DA32A03B31DDA21732B398358DD40D7586E836CFA047961360CEA2F1E3DD0CF2D90CBB57F68C4334110694A6C1BA17B1E9E533E6CF3A3ACCEFF84E + 16: 112C2ED4CE732E21334D7248A30E683246BA602AD3681BAE365E857AA840F1F80FCEF1B9ADA33AC1F9BF6FB75045F9E61449B26F9201E482E7F2ADC8ED9A1D80 + 17: EF574EE7B498AA64F3ACBE1972E42B873C6FADE053A1459AB52D5E5B49C0AFA0C62FE901ADC3FF07A7D0ACC459C3DDB3F6D499C70B63F68B60B02E2784BB9AC4 + 18: C6185B5836DD3B160695E5E27058AB266EDE91A5417DC086988EA5181DF5BA0C51DEB11F6BA14AF2847540BE368B6C561CD976809E2D9982F4D49F96E0AF4F7C + 19: 8510D305A5E1AB3A0832B242ED402BEC2D70C24B41BD840B8D2DE436A6B4DBB7CB5F7F9F1432E694F0CB1239EAB0DDD92E6D0C7E96FDAD5F8E465E286D7588EC + 20: 926800FF566CAFAEABACA9990772EFEC8AC956C3C572A360194F95AAAAE477F98AB7750B2710E262D039D8584BE79D93E9E6405BA25DFF6DCF29C54D748DD655 + 21: 0F0B98CE94E2CC67D36086D153A2DF48F20283413407C3CD0570B619871DAC188AA37BA30BD706AFEF475BDA7AEFAB63055ADE8B792F025D088B51A08E941B01 + 22: E6538F3479D33979F046FBC88D4BA785B072EF58877BFC9D1214FA8374B78DA6895D5A4F4E50E6AC6A237E48A73EB18E4452E7C8AD50C82238FA9B323C96935C + 23: 378E83B88847F234A6A2FF7304ABA759A422E6823334ECF71E9C3C1F8B21B016D9A8A100B6B160772FFF12482A50613BD832EF534DBD1D4D055F3227C7513F11 + 24: ECFC0F6C168962197E181C27FC9AA1975FED01E655B3D4A7857872451D6AF810783184534C401709A63BF6BE6CDB1D1455C382CBAA6F68E8180CBA9E0CDDB9EE + 25: 8523B737250579A3787BD83E5DCC57F7038B393F003223A7BAB98EE4D040441190622290B164F32FB96682730DF62CC366FC33126DE2F7DDE3A38C818C48F680 + 26: C6BE341A28878B733C30F50D67F6933D3A15A0950CAAB96B9F3D7D78C95C61874A400CAB65A100302D9E2DCEADC4A0C043834EB0433D5D684C187AED93B5EC6A + 27: 4AE827A36DA140D2271F74DF1AF4303DF4B1C319428F8BA94EA28BD3765BE4535275053DA49B630E6B754097ADCD7F17DC7C16158F43E2C1851951EC3016CD8B + 28: 6D3F01856A8A28E28EADF60401E84253C3F7CD13F3A9FB8F94D8B07B74F7416817F274903C135BA0DA4509A78D004388CBCCA75B06132C7CFC0156C03803E85B + 29: 07CDC2BDD9CDC49853384FB647736B50D788AB80A0A54A0969B86603B683C22A1C5FD32D3AC92E73D378F379C4BA30A48E7D38FBB867E981271FB3962C745659 + 30: 9DC875BF987C55CE646A709E89CA89E226B0F15666D5174771368FAD768BF3318B8BC7D8CA80AFB5E6BB7FC0090B5559F11DA165DE51B940C9DFE911D4790477 + 31: 58BEE92BE003CCC34F9CE8C0B323C6BAF1297460BAAB4998CB3B52D2BBAA24D1B06CB597EB2E609A008572FF93710E3A7F42AC53E3FF09D4733757EACA41E20C + 32: 888AEB1BE2BECB28598556A128AFEA037D0689C8D13D9894F1416B2C48B2551CB2FDA321A26CC4D7E1C87332D7A3C18FFB455C92C0E7AAF829FA40B8A28BB656 + 33: 19099B4E8ABF225DC7BD1C1DC6D52F54E8FB7E4EAE0AB19293C686E6FD2828221A1153BBA4C143795D1A718585D9255B6DC911C0EDA5E0042A10565AA5D6D8E7 + 34: 22B3ED65F64C8E51257A922FF90DC09447224B9A8C7B5A6A94D68601F3D4C7C1557BB90B91DF318EF9F8BB367E838D36A3CA82FDCB85721AEA20A8A2268D90AF + 35: 0D2B24C6FD5D772704BC17D2FC8C011F1511F92491104F3C22470864882656AA40DD07C0C329C8BAFD90ADEA7F473349038CE475D352DA41E24FF64723070566 + 36: FEB43F7DCDE56A2EE963236C234E5800C011FC54D14396288DE5A7AC7DB2A72D1E8F63F04D1DDB3C55CF3BF19F4E0FBA4B79405A6B45ECB31254C9F1951C632B + 37: B8AE2C8427A750F34647C3529A05D44691B8DE0C79525D9145665BDA5C0C396C00E936BF2493F12945899B6FDAA9F61E6E7B22846023D140F873EE7D48D76BC8 + 38: E80C49D1E29F6FAF0BB5C7B47F5A85B3A0EDDED84418890748724792CC83B53AB044B051722F1ADAAB713E5069E883C1D172CE0EFF6EE6AEBE05B1FD77DB652B + 39: 1FED03FA70436EF45286648ABF39057C33815E6A80A19E22009B89C809DD6F0099C944B882FF9DF3DF08DD51295F3F02FBAB40F606C045BD4395969E27647D24 + 40: 2E3630EB519F6DD115B3E4818DB4429CDDF1C6CC2C8548F8CCA226A24F87A949A27DCBF141803B87B2A2C0F8AF830031DB1FE084E3996D8834F8E7D29EEA4AFB + 41: D54509526805DFC0871CBD6E41ACE395C64373E8F57146A657C28BB3ADBF7E57A152D27BE24B8F30F08329C2E040359B119690D9A1118BC14A3B1883D093466E + 42: 0AB062968EE4D71DCE807EFAF835EE11588854ACA0959B5341DDFD10E70BA9AD427D92168B31B8E6EF81F58615AF9215A8708CE1F144EE29901D1FC282C3F78F + 43: 45862B0D0F0AC5CC1C5769C29D786FD3AC788CFBCDD6CAECFB120D05D71F2575F4174CAD5E5A00D2D740D0714E92822427085F044A72D66631755BC55E5BCC8E + 44: D3A9EFFA759181346D8FE53130F05B2C65F96E1D5908A61DA8FA3A9BC551A7781ED7B1A6CFFCB2F742DDAE8D22B0EC99D82B14EB85719253693FF920FD5071D8 + 45: DB53395A78DDE62A406211955EC56C6F7BEB9EC2275501C35CA955268C3E2D71BA246B4286C76FAFDE012F9E2CAAC8601A74699B466023FE9F8B1BA26F65042B + 46: 9426FFB7B70DEDF1CFBCE6610583CDCD91AB421FE39DDC31F4215CF7604B9050C84A3BA29C4B236F1CC3B09F53D29229132FDDDD9B468CBB6338BBBA6193F84B + 47: 3D74F17DC6FE057703C72452BC7A078EC019424A89783F1FA40003657C323997DF30BBA38CB4B16BAD8FDC43260956090F765C26AB1FC88BF7F87EACA1821B52 + 48: C6EF119085EB17EC1B9F74791D95E366FE916F5397C20857A8966C52512F4EE16E63B53A28F7632A867EFC7FFD8080B173D5E2E33A2063FEC7D1181ACF8C7824 + 49: D878B30402FECA5EC93362105D5E183D658DD2FD38B8173FF609740CC84239C4F8F533AC3451D369001CCD4AC78814058DE0F7E1F93D167A46E85E3002F4F386 + 50: 948C4254AD2C5658A28D42DDC3CB4FE4CF731B4180B8A4A183C23C54CCEA045307422547600598CCFFD3C6229DAA6CDD006D3C782ED91AC61172059D016970DE + 51: B74FDFED0388D5164BEE25E37C6687FA8D5C069D4FB0D42A7F1A270A676F83F24FD1C9048EC0D49F7BE913D893E0015E0A3F724653B3F0AB0017683948712E46 + 52: 497EB803D053D5DF498369BADBF8AAD57ED1B072CF361D3DB2A528D3DB16DD962887916E9D21FFB439DC2C025CDD8C21ADCC98A23C8C5B0245F2D71CF728F10F + 53: 63F4098F650820EDCEA3E7C10B65D3B0F1949A28FEA323702F27C7D311C7E6BFC82D4C01F4FAD06FE0288E410EF325DE192F78B88E04075FA9581AE2B031A68B + 54: 337914B013B8056D7849E42ADB47FA761B5AB05696CB8FDA6B87FFF88B0477902991AD81664727164053E4E47ACDF880DCAD0E0E67F7141123DB494450CF0B61 + 55: A385FE66F8C852638F5BE44503B680298EBBF27DBD9F20B1A0447215C0E2C1078926002113A71C78148D5019FB22C8132DD05356C78A1A8D8E4EEC5A6442DBA9 + 56: 218336585A419E9877CB63387C5E759FC93F0FE1A7BA717B8BE9B2302393E0D14DEF2F749D138692D0A0296F1C792B567F40037DD2B8787F1F47FF363CF34F37 + 57: 7EB842771A61A9AF779C8794CA055518E7F38CD13F61638900EAAEA000B12816D52C593B62B9DAD79DB7397A463AB99A9D0035E7A1369B0556D593DB41EEEB6B + 58: E41D1492D3472FBD42F2460650F9DAF2ECCDEAEF5F4516B452D940DAD516F5168439154B4BA76610461B343BCF1E7DD7DD8C285EC0CC46C17CE3C7E14103042A + 59: 88057C0B8442BC5763283EA17FD1FE1AE011A988E1D7E0F914004CD3AD2E06FEEECDF59E309B9EBDABF19559954C37F71FA98C14BB19F7B91CE5F827C1DDE1B5 + 60: C5DE99AA273D1971272263C740E689739B39725A0B7C48B41577F05738A24F5EE2C0B673F93BD52A083798DDDC6E70A209213B58C95D49ABC5BCBABDD6AE7D22 + 61: 68296AC346BA3B14C038CDC629C5F5700CEB9F5DAFD94F948C6B991C0F91813BFD02660A2A05A02A61D8EB03BC93601F9F6A38196650047E1D7DD1071CC6974D + 62: 1CE0E6793B0ED59C4DB7D5F24FEF75A4ED2F28CE4AA7E5EB25919219C2C04935E4B15841821FA92FC7537DE2A538871E5A043A773CB1ED061333113223248C18 + 63: 37BF321F66ACE827B66ECAA651CCFCAD30AB627E717AA4FE441279C4FA48555CB7784B0AF25A73B86375BE71A1E3FDDEC661E0EB8115E0BB2B9A7FF81DC75DF9 + 64: 5C3C6F524C8AE1E7A4F76B84977B1560E78EB568E2FD8D72699AD79186481BD42B53AB39A0B741D9C098A4ECB01F3ECCF3844CF1B73A9355EE5D496A2A1FB5B3 + 65: 85A19923268414DE6A10A2CDEF7917D7AA01E68DF9D028CBAB5C5236FAEFCED836BDE9CF90D8A214013056202A1BAE5CB73606078C5572D8FE85C36002C92D70 + 66: C2FB9763A6F86225F6C66F55ACC8E7E17C1A2664416B2704D64AAC2CC5B04A626030B5243CA61D62076DDBDF3C6B3765C38D0CFA01D4D45C124EA28DA593F84F + 67: 5083280300FA5A1B172D7B5CCADA5CECE1EE5B7B5D382EB4A430179EB133970B0B89F6BB6DCBB1F38EC9F13F5B7D1559F114DE0EE26178EBC56CBE31BB26A91D + 68: B3571E8C1CBC0C58E23094B39352D554B43F9E7DD0FF981C12A01E0D8BBFF06A39875D90BEDA7F345550E6F67935A49E0183456B9967BB319D74AAD87CCA3695 + 69: D11537B780D458D37279D00621F646EBAD3244A22E4D45DF11AC5D084FDF70E7A32F897DF727E65EDD1019DABCC05DF0B5E015FC5CC1184129C5DDFB14F62154 + 70: C146458EF40E6F1944BFD863B2862A97145BA580D47C7ACA67E797EAC6790841C57D68A74930AEFCD49031819FBED806A0C033DD529A203B4E460F357BA1BBFB + 71: 660F3E1D5CD3B2AFD95DB0D8C258F6AD74DD40DB688A37AB4A24D720766541B1CB928001EF6D67CE5429039C9C1490613DDF90A27E6152BE7D42E1614C590056 + 72: DEC468EF73E98F44B60EB994935921F920DC0CEEB7498655F0FAB7607A77A7A3D9462DD8BAD46CB408EFA81FF08D7E9508BC565C1578C37C2B87D41A0A32A549 + 73: 070D4C36A0934C5C12E6B65FFF385404E49C3871DA8674D93D26E3166A7EF9693D946B419F0E10C9624964B37493DC8A46D26D8AB8942E60143036659CA4C91D + 74: BB8935CC84E08E6B4E7C6233E41D880D70CC018D1668EE64F19906A83730495D01AFCE1A4EA8129A98B7F9E074FD35C0BA6D5667625DB63A867BAA67BDEFC190 + 75: A0A7A0B619643115C582BB6953D2A3EAA942451F631FC56C0933B535313D668FA4CA7D6BEC4DC9FE2AD7528DD6F8DBE68478A040FBFDD2F3DC3AD7035DB67371 + 76: D6C57C3FB08D07A30A622B25985A52A6E552499345244725B1084E41691B11EB31D3B9776940A9A7E6115D2D1A93372D3A7388D87B01D13BCA726E8823E89729 + 77: 413CB26BE2B1BA8ABE930ED1B9978BA4874CF32B38C825CB6DFE9C21A87C0BD115D3357198FDA0A5B7CDEB4235A354E9C2F37D11B33AC6A257DEC67326830E23 + 78: 748E4648FBD009E4848E44A284D0CB2088300F50CD5215A285826E968B9DA59B6322E1987F78447150AF72CE37E516BE9E83B05A9817AB7A924ED8B09557CB5F + 79: 0A8111FEA824D43E0991C22FC3B1368A191D0C73308283494309D0762AB1EE5AF0CE2DB8F0562DECAC636128688540E845D72BEA3852A19CA2ED22D6C1E82CF1 + 80: DB1067879F014EF676471D950A81DA073D676DE52E85F67890C8471FE6144078DAF940CB6F9F097BEDB8FAC94C737C5B8A3B4217CFF4A56DC349B2AE845AB25B + 81: 6165F19F569BAAA3A3ABE6D6108D07E1ECB22092F66227DC27173DAC097118C2D927F2E5F7D20C8CEF0F99C6FE6C7AA46BF18FBC452F6FDD733728030CD0A4A6 + 82: 1D4AA14617A4BB9E48DCC1A7EE5DF65298AE45FB193F077FDB6D1C2B3252E1633AF86A527C29861661CE155A47E5BAC91D9B07715E0FF7E08B39A3128891EC42 + 83: C2C22B53D6BA460954C2D826FD3DEEE60E33AF2EFC87A61CBF2AA021166AFB90967ADE2C564D037518E4141BE9C0D0BC0B4F95498D5AD920BF28CAD4F5FE700C + 84: BB5E9CFE19C6A2D14EA4C1F6BDE51855DF61D650B23330BAC30A5072EAACF86CA02AD31FE4C146176DEC75C56A56C2B868177E0E365414508D2E7606AB9E8921 + 85: 6B40A13C5486396864608BE7285BD4D1205180BC41E10E537042A1CC6CD12FA7737B5E73D768BBC5D687FCCE41880A8D9773C26316ACEA2D78DA26FECCC11E90 + 86: DAD0DC8A7D78E29B12182D36F47B93CAB562C44FD6C5B1718651022CDEEC30133437431D13C43EC1C02DCE776F459A57C29355B3FA0D67C6BF84AD26194A8854 + 87: 8118AEE5DFBD7FD9F94403FFD3C6BEA08706D4C4DC78CDE72F751A6C4027ABEC7786A62732819ADC036B787E25E151AC51B60BD2381A64F05A326800D7514B15 + 88: C64737334A61872EC00C8A3F1B1EA931FEE8D80203CE6DB9F1ABEFEE2CD3E652971615AE4F9A23400B9E31D861BE6B7E0F6DED28ED74B45D6AE90E70AD49508B + 89: F927B571B03B892B46C0A16148F13A2E6B80630CE41BA7DBE311F9ADBB5E8F23923CF0CA527DDD20BB3FE42BBE805066BEAD569F6FED12A2722A8629427ED841 + 90: 2576A445CCD8977F24F50EE30EA7A51F0F3F49D41BAA663BD1C1734E02367A382E3D0E8C07EAED0C6A47CF662FE573BAE5593D9C4BA8FFDB4AF024F6064F7A89 + 91: E85C73AEB638F35565BDD2523AE2A86B573C339B4D5FF8498ADF71BA587CBF146AE63B8C920B2F0A166F802167A04CD0D7F7A842D7D058165894CF9188289032 + 92: E74E2ABDD6AFFF851EF78F8A866DDE9B9F86D906B298DD1E3630E1D4A30B6FCD7FF91943A57367A00E2658A84346F53ABC896EDAA395167E5EBD12C954E0B820 + 93: 6827226985276BA731A9AE2E4DBF2D0187C05D566F06D098E05E3F425DC058958B50F09B4CE0741F1375E9B522F94A61F1ED8A43A8D03A036D2ABFCEDD4F0C1F + 94: 19A71A12DCABA1BA185BA38BCC0D915584A801EA49F975393B25AFBC456571CBF1A6F9121CBAE89A9B438092C65532489A95A0864320102EAD9A2EBD30D41F6F + 95: C70F19BAEA7420A7482C9C54CBB689A9AB93E4F8538EDC2371A1EDB3A103DFB7176E04DF170FF71EF46DFDAC1E8F9CD6FF96115BE1EFC271A56BDCFB67D29E67 + 96: 8BBCCFC8815786ADD9F108F4381A2B084179002AE940ADD4C42AA2550C353CD0351C2F7F1BD544D8F268FA332B0E803838318A39079E9D93269A01EAF9CAC967 + 97: 5266FA966A04B8A2450ECF3826C9E1516FEDC33EE81D4911A601351564D27C8BD4A11BF00E0DE237E50D75421CBE475E38967F28E6A1C5D311A2C95B84898D1E + 98: DF87823E1E02AF34532C5F3A08CF03CB9B2017B835525B3E3C448B1ED15569935D9A1DA19A6B1E8D056FBC868447ABE6226B97F256F6B638B052B4BAB3BD4808 + 99: A1317CAC2364B10EABBD3540B6139D337C0EB3F7A740C050988FF9B3584213DF5833AAD81D36C30CE6CE76962A9E1D45F08667A314036A299454F25F73EB067F +100: B752B6EEB497A8BEBFC1BE1649CA41D57FD1973BFFC2261CA196B5474E0F353762F354C1D743581F61C51F4D86921360BC2E8AD35E830578B68B12E884A50894 +101: B0BB23AED2CFC9C58C8BAB019CD10DBE75717EE8F04AA45FD8D84748E3F05C523FD2F70DCC460F7A18DF7D28A224BCB86CFA4C8164D081D51F3487A7BD0C8109 +102: 0FA46C6A759DA9A3649679780A28FDD51EDFD3F99A4B801C5824247B270A137CF40006609E149C919CDA0A6C856A9A8E855A670A2BB2CD5211FAD42E84F6E365 +103: C4E350267BD335848D00151AF2C380E49A323E63AA264D534EA1BF7A860B764A78993F7FFF34ED93ACB1F5A5AB66758C462B4D2F2F4E14225D29FEC0C102E772 +104: AFA0F1DB8A321FC6C4EF7C65ED2ADC4B094E928E230D27295699DE68FB5C1657FE0E5C4E66C5852ACFC45DA94BEFDAC89CF0D4174B262E6FD51CDC3E7FFFA5CE +105: 9A86A440FF8A33DCD38C69D7564EF827F614629CB699B7F45E7FFF1CFF4AD5E27EFFDD32EF1D0845987A6A273EA34C19374E9FB606BB2E3B909157CC6666D29A +106: 1FAF8C564575D654133B0A452EC43959C9F9E20C044724B74EFC90D2CECE4C49A0512C9F4DA2E999552E3ACC04CE0F0E2FDA9826C2A1FBBACEC4330081D5CA43 +107: 8B35FFFCD91E617C8A49B13CD0FFA2199FA1F20E5633AE6E95881BBCA02B1E047392DC9A4C0F0A4C39D3984E78ECC4DCC1B5C94A26ACDC1F69C7ABABFFB45175 +108: 6C8AB69E946FE86DEF6F14B955B8F1977686EAFF8E384CA45F245CCC0EB1C80AF8E62B0E7387C0DA52BBA31B1A01EBB00CA26CBFDA9D8069A773C3B62F989A2C +109: C3A243B45B7C3C2002CB197BADBD84C4900D504FCD277D2DC6C06D34B1317B41EF098BB980800FA9D011C0363D074308835AEBCF3393B1C925045E97E14831C0 +110: 803E065AFEFC6C48EF9F701233AF512465729E81B0DBFF99A2E7FEFFB542831E1D3B30230BFA2F30343695C060AC8140C37CC8D1E25E95E6A1139C5522F4ED28 +111: 86618429B8720ADCBC8B9FEAED8BD44E0848572CB6137213273563EBFDA859240E17DFDAFF68B09953F1853C9E7EF217875E7BD6959E76DC3A1CE5F548B76CEB +112: 96439A93295B5C479F0310B28377FC10DF81B593AC233556B15897F1FA3886C940639AFF2ECEB29894DA884626B4811254FE2622EC7B4577087D9046C96AA556 +113: 9F7BAE13DB80C72A434BC4704998A73D7E546CC2590E0D0EE511CAFC63C622A8B2A296426E42754606D02B6EA060892E325EA1AC13EF0B523A3551F4D25BE241 +114: E999A862E5C479B7BB21EB52E4BD301571A8A39B712EBFEFAC720F28C515025E98CCC74B950D57CF3C3B34D788D62CDA0339AE0DA02C8A107BCDD797C4751FF1 +115: CD00EC5142CBBCA87BC15D69EBE96B5222F25BE1576B318208178679B13A9A8BA4BBABE9A488BB38C4EEF327C9A4DEA4225DD30C0F70B97C18C5C2FB19FC2134 +116: 1289951D2B62112BA590D8C0CF9EFA38AB77737F994060596738612E6BDC41EC8672F50A027A2C049299FD39E1776BC3EEBFE3E66CCF4009615D63F0A4C43ABE +117: 451A46FBDC954FB76E744AF3DA8429C881197F6BC12D22412438729288AA4540843B9FD4CD1BDBA5E864FEAEF0CD6CFF045A37510B3759FADFEF4697E9BF9240 +118: A267FCDF72D9160DA2A01E781E07701478F95A38C262ADEBFA194EA6D5A50A9CF3E04D32AA4B492580C6E8D8FAE1F813F3C17F82B7F47D8CE0C900F0F3052F98 +119: 3D910AB6579455653EFC939BE1B22D993537408086361008EBB166724FAFE3C8578EF4BE0378BC28ED883FC0FF3DE5A9310CEDE65FAF3AD9590A13B3CA4F81C5 +120: 47386DF4D41775737BC4E52D7CB2EFC11BA335A5D59597B5DEB3DD0A35032461F5DB4779D48BD6F3A10C5503AC563C790235E6F54EA79CEADB6A56AFCCE890DF +121: BA59044EF3A242974F074337CBB6840FA0506C2227A429498F546B2CEBE0644DFF1D442190C48CB54BEE72F960670F71AF1F8402AD5ABE8C1482DEFA881FA903 +122: 89B4F35E5C8C19AD61CF1600BA80C1A1BBCFDC86AD9F8066C967BA10F62827FCEFA1EBD07C90C82B48082A5B7D6A72E0AAFD230DE05955C7E8C081286B0CA96D +123: 0C7F94250F4EA7647F91E7EA8B8612AE8E7BFE4F5BCDD90CDCE564BC9842F6987AFB4C3661D8431440FEE18EB2EC70BCCD34A6B61D209CB72BE782A0808C08E2 +124: 2C8B8B17820085795BC6A2720B5D0BDF5407D9DEE1CAA4270FFAD010AE9555DFD2B74A742512BAFFAA1D5B4F14ECDB2BD4BF37838D5981A317C7287805974019 +125: B464C5A9D040F11DA45D98C4BCA9295D0F589DB11EE5603410C62BDACCC329B9AC14567C3A6F3BBA4B92CD3B95BE58AD4DA435199CE62D8BD61269F8BEA38FE4 +126: 2F64554FD54AA4A04ADE3793AFCC5C968B1C3603F4F71E1BB5342BA4E951D79A4580BF57736E7FC13A43604A057E9C360C099AC5B3403DA8AAFDBBF417FF6ADC +127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B +128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/hmac_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,1736 @@ +HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is +of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of +step N. + +HMAC-tiger + 0: 2EF793765716EE48A671BDB5F002103C43734304C8717C85 + 1: AE61B56C82BE9FF96DCFBC20DD02B4BEA4FC6B6D5F4EC412 + 2: B54ADBFB404457E6C5AFCCEC27199D1F259EE1994FFFE99F + 3: 08AEEC38E88403BB854935EB6F1464CE95B044F4B4202524 + 4: 4C9DAEDC1929E22128F2A7ED5F3556D8A6D3A8315A7B556A + 5: 764794ED9EE1F94891835CC3A361FE75C600C7951A07F450 + 6: 1A4C447A0FB8826A0881ED2E7BD89499EACA4B6C49F96060 + 7: 1396A21D8B465C6B898511DF94846588EE8E35C0095AD90A + 8: 7552EB03CE26A8F079AC96B42F556FEAEB756014B8FDE622 + 9: 835B7CCA9D9F13BA2A36CBD746E5C92D5B2D123CA2EC848E + 10: 7CF4EA88FF8B9A5A57E5ABB6B35278EE9D8653F624D662FE + 11: D588D953C6F438D077A1E302F84E25EF31AD99B9C5FC9DB4 + 12: 86EC62CF1A08CEA9171AC742E8E615B3F0C7B6FBC95DC3C8 + 13: 6EE7C51E26187F86370A26811C75136E28B0C39A113D80F8 + 14: E1326D54123BC26CF41B30F9F2BA2E732203836AF8A74273 + 15: F211E4C46862E3AC8B8E69976A705582CF6D1B34A6D342B7 + 16: 0C6160FEFE70C81C71B7465F42F070F30808CDAE448D1974 + 17: 492FC6BC091489F926F0F54CBF3E3F6C8CEC6ED14DF2DF8C + 18: FD166027ABD1BD9DBA13E3908D16C403E1691FF173328CA4 + 19: 28D99C64CDFFAC1E6F7B33C8E675E49749CE835A177A1C63 + 20: FD7BD55BC2A684F4875C811143A2997356AA87A300345843 + 21: DB8968E787BF65C00992ED9DDE974EA71BA947395111FFB3 + 22: 4C31B2FA4E6F7F40DECA589F85BB69BFAD1815A73CF9EB23 + 23: B4D8D7FCB314942F171F85EA0953F7816DA9F07D72AF48B5 + 24: 9A6A70BAD76203A7A1F64D1EE34375EC8BCB21810ECE0B68 + 25: D21D7E5EF6F1579C84428AB5D574468933BA037C9B0C34B6 + 26: 3C5292C87B24626241693F0EBE20A96800905691C5945E65 + 27: 350BEEC075258BA7FE0314E6803152B021570F067AE0D4D4 + 28: 6881F892886F9D66E68B937BB3A71FF5CB064611C722996E + 29: 07831F1B2D00108386339F192729687B2F57B9DAB2B1210B + 30: 38DE8DE8398EEC32939A239BC0198B0CFB18D12E4F2A3023 + 31: 5B683578F81867054089AE2E1B20E02B3BD92334CBB01FA9 + 32: E30A80BE07651BA17E2DF0D43A583A9DB268DFF3AB7393ED + 33: 42341B1EC4F61E90571188F5599FBA9ACF884B1E15694921 + 34: 7D98297D65F5FEA85CB967F22AE0707E03F305BF1D2249DD + 35: BC8EE5CE0FA8F9E6694406009EC9358BC420B7E5DE07B6F8 + 36: B8095DE6770CB4CC2127FA672F93F39CA4AF0CCBB9805DDB + 37: 20C0E981DF1B763B6BB47D43F66765AD434127C1FC55F829 + 38: 59795328D40D2CE6CFDED8DD5089F2D5B796C9438E7646CA + 39: 0789CAB229AD54416C82CA5A2E667EC7CE66019FCACF766D + 40: F7C81B1AE705019FF9A9905972AFD72484A70E11FB81B278 + 41: E72F52644BF5EE59BE87DF692EF0070D095115B7664BB53A + 42: B9A5DD984358D0B0F3C2781BA60E9BD3473C1C89C7982F23 + 43: F7BA22269249759F1A87AEA0A125D4DF9B58E93714449008 + 44: 5D2257317F8978576CD7D2CCD346E861A59FE949F74A3D82 + 45: 199D8D5B0B5C5B61E046F50E0E389DA6F19CB3A7A37C8588 + 46: F489CC6CB2D3E9F741D6C9008265CCA97E7E54D62F5EB85F + 47: A5E7CB0787EB7E62A9CFD8486390A6628C9876654B9E85E4 + 48: 22FA78EA17F0D29E16276C70A564D234BC4ECA7302301528 + 49: 4422534FB9EEC601CE7662345D6B6FF932E54BB0483C2F62 + 50: 5D2E2B90B460D393F36BF32B2F491E224EF388FA72A48501 + 51: EA5287BCBB856BF04FC785541079087CE24783E9310F3090 + 52: DEDA3920899FA69F913AE50A4F0D7119C9D3CE8F4E6D5BB2 + 53: B2F55D8EA64C9842BFEA4FADFE616664CD44C57D53998C58 + 54: 3D2C72F26188E1EF5C0F0FC8B541224066C4DF455FEE78FF + 55: 50BB36BD8A8D97E4D6CA78DDCDAD0690FBBC93DC9A66BF18 + 56: 48140E192FF8AB74FC22676AAAA186C1A7E2FA0166E986AC + 57: 40AFD540C40EE7E598D26AE3FE5A47939299B5DD46B0B4FE + 58: CEBBBD763B077342BA16D4B20412C9EDE0F0508ABCE3501B + 59: 0FE4DFE539160F5924C324B8B43DACB4F220195D286C6FA1 + 60: A06D135075F943CEE74AAB1B8DE08B772055551B1E73ED48 + 61: D4E1B5EBBDA5CDA5040DD697BB96DD702C6730CFCC012992 + 62: BD5E77B67B42C507C4912130C8880A9DBD66431DCA0C0038 + 63: D81F583A9B4DD1F48028CA602CC0F131D60561FA34F7B3B4 + 64: A41F0481EE52842CDF676177F8E43BC1F1B00A5682C63E15 + 65: CDB29E274ABEB20EECC8378D5BD806997502E4271AB56708 + 66: B8366ABD45565BB3D26CE46B6F419F74B34851863FF4C336 + 67: 5AD2C193D6D51C9C7E56C5BFF55C1D61E045366B51E7F619 + 68: 9948E3AB7D121B15A6CA8DFDF4EE5377C957F0DE891C3575 + 69: 095676D61096853635128A80570BD1CE803AC7249C0A0F57 + 70: 354F4CCC1E5112770B2AB035AE07200A6CDC0280AD088AFB + 71: A8723395E80BED25DFE8F9ACEDA942A77D225D00440302D2 + 72: 0D2BCE0F8CF396FD8277C8BD9B19D54965308D3ED04D2F27 + 73: 54B1939E9944F499798B3DCE3479AC315F2C42A1EF231984 + 74: 5CFF726EE4B2596240E6CBBC66D7C737A4D12A702B40E81E + 75: 82996D7F3F27B473BDA647BBBA7230DF217288F2D1A38B99 + 76: CB95F63E0E7A2EC4F26E94B81A3C8C757E04EEEAB35A8C2A + 77: 057DEDF45207EA885A0BAC5B64240DD21CB9D99CD8F38FEA + 78: 27DCDD1ABA459506EF98E5C8D567692264C4153F91FDB269 + 79: 911C83660F7EE8CFB5F54890AE98CCA36C4C12B8CC771DF8 + 80: 67CD07209988C517FAEE01E64AC4B5CF261B6035069508FA + 81: D9A40C407E2BA852684770A5EB08D8502DFD264F2DE5A5FC + 82: 9AAC50A2BCFD74BE3DF85237478AAA833484FA3DF912A3AC + 83: 38078488F6183B5A94B655F24212FC9769450D93986C9208 + 84: 2EFFCBFA4CCCAFCA66BF8B368FB1FEFAC280C20416BB90EC + 85: D626FD6D285C49F20E99B88B9F82640D93D9E765CA55B5B0 + 86: B1DD178943B26AA241D34031D3128344C6955F6A942CC5D3 + 87: DA0C850E2067F9FDAE433C1230E0F629700FC8896ADDBDE9 + 88: 58E393E353BD7DF75A591904AA99526E94FA45C98D095E21 + 89: 323D0E04D239BD70192B2ACCB9ACF06E2F8C3B07565893AE + 90: F9C4147C6921640C097534BB08020540B420AD569D03665B + 91: 5171DB964AC815B3A6D058419FD47833DDAED71039966E6D + 92: E7DC7C574AFC2C9A59E46CB8ADBD03330A5321B237DF7899 + 93: 97074CDA9FF8D40B0501E9F632ED7335D6A7926101A34C0C + 94: BDDCD4D007DE39680B80F9AF9803A9F21C836EA971250CD4 + 95: 0DBFF45E3155098D4B4C13815FB461D3C4BE41E9E1A68757 + 96: FC16CB95478E4D23A7AD15CCAE3C24BBB3D0FBDC8A00A144 + 97: 93A7CB506481D6A72EAB14A2BA544F8631542B55903CCAAE + 98: 9CC1FFA19736AB6EB36EB4A2C1624FCB6913B255D2346795 + 99: CE3526A088FFEDEA4345AB221707848823B16DADD19AB487 +100: 1E1D790323586DB8A306EDCCAC8C64A6F29A36F772B8D61D +101: 8C403515F2B9014E9519EC04769ACCF23E522D3E22DE7F41 +102: 6B6A634607634804988301240CA5AB029A9E86E51281D64E +103: C7C3483CC8E6B58520B554259EB08866AA7980B53FFB6B86 +104: 96E429611C9E411321947469E2095CD9B0EF29578030E40F +105: 5C5A7F2B7F1F9BCE730BE2779304A443188FD3B31DD2BF19 +106: 70933F999325353277E0AA1F543B5CBED3F28DAF4FC70A57 +107: 5CD6D136FDDF4AE9CE42F008301FB6647096D5007E79973F +108: 1162BA742AD199AC17FC707285301A82BA9CB12C09BA229D +109: C36615F6D5E29E6CABB7EBC44A6D3F7B024DAFBD338FEFFA +110: C29FEF051D1606CEFCE3417BD571CB9188BBF0FA8AB98679 +111: F925144EDDD27244E19E4B6E433F312C6CDE43EF4F9B84B5 +112: C4230A59E54A34D0709F3F1DB02C18EC8AA270078DE424D5 +113: EB1699CAEC36681CCF8A9144DFB5050566042977D15FD1F9 +114: 9FBF0D9B2DD9A6E87240E538590E9799B76E22604D22AB75 +115: 2657EA06D69A78A5895A9169F849B3DE111B31E5673A8E17 +116: D1F9E1BA4F4E52CDAAFC388FA4C366EF4BD5F440608D86B0 +117: 049196BFFD9F77175FA936066C3119293EAB79D1E0028C8F +118: 9CC1BD2CADDEC1D82FFAFA7031F2E5C9B6765CF1727A0ACB +119: ED00438670D68A70CE2E0729997CC9648947EEA35809B8C7 +120: A520A0089BC16C84CB8E05425B330C6D261108EE3049FACF +121: A55B470483E547D2752EDC3C4FDCF3B4C48A1990AD857941 +122: 46A78E772C533EC8EDA60EB4A127FCEBD35E7D0E7F183241 +123: 5EB9A774124D571FCCC83D1F36C603D9C387390DFB3928B2 +124: E904066FC77F73CA41166297A8FC631FF59634B659F0AED0 +125: B85B66AEF7D9904356F1CAA5583757D1D69EEBB8AB1D1420 +126: 6639F85214BC798D71B757FCD480CB78D325881781A3A073 +127: C5B72BBE80917B55036A9AD6908D59293C49373F0BDD104B +128: C0BD695F6B9B42DAB543C31BA73C9497A6AA6419A007A9F6 + +HMAC-md2 + 0: D39AD9DDE006587A8BE949B11B9288F8 + 1: FCB21B5348C95E8A8DCBEE50A80302CA + 2: 2F26B6ACCD0E03FE9B21A1B0E75FF665 + 3: 17CF85D985D0D85F545897CD42C6EFE5 + 4: 1537A6943B4F5AC1272E4161225D987B + 5: 83E17165D62CA6E4B9ED67DF1E599954 + 6: 7A3195C863DFF86A98968F254E128E61 + 7: BD05057AEBFCB92FA4B07456085EC6C2 + 8: 23AC0D307BFC2E87760F8BDB21851DF8 + 9: 2CD26A2F2994106A375BEB0433575BDE + 10: 1F63BFC44FDBE9A966CD90DF82265EFD + 11: 72735FAADC3819CC24CFCE1D589BA311 + 12: 28B589C3C8078B8FFEF1C8297E33C1E6 + 13: 70A6DC014CAD2752931A47C0879D2371 + 14: 81694317A37FFBA816504974F38B4829 + 15: 72F26208B3051F1B938EA7E03DD8C107 + 16: F945F57FE0696A4C81EC59AE69384FAB + 17: 54D8DFCEE33969486956698495B4BFD0 + 18: 508B82F88A234E753A9E305E15A14D82 + 19: 527D77D2AB25131693B02F653ACBD90E + 20: 4868AC540FCC3A896D5A89F7A0444D36 + 21: 6189807C5FDDDD68D20356ADF3B90DC2 + 22: 0356362F2BC4206F2B930C4282213758 + 23: 2F59956F19B3CAD687C66C4EC3CC916D + 24: E30CEFBDA3FA1A8EDDE3B72614ADDEDF + 25: 33E0E6BFCBC9581BBCDF13F4D3F26724 + 26: B11C6476F9775219A9F18B5E88857790 + 27: 49C7A9D7F56344BD405E53BE927E3A58 + 28: 99A06874B0F0CA45C9F29E05D213195F + 29: D21A60A18F061FC453AD5AC2A519071A + 30: 2F735E82090144C036E3D12DEF2E0030 + 31: F9539EAC81BBCD0069A31E2A3C43769D + 32: EDCAA9C85A614AB6A620B25AF955D66A + +HMAC-md4 + 0: 752E874F35085E497D5032112CC65131 + 1: 6B2CAAEE210F970AB481D6D8EE753114 + 2: 2162A41522C2DB0B8AF1F0C712C19A22 + 3: 7C2106C3CB687F35FE2658BEEFB497A5 + 4: 3715333CA3EB74A15B4B1802A1A78921 + 5: 403D9A691A130AFFFB81A655AAE1D956 + 6: E697C3CB42716CA1973DE0D15486068E + 7: 99676F34E42C61E396F0E76BCB77BEAB + 8: A2B2CE8CF8AC151C5556A36D58894C61 + 9: B8614BFF1DAAEA90BF319F333024976C + 10: B8759E8B97DFCBB2DB94D8CBE2C96B20 + 11: CFFE6119EB0C649831459339C1B0C82A + 12: B2FC0DBA9C4830CA66423728599D3660 + 13: 454749F1DE579F1918FF046FC1CAE7F6 + 14: CC625178FEFD46481B7D02618AF6194E + 15: C26D523EFCC42C4AF7EEC2EA4B45B719 + 16: C352DA2D077FA3F493A5CE0E9A79CB87 + 17: 570DDE9FD220F59867F17484605D2061 + 18: FF5954A163CBA61CD3C8424CC71682C8 + 19: 1240D12E3D6C07F6FE1CD595C847C038 + 20: E87A4D7958C43CA71791B13E16301036 + 21: B2CEDE4A15F8D64C53D243F8C5763C05 + 22: 54A9E9EAE155E7AFA6FC8A7E05D7FA9B + 23: DF0E79F27CE25E56ABCFF5E74D1212CA + 24: D9BE454A95E5D9127990577F7EB7183E + 25: 26F9221A8B854767861BF0281303B89E + 26: 92BD4CC81A673B254A4AB493864BB014 + 27: EBC3851E0AD28BE9876BEFD6B0A88B44 + 28: 1134BC8A40E1D2FB038B67548AC2040B + 29: 954700135C4E7F232337C84130B43360 + 30: 8C3EF2D8F896C8D252851A1543F72493 + 31: 52817E79D2B0B3A37DC08D18D3519F92 + 32: DA661A428B9659DD59545E3B09162F8F + 33: 3FF5BB67B48F87B4B642DACCD2E4001E + 34: C674F95BB622D7B8281FFF34E9EF3E7B + 35: 3A4D25E3BCABAD8CD4918CE650EF00E9 + 36: 2D91248C51837A8B80898E2CE42CBCB4 + 37: C0B3BD2B36493F0EAF9AAFEFDC37064F + 38: 9B4723B091102B480B2B59069317F292 + 39: 0F8EABB489254491FE19AD0E328A483C + 40: 25469BD482E1405E51AA021752394C4C + 41: DF1DF50EF9D95892D08DFEFB79D6552B + 42: 707A546964CB22710482C478E58C2E0F + 43: D1E243DB14E2F946D650C811030ADE9A + 44: 11A1AEA678E98A65420747DD6CF9293F + 45: 66E735F658BD689A9F1BA0B526827CF9 + 46: 98170734E67F576CCC3D01D83965A6C9 + 47: 399D99CB7979E80F6D3B5D5BBA5871CA + 48: C26651C32EABC76289CD0843D3BCDD92 + 49: AE0F50954C90E8897BCF504592D0626C + 50: EA3AB701136862428EC326D2551F8AC8 + 51: 4AE98E5A1E6B1BA8CEAE844E34934039 + 52: 7C9826187053186DDC2760AE6FB56DC7 + 53: FE0F555B851CAD830BAC9FBB40705671 + 54: 221BB509584BCC7E10F3B4FAB2AEB1F3 + 55: DD93EAFE25EE27C6FDC2CCDE7D273267 + 56: 535472E1ECD49FAA75CC6621BE7E6210 + 57: DA4554FF7D5B289A03D195F94154AF47 + 58: F15A3F547B5A3844BFF713CBCEF701A1 + 59: 279DE06FD5644C520BADD3B97D96274D + 60: B933E929073492EC1E2AEB78071C7B83 + 61: D1DA2335654AB4CEBAE5C2E78CF27553 + 62: 06FC50285F4BA5C8B5A478E9C02D6434 + 63: DB66A5D55224DDB50337B7FEF9A808A7 + 64: ECFCD0385FB49553EC89DD94AB084D23 + 65: 4187B0B79E6CB916F747B857AB2F75D3 + 66: E03E14F5E00B2DFC0614308608B929B9 + 67: 5F61FC3005167EB3256DB549DA8BA562 + 68: 21A4D14DF8E934A858569D8BA7F151E8 + 69: 5955DDA4CEF16ABADE2B551841C69B8B + 70: 8E77066A973B60DF64C27DBB93EF204A + 71: 2101EE9DC8221FF17D9D887FC39F41BA + 72: 6574A9DE32B7A673B5BA20FF18EF8C93 + 73: F571B14C9F5C5C1858D48AA944A13050 + 74: 0BA4BE0A5E853D07F79B2D29BCF046B5 + 75: F240C8C38D71131F510369D79FA32208 + 76: 920C294DE37C28803FF3C49A4135CD65 + 77: 38796D25822AD8F2AB4D64E4A65626A0 + 78: 65A203170FDF794397FD1090E318C5DA + 79: 965A767FE4A75BEECE26BAA79D816AD7 + 80: 0F4B30947B790C47924657648FA1D88C + 81: 74B05F7B7D006F7DDAB31DAE251C3BB3 + 82: 61B0366B57A8F46C2F6C16F935DA768F + 83: D4CB13CA922B542980F854C9780A1951 + 84: 039B2F23A1CE410FF4696D9C35C40C08 + 85: 2D734E28F995C2AA2A7AE2412EB99A10 + 86: 1A55FE47703ECDBE446033F492412812 + 87: 6AF4CED86D0181D6E99EE6AE57F295EC + 88: 69C239A875E0352D20BCFBCF8D5CA19F + 89: 62723FBBF0AC6F397438589AF06625A1 + 90: 424EC9353901795251AEF7D7BCFEB8BE + 91: 9BBE4ED6C8BD14F85BA86E553B1B8152 + 92: D7840AA82F788B7D58712E29003D1239 + 93: 4AA55512DCAF770FE4D9428FB318B0B0 + 94: D040BA08BEDFFB20D2C499FEB35EE12A + 95: 0F295EDEFC85546547860B7F7CDFB1AE + 96: 720FCD871B7D8824EE6A7DE9FF1A62BE + 97: 2FE3AD14E24C441C36186673A0D60767 + 98: 943FD502136B66D0313951198680F746 + 99: 4EE6829F3EFFD0A87115512ED28C85BA +100: 6EE1AC28A320246CA5C37F981E22D294 +101: 36BC623D6573C3ADB164F8A6F02315AB +102: 08B3AAED34FB0A0F99C4B22714B9CEAD +103: BDCD10B66096AB992DEC5539773EAF23 +104: 6DA36A53A79FA2C68E5060C0D2D43E13 +105: A3E886199532C025074D4646113F9C23 +106: 00D67A1D2ADCA77A20441CBF593FDEE5 +107: 2E4399F5FB44FF5573B73D01C5B248E2 +108: ED22A18A8824A30B68EE0EF9907B2B91 +109: 36166824634304417BECCC9519899CDD +110: 0757DB01193BEEE90617AA8CAD0360A8 +111: F7691CBEF4ED2E9FE4EB992CB3939970 +112: 09DC2FA975CBE8CE828919957D110EC2 +113: 7DDB74DEC57AE8C318AA5CCFB53872F6 +114: A26B7DD0AA30EAAF1F4F8314AB7DF16A +115: 088855527BEBCDB67A40FEA4FDDCC061 +116: D0F8ECC0C32B7060CB6128279F57FD80 +117: DF5B79D3671CA5E5B44CD395F6FFA551 +118: DA8999EA059C463D5F05D04020EE867D +119: C0EE404DD8447AA70D3725D5634E2B53 +120: D19D1A725F5E9F0DF21871B31900CA73 +121: EC202984BE149C93CC1D440CF6D29E1F +122: 422DB7C21B1348983B75498E270FE6C1 +123: EF136334BC30C92DB9082A9654B391E4 +124: 0B3526430AE734054873B14DD696CB3E +125: 3BEB77C0F85F8C6F21790ADF30EBB812 +126: 4376F8C8EAF5A94871822DBDFBB5F88D +127: F7DEAF52378FF735B2D171B17EF573D8 +128: B4FA8DFD3AD4C88EABC8505D4901B057 + +HMAC-md5 + 0: C91E40247251F39BDFE6A7B72A5857F9 + 1: 00FF2644D0E3699F677F58ECDF57082F + 2: 1B6C2DB6819A4F023FFE21B91E284E93 + 3: 04B0ED3E73FBB9A94444FDFFAA530695 + 4: 1557A22261110DFB31ACE25936BDE45D + 5: 54C5A67A9CB4544CA66BBDA1A2B8479E + 6: F803D9E43C934545AF078FFBB34BC30B + 7: 32F56EA655DF36D845E430D637C85D17 + 8: 14BD2095F4A478C10EEBFF379DE76DD3 + 9: AAF6867B3FA01DD26312B0DFD6371A2A + 10: 0FA2A6FEFEBE7CE3C31A38400F8AB260 + 11: 54C37BE13B7333287D0E74AA9D9227F6 + 12: 385D75A58B0C95E5CDC059DB168BD1D2 + 13: E73003103ED65C08E62D46AE1E1B771A + 14: 278ED4A4EBEA1FFA5EEC874F198C0CC0 + 15: F65CE9EEA7FDB90B9CC603329D3FB9A9 + 16: 8640836944EE0009B2CC6FDC3F5C39E1 + 17: 7819A99F82BABDF060AA51AE109629DB + 18: EF26336668486C76921D1DAB67ED5673 + 19: 13ED7BC140F1496E09AD29C644586957 + 20: 5FDD337CE9C4AC8D910833FCC2BD837E + 21: E9470246ABF7CF4D37FD378738D8F763 + 22: 384A75C33EFFA12EB69187BB80DF843B + 23: 63866A5406B9EA0341032FCFD0244A4B + 24: 8042F8572C8A9B88E135ACB83EF1FD39 + 25: BD1BE6AF2D022F966F612569E191F0E9 + 26: 9F70C839533EE4C7B3CF20C6FB65C94C + 27: 800A5CE92CA4FEE6F1D353F496113873 + 28: C35E93E1E54C84C4389D2DE71E1B9846 + 29: A130EF5F91465F5A56999F450E63F4F9 + 30: 5F16564E05285A099F628245DF9A3C2A + 31: A34F7E3DF06DD84CC67E8A922240D60B + 32: 945E50753B6E6C920183822D5F280F10 + 33: 2DDD269DBCDF5C21A1C3FD540FF4ABA9 + 34: 212FE3E2CEF7DF74FC01CC2CC83119B8 + 35: D98B2930011649F16C08BC8C0178D838 + 36: E39E21026111C1EFB0C491C0FDFA841D + 37: AE46DE06C3B0D2CEC35352C95A1003F0 + 38: 5550EE50BF88C9DE5ADA34567FE044C7 + 39: 6BC486627760373EACFF508F7032BF31 + 40: AE6E0B8DBCFDCCA4B3449B57647D5AE5 + 41: 6BE5A0F140DFC4B75439630E6F9A36EE + 42: E3E4E735BFE79397D4653A6243DF1925 + 43: 68C1D9E8973A3F6B92B588469D68A2A5 + 44: 956132D512118D5F446C8CB912B924D9 + 45: DF5C2AD650B3CA7A89EBF92EE618C845 + 46: 14D375CF7E4294ED99135E4237414F01 + 47: DB966D40B447692E2D13CC0C09C1B495 + 48: 53DADCF1C6B99BD403052A1CE1ED0D14 + 49: DEC4A3C1DB8F6AA4515C512C9299C4DC + 50: 3B3A51DD83AB1DC56A7F0CBE1C71923F + 51: 03C73353B3203EF9CDB95F9DB8750AF1 + 52: ED9E15FD86D66DA2D546D2BFC55041AD + 53: 81B649338F9DB1C6E592427D38221C7C + 54: 92E170E13BF40FF65E3B4C665F222DD5 + 55: 00D5E23F5F829B21D454C4445851AB53 + 56: 39057029AF0B3F4391A7BDC6DDCE4D07 + 57: 2DEACEFA698F9CCAD5198C4E17E69A93 + 58: AD35FD52EA199E26948009DF3546D3A2 + 59: 4C42CF2CFD4D8FD9A06E3F73D02FE818 + 60: 4D7C893E4313FFF72103854463414277 + 61: 3F04E8B32AB56EAF216503E46BD7AEBE + 62: F015DDC3EEF41ECC93E944FA3577DB52 + 63: 31F77A50A2ED96ED8E4A3CE04B9DAA23 + 64: FBF481373481756E0C88978F7E0809A2 + 65: 7D8D793B287C04E7D2896D76EAA5CA15 + 66: DAC74AEBECC2385DD9D0C3147CCA1F78 + 67: F6DDE50D37B460FF5E8B4C03A0854BD5 + 68: 5710D6A54A2124E06A6DADBE9BF76119 + 69: 19DB5D13A53E57184759F33976537AA5 + 70: 848DD8D32130626FBD11B0133C2A29E3 + 71: 4F75BE04BF2F6DD85D048DB82F19C38C + 72: 4AE9436540ED24BCB5EC62977AC90789 + 73: 859D1A9FC2B795AD60F24A37EB9EF890 + 74: CD45865317FD17B652DE9F9EBBBA16B6 + 75: 52313319D395F453BA2C0A0159CF180B + 76: A7B190C0EECACCA4DFC5B45DFB324718 + 77: 23E85CAE85B50F45F7F48EE0F22FDE85 + 78: 6A80DBFF139A5345235EF76586CFCBC7 + 79: 850E638FCE5A2F3B1D1FE9C28F05EF49 + 80: 797CDC3F7E271FC9A3D0566A905D1CFE + 81: 030CE97A9A0B1D5403E253D883FCAF12 + 82: 648FFFF44E416D9DE606BA0DDB751194 + 83: FE15098E0DAC65FA8EE45CAC67121CC9 + 84: 17C90ECD390A8B41046B4C7FA0354E4F + 85: 7D149DFF5F6379B7DBF5C401DB6D2976 + 86: 8D055A4701DD51CB9D1AF8E2AE59BD21 + 87: F3481CB07B034EB4A023D00D4FDA9A86 + 88: FEB22562FFAAA9CCE5CDDA34C29E55C3 + 89: A620AA447216709D8CE5C5F23474ECF8 + 90: F25FCBB2BF7440C5E3C5B53092B8C828 + 91: DBBAE1CF60BBCA0B05EDEA0B362F0A33 + 92: E18E85BCB4633A797FAF7975CEF44B84 + 93: 1BE27EEC72C2EDE151978705C7C7DED2 + 94: A15D36C5C5BED77699838832FC225DD8 + 95: 08F31E68BFBBB420742F80B20B69BE8C + 96: 5E9B4B5B3228F533BA8EFC3C0B9AAD3D + 97: 1239BA6D941D1D8AD2ED561BF517D4B4 + 98: 5233F50218E0D097EFCC68F1536F30AE + 99: 340B47C78B003272EAA4B9D22C3B0542 +100: E7F11759FE8A897364C21767570885BB +101: 054BD6ACBFD5421C0290B0839C0A0ACC +102: CC0748F7B2CC921CF5FA019F955066C9 +103: A4DF167697949B1AEDBBA3226A334BAA +104: 29893B9776BA5E750A9FCEA37B0116AE +105: 2DC25C935F006F7965FAB3256D77004D +106: 24089811FFF2189FB9AF38651F43977D +107: 0E048569D634BF652CD8EBF859C9B69A +108: 00386B569DAB73844A708BA5B48BBAA8 +109: 8033E1AFFBE1218F81C8331343FBE5B5 +110: 9B82008A34F3847C1204ACA89F3D57D1 +111: BE1A529F88AA05A42AFC40F663E97849 +112: 5237637AA645E83B0E56A1361AB80643 +113: 15BC4405E891ADAF48FA56D4356705D5 +114: 0820087438832B63AADC479CFC88BDBF +115: B1E3BA7E96605D5FF614B1BEC1F57AC1 +116: 838A096D64E6C0DDB069DC89E4C3F839 +117: 934BCE159F3959A933C87AB497CA8D42 +118: CA501F1DE619A570DC38FDCB8B3F7722 +119: 033B27D5994A6F5D5F6800539B69E876 +120: B447FC68FEF4E3CF9290B06EB6AECAA3 +121: DD3D3F72F0F1FBCD030D839DCFEE457A +122: EE73C4C996E0150D93B3144F20FB2C1B +123: 5AF9679D2441542391C6A903FD8C1626 +124: 2BD84B87230511DAE7256B62A46AA45E +125: EB159E5694C191F7708951EBC0AAF135 +126: 60F02EFE1DAFAACF65F6664A2321B153 +127: 14E5A0E90D4420E765C4324B68174F46 +128: 09F1503BCD00E3A1B965B66B9609E998 + +HMAC-sha1 + 0: 06E8AD50FC1035823661D979E2968968CECD03D9 + 1: 0CE34DEAAD5CF1131D9528FAB8E46E12F8FE3052 + 2: 23924849643D03BBEAC71755A878A83BD83F5280 + 3: 6119DD9A7024A23F293A3B67EFA2BF1D82EC0220 + 4: 379DC76AC2D322FD8E5117CCA765391BC0E10942 + 5: 7897CC86CFF17A3F95C7AF02CCA03546F5CC2368 + 6: 1FA1EF3980E86B8DF2C8E744309381727ED10E8E + 7: 03B2B726D71DAC6A2BEE63EAA09631DA78F5958B + 8: B8CAC4C104997A547374803B5898057B3F8110A9 + 9: E165E07F8D542FB288C7D367198D0618DE3C9917 + 10: 18125F046C675F434B3C53A28C301FB2D91B5D34 + 11: FAAB993F2FEAE442D28FDBB613D2C768ED13342D + 12: B657E7EE3A65C6484D007E21484813D9AED1264C + 13: EEEC2BB7BAC158742711ED13090FA20462A5E5C0 + 14: 12367F3A4E1501D32D1731B39CD2DB2C5DF5D011 + 15: 57DD9DA36E7A4E567A2C5AE9F6230CF661855D90 + 16: E37110DDD295D93990C4531D95564E74C0EBE264 + 17: B2115C4E923EC640E5B4B507F7BC97FE700E12DD + 18: ED20C67345867AB07E9171B06C9B3B2928F43188 + 19: 6CA7DFC9F8F432DED42E4EFE9F2D70D82507802D + 20: B39EB4D2C190E0CE8FA2C994E92D18CFBCD8F736 + 21: 91BE5ABF1B35F6227772E36337F258420CF51314 + 22: EB957199EF666C6D0EACC64FC4261D11C715BB23 + 23: 2A18D8D4AB1F8C528C9D368BF5A7CFFC2168D067 + 24: D4DC370D482D82932701DF8CEAC9337682C2551B + 25: DB9665A6A26DBDE20238F04E9F1A368D26564E4F + 26: D5AE212C9E543F2656699B59DEED54CAACA9A071 + 27: BE8890F9DEC6A02AE2848D8505B6408E884E6D1A + 28: E8D9DD9FAA3080560B0EDE798B745FEE2A1E5479 + 29: E219219D2CB8C363C2687F578446ADE1C0404287 + 30: E8E7767B35ED8D0965F68272ACE61924CB044262 + 31: 1B26689C1EF55448A61DFAEF98B6E7206A9675EA + 32: FE850390864E98A17FC43C3C871383169741B46D + 33: 3F63068D536A282C53E5C003BCEEC96646CF7455 + 34: 2962C292CE247F11ACB7E1F981447C51E9BBE63C + 35: B28909A2B7B2E0E13FDCB1124B0BDC31D7D2FEDE + 36: 8DA0FC30C8322DABD67D61E82FC92351894789AC + 37: 543DAC6D449FE2DDC3201927D08695F68F832905 + 38: 371540F3092F77867F0CA9DA69318C7673F68388 + 39: 7EAF32204EA5993C87E9A12C67ADA4C85D253281 + 40: FC4994BAA05F592901085ED7DA188EC3A9BF36E3 + 41: EBFE77592EF34E81BDA05305876411484DC0744F + 42: 25F64E8F076305D6F5741EA58232F68B725B8F6E + 43: 5DBA03F7E4B4226666F0D8D5BF49FEE77951D121 + 44: 98E1D56D723DCACF227D2AC67BF2D6E7FD013497 + 45: 53550BC55A367D87416FFA25261362E7D4618DA2 + 46: B18434BCCCC5F08B35397C1A6684D60F4F3A452F + 47: FF2BF38DFC6909B46A01E055D173F67A7E456341 + 48: DAFA445432ED37FEC99059DB8A0BC528E788E95D + 49: 7FF823C570F8B4C0E483165C076AEA7B5E727632 + 50: BC4FC948AB621FE1419CF6006DC04E7D7B32FA23 + 51: 1678AFCC3FBD1063E7C82CACAD5B6A933A93091A + 52: 97DC2F9F56738FDAFFD555BF09274153FC2FD009 + 53: 74F5CB4F0900441B7AFFC278C01A3038DF3D60C8 + 54: 021F66143270C9D58F26AB193DBA81A811917CBC + 55: F486D1C8127813FEEEA8A693C4B8ECB5BB53C3A2 + 56: 8397CAB8EED5B2164FEC6BE688971DFA2138934E + 57: E4477CE9BF8CC5A4CCDE039B4E3000F1A0F4153A + 58: D6D2D1E3EE4D643AC4B38836AE54E846F99B376D + 59: 9545B2C6279371D4D928AEE24328121D43DE1E5E + 60: 947ED38EC087C4E53F417E8216408863A8EBFCB2 + 61: 32518A2326ACDE1E962B3D0D2BF950F318894E83 + 62: 5D21D368FB9D879ADC27B341D608BCF860AB14F4 + 63: E2BEDD94D565A51915B1EC6FA9DE18C62D12533A + 64: 15ABF657DB6473C9E2F017C7A2F4DBA3CE7F33DD + 65: 0C9DAF8D959DAE3B66FF8A21A94BAFC523ABC462 + 66: A36BE72B501D435CB627C4555A426C4ADAF3D666 + 67: 1C171979D67A014A0422D6C3561C817A354CF67D + 68: B75485B08ED052A1F4C3BACCE3C563DF4BA82418 + 69: 17297624219C5955B3AF81E5ED61C6A5D05BD54D + 70: 38A9AC8544F0EF24A623433C05E7F068430DA13E + 71: 1E9EEEAD73E736D7B4F5ABB87BA0FABA623FB2E5 + 72: 4B9D59879EAC80E4DAB3537E9CA9A877F7FAE669 + 73: 7F76F2F875B2674B826C18B118942FBF1E75BE55 + 74: 1716A7804A9A5ABC9E737BDF5189F2784CE4F54B + 75: 168027EDF2A2641F364AF5DF1CB277A6E944EA32 + 76: FBC67DED8C1A1BEBBBC974E4787D2BA3205F2B1B + 77: 33DD26C53F3914FECF26D287E70E85D6971C3C41 + 78: 97906268286CD38E9C7A2FAF68A973143D389B2F + 79: 45C55948D3E062F8612EC98FEE91143AB17BCFC8 + 80: AE1337C129DF65513480E57E2A82B595096BF50F + 81: CEC4B5351F038EBCFDA4787B5DE44ED8DA30CD36 + 82: 6156A6742D90A212A02E3A7D4D7496B11ABCFC3C + 83: 3040F072DF33EBF813DA5760C6EB433270F33E8E + 84: EE1B015C16F91442BAD83E1F5138BD5AF1EB68E7 + 85: A929C6B8FD5599D1E20D6A0865C12793FD4E19E0 + 86: C0BFB5D2D75FB9FE0231EA1FCE7BD1FDAF337EE0 + 87: AB5F421A2210B263154D4DABB8DB51F61F8047DB + 88: 1B8F5346E3F0573E9C0C9294DD55E37B999D9630 + 89: 09DAA959E5A00EDC10121F2453892117DD3963AF + 90: ACB6DA427617B5CD69C5B74599D0503B46FC9E44 + 91: 9E1BB68B50BD441FB4340DA570055BBF056F77A2 + 92: D3E0C8E0C30BCB9017E76F96EEC709BF5F269760 + 93: BE61BB1BC00A6BE1CF7EFE59C1B9467D414CF643 + 94: 19D693B52266A2833ECA2BB929FBF4FCE691A5C9 + 95: B99816886D9FE43313358D6815231E50C3B62B05 + 96: 7A73EE3F1CF18B5E2006A20BB9E098E98B6513CA + 97: DEC620F008EF65A790A7D1139ACE6E8B8EFCCA5E + 98: B6BA0EBD215CF1B35742A41EB81A269ACB67C9A4 + 99: 3A0FAAD14D3B64BE4EDB9D5109DC05DFFA7680E2 +100: 12E62CE53283B5422D3EA5D8D00BC7F0AE8A127C +101: AA36F0CC6B50AB30286BA52BCB9BB5C1BD672D62 +102: 55120C68B419FE5E12DB526D4ABFC84871E5DEC9 +103: 372BF92A9A2507509C3D3932B32444B7BE1C9BAC +104: 7AB4B04EEC091F4ADA0807DDD743609BCD898404 +105: 20CB412425E88482E7D184EFEF79577BE97BAFDA +106: DEB91399A7BFB8323BC8E6A5F4045125277C1335 +107: 6769F41624E553B3092F5E6390E4D983B851C98C +108: 716760E4F99B59E90A4F914E1FB72A6D2C4B607A +109: DA0AA5548B5C0AF0CC494F34CAB662A30372DD11 +110: 17A0E2CA5EF666EB34E2ED9C10EBC5DDCD0D9BBB +111: 1B3614AF749EE359F64F3BE3650210CC3C3498ED +112: 346E604622CF8D6B7D03B9FE74E7A684AECCA999 +113: 629E46882D214F9BD78418C2A97900B2049F1C83 +114: 765F86114E942214E099E684E76E94F95E279568 +115: 002ED578F79094B3D7E28CC3B06CD230163F1586 +116: 52CC9748778AF5C8E8B41F9B948ABCECF446BE91 +117: 9326190BF3A15A060B106B1602C7A159E287FD4C +118: 18A5DFBAE6E7C9418973D18905A8915DCEF7B95B +119: 6D25BF1E8F1244ACB6998AA7B1CB09F36662F733 +120: 5F9806C0C1A82CEA6646503F634A698100A6685D +121: C3362CE612139290492225D96AB33B2ADFF7AF1E +122: 3D42A5C1EAFC725FF0907B600443EEF70E9B827E +123: 7FF97FFC5D4F40650D7A7E857E03C5D76EDD6767 +124: 3A92F2A18E8F593E6A8287921E15E2914DF651EF +125: CDE6F2F58166285390B71640A19BD83CA605C942 +126: 21A227A8DA7A9F5D15C41354196D79FE524DE6F0 +127: EBE93AB44146621BAAB492823A74210D3E9FD35C +128: 6560BD2CDE7403083527E597C60988BB1EB21FF1 + +HMAC-sha224 + 0: 6E99E862E532E8936D78B5F02909B130AB09806B2AF02F7CB9D39D12 + 1: 1D1D08669FC34CDC5FE5621A524E7181CD5B5BAFCA3DA56D2E15FCD9 + 2: 014A21F82D0CAAD15EB74DD892187D7AD93F2BEB549A596DFF2C9AA9 + 3: 5F600F19EDED821AEED09781792F9435458A32A60FFC1B678FE2C905 + 4: 8D933E18052E7FD1F98E5E7D02384DA60F3E743801032256282AE2CA + 5: 21362A65B49C33568251CD1366EB13A4E683359855C00F3AD6710896 + 6: 1E1814B72BFB185265AF94FA622E4A1A70826C06F2BE2EFD96E4E168 + 7: 118F2E1C2F1AB8AF2BD17842FCBFAC966F5B21A81996E3CBADF76442 + 8: 2C6C72703E33A20EA0333629503EBCC41B64DB829064A5C7897C465B + 9: 794046ABC3BD8165D12C2453FFA3FC518D1A6498A48C91053BEA2966 + 10: E6C3B6E2DC215702960633C976B86B8378D7780FF884910454032C7E + 11: DE7CFF6E85D9411FBD58B28FACF72DFDAFA115614BEF3119F6527104 + 12: 11CF7495ADC07EC29EAA7B3464F772D49999A5E1832F71FCE18CF7F1 + 13: A7541E63945FCAD62D2570B015079DF0422E96075986B45772860F38 + 14: AFD3EB7EBFBA79CC68E4F6F6A2D758969B5C5C014FFB53CFF21C2841 + 15: 28D942E37CB92EDE2E6F994E9EEE2BA01077D099F3562FEF97A8CAC6 + 16: 34C7562962548AC9661759B4FC347D6A82CD47991EA06E855571CDE1 + 17: DA76FA12D69D1FDBA5E544495BBE45F620BE147B73D6AA64D3B3C298 + 18: FBF1911FA019CB7ACA20E3F93ECC0D5E8D60DCA0A1A7420C63BA1864 + 19: 565FEDE0EE20842B82D59644929C2A1A426E397B38FAA772781FE018 + 20: 7B9C2BA77B2989904F194021D308089E23F00954275AE9AD87306A31 + 21: 66CBF93ED8071FFA36B61F3AABFDBFE714C3C055B2FBDCD3CF369025 + 22: D96F10ECBFAD7FDDDF60BF1511E94869ED1D992051539E50D5F32831 + 23: 5473F93F0D979D77C3C6B9CEEB2F3DC1058D81401669EF4AEAFA17E7 + 24: 5B5A75A7D99C1B40961533C345B95FBF0AFA916D6E133967FCAA15F2 + 25: 2A1E50E18C37AB7BD928AE14C206FAC9B3E869173CA337FB9374565D + 26: BF2B241659C96007ADC25D9567947BAA740555D066636731EEAE3C97 + 27: 6E1E7B64A70B190BEEBDB9DA82C8E4B160CC73B8FFA224A6B92180B3 + 28: BE36A5F8DAE9294B3995D278CBE9273E66F04D46890B44EC55028C3B + 29: 9983C289CE2F806F41182752A753E0A890217DAF3778B3AD2ED6685E + 30: 8B0F08EDF2CBE25E8F9EE4D2948BA6BF81672BF4F509530328A8BAA2 + 31: B65FB77E6CB86E5F409EAC2F1B5A05E1910213563F816121AFA8CF14 + 32: 5D15E17C8C159EA5DF5F126B12ACE777EAB36A0082C57DF71E4D9609 + 33: DCCB3D17C8756F2546B3E5B24B1678438959D83A56524415666DAE05 + 34: D28DAB7CA715AC86BF4469D743A0005AEE0101F339350661D46A1684 + 35: E7A1CCC4B2B300457DCC64534152119390B69610C7FF9DD3A683439A + 36: 29380148DA403AD5911C7BD52C783EA97EC306F2B32BC426C4D7FD35 + 37: 56DF59CD635F025925A968591E60DF2CBAB22F98B67C78122F3CE868 + 38: C20EF10AE9CD99CBB54C94C971780E0487899D7A810FA51A6553DCF5 + 39: 5B78837F366097CAB6D31624C06B099BDC71286E3AD8873509ABF4CE + 40: 8DA09589C44E710B9F84014FE553074E72E0A86C9418EFBBE420D2C8 + 41: EEE18FA2BB5A5CD16017B4621ACC4211EF7CD60613A8C879B0AFC0D0 + 42: AD9670FCD043E6F91CE986E6F55905337248B72E7B8551AE72ED32BF + 43: 97FA4FBA4815DA49F6127C96C969574AA9543B338F93BF9171D2547E + 44: 838D5AC81EA6BACB827327E8EFE96CC2B14D92C55B40CE58F4DA181E + 45: CA99480DC8480FA07784EF02074453664DBC92257366514060F07C93 + 46: 93B0E493D272470F9F274DFE4B9DDF183B26011090E15861FA21CAF2 + 47: 770CAE487AE5890DC0B931EC17623293EFA5B22EE1ED496A37EB9FCE + 48: 6F1D5CA0446E7B82DA02847ED1761CF02D646E56FB0CAB9B120E5282 + 49: 2A8A1254F6CCC3D656397A5F2D64C266412FC5207866B073B77DBDEF + 50: E8CB788AAA965ED87FF2C7B5F3107684326DCBB0E667217E0EA62C51 + 51: 85BDB6D1486F27827D5870812BEEE2C3976E0DED4BD2F994BBEC12AA + 52: A14E0343FAD6BD78E0A8E3BCD6D0B6C83B1220FE6C89F57F44BC805C + 53: 2C60D71F2D4BEC90CF10804DCEDB9311637B34D62E9CB68B8503162A + 54: 36397D66B434BA744174DA541F080CF6582F10322C7FB1869A100141 + 55: F612E4EA307F56447112CAB5D2EBEA7D12C7C4427D9155D4085687FD + 56: 9798B420980748993BC78E3601B8AEEE2D2CF6E59799C7B07B88435E + 57: 50BED37F1EE78FAE16D178FECEC2EBE4776C8E5FC738F9506E8AF676 + 58: 2755438A9AC457B81999D9E1E479C36DD9AE1F920F5BE6D109ED7431 + 59: F3DC2238B13BA706A048253F86B79045B72EF767CF25DC62F96DAEA0 + 60: 11900A3154C4DFC49B941258A134C9201DFD280728BDB3F8BC7903F8 + 61: FC584202454DD7C9258F72A6258E42F3C2669FD138FD7AEE6200C4CB + 62: 185355C13E146EA89387C332225DF31CF114AEC0BA3A5A5B53667709 + 63: 8194DABD2F7A02DDDD7B752AB5669821519640EE3B0059FD333F3401 + 64: 2CD6946C6DB676ED1EC272AE34735A0546AFB8D996323272C39A814C + 65: B7A344BC5EFFEA97AC49894A85B96F9B570E680DFBB28C76F7F9A180 + 66: 9011B80655A9CC7964CBC4BEE1CC03074003CCCFF5DA553B289ECF6A + 67: 6BDE25371B7EA9ABE31A524E49CAAE40DB220E405463D93FC7F66904 + 68: 35694194E10D0EBCA6758099D09C99C3CAB37AFA52FC4F4361C510F3 + 69: 4E7A79F362D7AE5B1680F30E6770CA46FE6264C9FCA566718C01EF67 + 70: 9DD18D21E413AE12112AFBE16684BFD4FAED7467A2FD5904EF0B493C + 71: 7532D374B66B1E5B17EB49810DC3C04264553E4C36F4550D1E860B70 + 72: 35EB09C82A624B1E3ECD965ED8522E9572EBF26791EFA667B4DB952C + 73: B9C17DF6F2A6506FB1DFCF1A9089974C45760A438330AE7547DFE685 + 74: A7DD0267C15B36D8BD1879F879E894FB9F33F254556B87BFFEDD71A0 + 75: 68A354D120CD63A5D34EEE84B7E5E5BC1E5DF6E021F712BD4270B781 + 76: 441DC4884130D48BA134E2FBA86AF643C8EB79CD1AA4688F82E0D3DC + 77: 17A3F16DEAFDBC1DA00BD14D9C24497BE765F41E2EC79578421ED8B9 + 78: 8756A267D0CAD54BFC848FCC4D6B6C94D39CAF07831EE35324DCD35F + 79: 004EBADA70F19BAB48E6072E2090941DEDB5CC0A7B624E4BBB671382 + 80: B7F8D35CB865977423710FA1E0F939808E68ABB54BD7EB0427DA03DE + 81: F3D0AAA2F912FF95251D3CF51EBF79B940DB56839DEA8BA5872D1FDE + 82: 0835B2DC376BEAE873F1FA337D75C72FD1BF0F72A81669AA891F2722 + 83: 7CF9A7D57CADEC3F013D4BD87C00B420CBFF73670A9CBB072D18EBEB + 84: 68AC0A34930329F5AA40137987208481E34D8B9C08EF7A85AE3AB38B + 85: 00492F706D84B903D5355FDC0B68C2C33B484A95A173FDC4AC945028 + 86: 6F6C509CDCC84CE1C36AB76C9BF30E4422C90C869C164C64696AB5B7 + 87: 4C0A35D512BD0DB15915DE08FEA8E6027063A1780C104F6273CAD5C7 + 88: 27087F6425878D64A56BD5ACCC0E303F803B7208F20AEFEF75501F03 + 89: 4EF78140430EF60F3CA12AAF8132674B0DDB154F495029B4051C2A36 + 90: BCCA3153EF93AAF21CA02D235A23D3013976295E704223CB37E860BA + 91: 20CC8D4C64E09B00ABF23864BD7EDE542F5BE480AFC4B9551B301EBA + 92: ECA3F86DA00098D91F866C58558BB7B00C9E4239CF83C5A3E76291B3 + 93: 7AD9AB198858820D20373C45173D76AF8D68F829D9A250ECADEE0DA1 + 94: 3E1C202F2D589BDAB015306AD063784E5BEA48AE8D1DAF45D571D2FD + 95: 990C44330D56EBC9EDD951F8CB92D5847F4BD3C6442906F57A828FA9 + 96: C92F9FCC6220EDEF52B6F842635A83914B236862F6CCBED16F4899DE + 97: 0E41C85D5C6D625E1884EF7438DD9EBAC818AB50CC265A73165928D0 + 98: AE087D57F9CDBCDF4DD68A3E8D5BDFEC709A532A4A646CB31785506C + 99: 4CB03AEFD24C833B5350996EB261E803F6DB698FB81F37F8A5C3D891 +100: E680BD218AE972999BECDC905F4D39251ECF49B29CF0A13AF5FB09A1 +101: 64326D6B692B0A17045434BFF13282ACB91E7B690339F7FCEBCC9AE6 +102: 20CD91504AB04E2D3CD849808F2362943BECB310F4A0BF6E3BD47751 +103: 80F607E2D79E1EFB0458E47C8E5726CDB8387BC05F42D6EAE3239A20 +104: F83C023D6F539967AB24309DD28321599782ACFCFC76B77186307300 +105: 70164A250799DBE6C5BD3EDCDEDB16D2516A9FC1BBA294C49F753824 +106: 1883397C9C4C9D33FB9E1E03325EDCEA1606D7ABF86C4387DABC449E +107: 1355DFA06822CC1F216C131F2BAA92A10BBF109BA3E648419A35C0F3 +108: 9E35B9B307990B7D664B9EB7F06EFDD23037F859ACB6B96A5287A846 +109: CCCA26C8F8405FF62421558255F2DA06F73F17D1AE1763A0BF8430DB +110: B4FAE909368405206333491674559B9094DA4C48913D9EACA28AD75D +111: 3A5E7D9273F91E10545FE6861D4FC223A5EB0F7B4FBFBC9931634C25 +112: 96553CF0C5C6F6A17FEED04024FCE1D292C392E60B3595FF53007AD9 +113: CA9B79F403412F71FBC10E094B35088576EB3F7F8B5D08757D89F45B +114: CF60CC5B1822E4A12EEB3E1E5F4AA79E345D8C8FCC546D57DCC7C784 +115: 807D65C33E74DA0E2D5E3788084C61AE3E8771FDFE643D1269A7901A +116: A5418DBCA94A1F9692FFDB3F7AEED75806CD9FD47171A6B67921C0A8 +117: C2B880C9E9D78B0C397D72C8B6684276E8C22A7F4D6821DB7C998775 +118: EA447EA731673E5DEAB57012CC9E0D3A7B2443165B665822963FD6B5 +119: 0F6D50C04357DF9240802977779D7F2214FBDBAE95B6D8F59B414964 +120: A3B24B29B29BBF32A01F21FFF13F44FCAA5FED50718803AC3BAAC548 +121: E31E36C38A7F2525ECADECA047533830A9C46D609E297142AB3DACAA +122: 592FF0C399A6CC1606FA3F404DA4BF8618A4DF159CBB7E05DCD30BEB +123: EEDD6A5902091ADB8EF491F820613740DA73A160D825121912613DDB +124: 3A2FCBFCB007F45CB0EEDBDD5A765EA0CB7A142CE3C024114D6D61DC +125: 5D29E1732898854AF468BBFA5B87065BB811AF8F55C91E82E888E842 +126: FD1F646D021EF31F634EF5FB0506620686B9F7D9B5C672734CA10FDF +127: 5E43945BA9DE62C364E34CC1361FFFEE9BE8974D7CF5D2E06428916B +128: 0FF4DA564729A0E9984E15BC69B00FA2E54711573BEE3AD608F511B5 + +HMAC-sha256 + 0: D38B42096D80F45F826B44A9D5607DE72496A415D3F4A1A8C88E3BB9DA8DC1CB + 1: 12B06C3218C858558CAD1DA6FE409898C31014D66CBE4ECD47C910EC975E104D + 2: EDBEF6AA747C951F25AB6AAA0D874648CF18FFECC4C9159F8FC71E971FAC6D21 + 3: 03436338A166E9051599AB268CD74867C6159378069A9FF46FC07CAE375EDA68 + 4: 634758DF0774A587F3AC6AD7988D0965524DE24EBE4DFF07EF622BCB8DA71ACD + 5: 0C08E52C7CFF8B5F70781197069DC8F209552D241687BA0D24661CCCC28D3937 + 6: 749F473E0D934694AB9917569A61591CA50BEF18CABDED51666DF243DE879D53 + 7: B1E12CFE0273F5D27192D1A4B70EEC4DDC714B66C8BB1921C63381F78CEC5219 + 8: 1C60F13A1C539788E989BAC2EBD4F8E126EE6ED82C2E25817C63B2B633FABD33 + 9: 5643F445B2C0656A49BB3DB5088C9E2E4B2082C2B611BBA0DAE5791F2FAA5D43 + 10: C467F47251DAD4694C9C7A6758E54CEBD68FC933C7C57458020774A2A2B4288B + 11: 85C90CF2719BEBF40EF8D501FDA20C342BC406E728551BC0275ADA1747BD981F + 12: 06B72DAC895B008DA249B7B1D8A5133F09D86BF82DE2C4251BFA6C3D8C4CF03F + 13: 49EDB6714A556DF324E41A3CE5B57006E38FD7CA8B90FEEA2ACAB429204747BE + 14: 7411921D759DA0B491D6D4CC372DB79CC163F146C345B4A73D93EEB4C262A1DF + 15: 5C37FFBD1F0512AF443265B2F3E8B6D01AD9B45FF6F373D2CD0A7C6E48D03E26 + 16: 773165FD16D51E51CD8A958E548902B47BBD0A6E156C31B6FEA036F6D8C4A90C + 17: 5B4BE909754EBC8ECBBB8B5DA6298B8341B35D92E17CE7281909EBA1EF568347 + 18: C6EEF2D12F54815561EEED3426D7AA7E671E26D42384B9478D91FC6B14CC76F8 + 19: 4C9FA0575CD96BB1DEF6EA79F5EC7A1F0478E86352812F690C2C2BDB70028BCC + 20: 7F87BA45FC41EC30E76F61E4EADEC013CE2B4C49CA6FE6D2FA525F6BBD45E103 + 21: 9B8CA1D70339A0894E16CE4E76F6655ADDD3EEB598F3DD80FECC5EEEF3F638C3 + 22: E4608AEA430A638799991B748BB858C91AF58F56B226E1901D28336B30498279 + 23: AF4F9C52079B28546FBB44EEBA20C7AF0BF493D34EF6967B07CA32FC4DE25ADB + 24: FE51F3A9313EEDAAA991350AB4D1D7045D42AACF3AC7155DA3AD9A2F1DE3A73E + 25: C1F5AED9D77F85404A4B308A139D33F351B20C91A738E698BD8182F124D96C82 + 26: 3CAC12A252B93B7D724AF9119FD3C18E85E88401F93BFF42AA05711B9833B1F6 + 27: E61D4E94C212324A64B1A0C04B2237A9A1C5CC003D83EA80BCEB45452DCB42F2 + 28: D01BA47DABCE4704B6820EC0ECDBEF137B9C4ACB80DC99B7C9220CFD9F9CE363 + 29: AED502C53A8B2C76F671376CDDBD0596376B3664B917CD9C9ADBC489543D4721 + 30: 3405AFD96584C5E5963362948D112A70155877BE3B5EFD479F226B73351ABAF0 + 31: 5FA0290DC68B72B1FA27DBAF157923C706B3F52CDE9C4EE38CDA31D376B0BC0D + 32: C1391C694C985CCBA707A8C78AD05E2180AF6B4DA5BB877AAC5E2AB33B4890E2 + 33: B018E7B15F92DBEC58F767633BCA3BD0D84B6D5B9443784DC1757166D7AA1C16 + 34: 8D9E2C84967004E3957DF59D502BC11CF8C8959368117EC5DB56AC958A3E791B + 35: B0EAF9C0E869D7A304DDB30061A73C580B0A6F9D49E15442ECFBB3B5A851855B + 36: 0B48B0D8C3ACF7B4F9ECF8E46563C921B1B6720B6C650D72DD1126B6763CD595 + 37: 8879D239EDB09F6606957D96A1F4BF37EAC0F3419881EEA79E8BF1364FB3FF6D + 38: CC663E436DE42E32EA110F9D90EB990D9151C9F06D51243D2076B0CC45361736 + 39: 732DC3B1F809E55C498C53FC75A23966CAEA16BE984F795CB1BC94D026FAB30E + 40: F1F0EEC77D97A0234D0F19B2FB12A96B6E2FF8626F79A74D4AF26CDE1344D838 + 41: 75C9D8C7344668C478D8AE6D9E2C41E336E7A2504CDD43B73CCBF78B4C05EEB1 + 42: 4B149BCA6429408B242E76C52C4D3A0A5F5437EC0AB6D24D71EB1AC5496D75BA + 43: EDB65EBEBC0411B4FDAF186033E306AD500711CCB80E770E99523BB2672A237A + 44: D1BBFF5A48346A0DFD5CFFAA7A2AF08C27F3FC2908D7A5D2F575E07CA9E72474 + 45: E8EFB6373DD3457610E57750738358A50026D2C6704A98148CDD69BFF7B70551 + 46: 8E3733B729CEB97444BCCA405044B98F45FC59BBA86444A3FC0F4DF4854B5C4D + 47: 868F3EE8F4D4DFEDC3FFAEEE1FA069F5FBB2CB818E63C28151C1566634189234 + 48: 3F5396115DC7F17AAB19A3A9779CFFCCA57DE7A7C1A42F748FEC49B7D8C2B82D + 49: DC2A5E3E176A693AD8CAE551A505729B78FBDE778B526E28953BC1A56B54840E + 50: DC91FD745E9A7A9D0B41C79B3B3939B84BDF78BEB007F9AAF8FF82084759223A + 51: E73DCF5413F17D4ECCEC813DC060EF907C2E952AF92DD247A0AE2BE798E6A40B + 52: 696B5EE4C1E1D8B60B0015EEA2389C9A35088022FFF10034D0D09FA722A2A3E6 + 53: F86C07265389512B2CE240A89EA29D61C6C79C2738FACA157B0DE43294485682 + 54: DB31CBBFD28D6F8564219911EFB748A5663E482DBA26E38634E8E27E3CF65707 + 55: 2F9675313AAB7A940AE77CA906D0342A448FDBA3F7589D14B1344D586EA157DE + 56: 7D829FD994258EF2AFDEF22C8CD5CC1D29A9A55B62847B3B6F5DB630421CF999 + 57: A6CDB9BC9AF75EA4680E895E8EDDCE76F536F7CCA571D62781A06DDB3424FA50 + 58: 1B4186A34EB07F5B3127F2BE0F3943610679DB0F6BABC7DA03B416FA577D36E2 + 59: 7B5DFF3459DC10B9B7AA2B2829094F97706DB5B2F133B8BF9F48D90253D68359 + 60: 2ABB68160300028BBF3B5A414970D11DF4FD6F4B4A35029DEF8492ADFB19A480 + 61: B1B13ABF9D20C42E755D63EC63C016126259C8A6C3F9AB3F0F6AC5D0BD44ECA2 + 62: 9ADDD17E5CF407CDBB12E5E52A50CE134F1B48A2A2AF90D7308344FB5A70485F + 63: 6A4C06DF40BA515C56476471D4A94F87A2B91EAFF6C66510892F2F20A342B736 + 64: 555D424206C003BAD0B08BEEA76DFC81B307C79BBB6E4F15325B2ECD37E04423 + 65: 8A58733E0B990D0D82F93F77DF36E30DCFD03B3181B73C544BB097A3A73B6AC9 + 66: 6FCCCCA4172E30A281A702E36E7BCA07370D4B57272385077A44D5F7933DD2FC + 67: 3B1A91E49AF88B1832F8E91109C7CC5DBEE2847D9ACD2A57404DBB565480AC75 + 68: 69584075C278763CB0B09D4C9E15E9300A191BF99907049F14EC8DE24D86C121 + 69: 2EE24340D13E68B10B95C3F77D55027F98BDE6BA5328D0C02CF89965687C062B + 70: C04B37F5932F427D40E21EEAB7C9594B16BFCF4F5FE2BF175CD63C62F2CEEAA2 + 71: 058E1AC8971ADD2617A4BF7D02B46A8B74A4D52B25643DF9729A1E7DF6CCC86F + 72: 18001F246ABC760197482E25F3AC64B14A795E55B41B505D6027261BFDE7C52C + 73: 4AEAAED524B173E08E54A83E2D9A8B8824E6E2F1B89203D698E9BCE7C3242F8F + 74: 7D82CFB1D7427302889CADBA23A99154CBAC0C9ADEC94EAF29EB07DC86B0B7E2 + 75: 18D42E92BA532A409CEDA8E3A07E751B430800827F5A9F14D93E3ED231BA08AF + 76: 8CFBA378D8595372DCE5D9A6E726C23512F84C0C1EC3C66ADF6B6C55DF63936A + 77: DE1A6E280A9054C91B826785928F37A16E1D2A9A3CEC831185B26D2B8EDE158C + 78: 920C40B4204C7F3D4775176BD245BA0276604C568B3C29943C9AEF1A1C93428A + 79: 935BB39E5FBCE5C4A15AC2A854475578CF80308E531CA86818DABE69BED8824A + 80: D608E561471CC09EC0865C826242CA26AA1C90BDF1625E1A38B96E3EE0CC5F04 + 81: EFE2A8D806A1A71596A05A2F5F48D18CFD4A742247B04E8089FAB27291A8DD50 + 82: 80235BE35DDEA5D49F124D8BE3D143F87CCBA7D0608C7E2CABBAAB01BB95E477 + 83: E9410E0DC14F3BE36A49A5CA673C12E18CBE4F0817E0C1CBD2069349F8A09BBB + 84: B2042A81A36F27B4CB96DBB52A61F701A815869FF5AA0CDCAD0327E1ED1C2F22 + 85: E9E5A9501B24952DCFBB9D59CF95A9A9E6A27FB7315EB472D1E2B7F523D06D42 + 86: 99193B4FAFEFFC932B261EF169250B96901ABF877424FF667CC0DA0154C50498 + 87: 1D9C7F7E681D20E1E0324EFE71C8B6913FE8CA87EE52E443335115AB2C458E7F + 88: 7308DB7E2591D2342109C5084B1174F07D289FBE91472FB2D8C06DF39F826B84 + 89: 90F06ADC29070DC50A23D3F093007E273E783491A70A2F0AD6BA40E34F02518D + 90: E676DEEDC972019F10FEC24B4AEAC0A97870E924F7B1D6D3ECF91EF38A2AC544 + 91: B5DA3B40FBF373795E67A6338F9AC3AD742741F34048930D9336D429D02EE78F + 92: 6FDE20988863CE157042EE52065EEDA233BB2E6EC0464B9DCF2AAC1F3A18971F + 93: 428D4CFF477F0F0379F634D1E7C15E4CE6DA067ADC45221A860C9C3AC4235753 + 94: 9EC80B57E921DA3F81D13B65AA851F5971E4074C96E0D8B64E50A7F5089C1FC8 + 95: 9088151BEF766D0896A48EB6DCC8A09D151C3396FBF3A9FE193C5E7BF9030B01 + 96: 86D853024A762536666316F363BB867EFE25FBD03BDD28EA7522973A1A1BD95C + 97: 007104BD935B532BA4702A78C505D67B41358A61DB8069585B91B1445DC346B5 + 98: 5C5709F6202948E805FAC25C454ECFADFAC693955864494E511F0CD1FC9CFDCF + 99: 0B010F71C5323CC96D3B8DF71170968096E44969EA55B4C3DAC632D30D81D529 +100: 54621EC4F31CC7F6273601D81674612B44726B5CC4A76EAD2BBC3D32DBF62A9D +101: 28EFE1AB745BE64E5DD7286C97360FF2D287F862ADBE44380F85E1388008079F +102: 831BFA684C25542676AD52819249A10D9EF9C2505D69CC1397D0D39D08B39E5D +103: EF7922C40CD96A47C5E7AE4D958B495F1D6954EDC20596E303CFBA43190A9EFA +104: 3A0262EBC746A7C044C1DB043951F7EAC645C40F554898D3D7B2B7AAC4EBD396 +105: 1F2CFBA7275639A12DA7CD1986F920C47850DE3FE13C931618C0FAC765820ED5 +106: 7AC8913C0975101E187FDADDAC5B5EC467A25869C4E630EADBB42DD2DFE4958A +107: D386591F326C91D274FE625A667B6F9F6F7D99CF56ACB365A218F1CF8E167A70 +108: 66286CB1B61156B005CBFC94C2CAB1A6694D7F123411B8A123F2ACD821C291F2 +109: 844D1038E710690050DA737D56FD6B17C261C7BE512713E62033384B53C40902 +110: 7EF970C40080F554851277F4E950C6F378B0A3DA3CD1BE250D976162F8A4EE79 +111: 9BC20A2B67566688BCAC77FCF30259F11D9B2FD2277D033E6AAE19E36058A353 +112: 796C72D95BBA1A4341C6B0397E165DD21CFBEF55555B35C717CE33B6C6ADE490 +113: 1E6A9C1F78AFF266EF8FB25C32C1FDFB4A0F64AFFD046D257470BF6DAEF61D6D +114: 0E1AD927AD658C5E0321333AF8AE4ED69903B4F22C5DFF90AC93268507A7C86B +115: 07B7A778E2931704E7FECA284FF3B14071E255A2B824AD0A2272D21448579CEE +116: A8D810DF06368A0E825D6DB4394916E43E217BEE9303AD4096A8E1CAD37B8703 +117: 6A9C7D302CCA1EE170366F355D8F40AE3A20D28BFCB2BA163DCB68E08DACB748 +118: 40C3A8B08FF9F767491E4243D1808572FDAF1D8CD21AB47115849531513D0750 +119: F26EA6760AA80360398371855783815BCD34431E0CCEC58A34A67997ACE43CEF +120: EEA78D68A509988ED6D7E3F27FC22F3EBCD570EF0FE242A0251457EAC4C3C1F4 +121: AF977819B87F2E63C0E131DFA2A31C555AD831ADCA6DE0FC1BE48D21A1E7E666 +122: 846A75DF3691B2BF224FB0E66E360A2E8BB1DA32422190F2B319B73E6900AD42 +123: FFA997FCFABC9FCAD4B58B0EF848890FB23B974CD57FA07223037450C371B116 +124: 0028C776965A0AE5E9E70D9B833BF328BDBCD06C5A12A2F1C510911E60AA304A +125: 7FA234C59957C214A7BE8D1B909C540B48E54414EE5FD1081B4C339FD2204515 +126: A840BEEBF2C2E80AF2E4830BB26F71AEE48A9C65DE4A9425DA9F98FA3A37DD84 +127: A95332415EA29A8CA6FDB0F771E3F2262C6907DC45B0AC8BC229F6009323C3A9 +128: 8B185702392BC1E061414539546904553A62510BC2E9E045892D64DAA6B32A76 + +HMAC-sha384 + 0: 44BE81C415D283AB7A62A45188E5DAFBCB97DA606BD5B16C92C1FC36F198C0B3A714921848D5E03DF1C4849BB8310C66 + 1: C1E1E68D864F758941B87E30C262348B373F167CE4629E4117FBA208773CCC2E6C7797AE5D6BBE2ABE6BAD4DE2E1052E + 2: BB27A0F06A1BAED5AC4FC2267C36EAB663E11EC5F0FCC0BDC09B9B0E803B0ACAA2F39D2AC73DE489FC7C9AD6DE3FC9C5 + 3: 70A273A2E9E5092EF8D4C58E99734A911B7CADD48954FD518305313B0B682CFCE192018D4847375D7E311470D05D97D9 + 4: B4FAF12B325B486B67E38A855D18B45D1BF6CC60E4D00AAA6E58268F524CC1121AD3EDB64D6E0FA524F11C0F139D0BBD + 5: B509A325F561CDDC539A3A4680380759747709D428B77E69C4CFE926F65B147D92D2C83692F526EBB5CF606AD162559E + 6: 9A1E678A743BA285CE154ADBB555CFD097F5839EEB2DE4147986464C1BF032BA0D80473293467ED0A0AC59BEAE736598 + 7: 1DF214529464666002C1AF094BB36F0FB14A4923031B108C21825E8C55BF6A0BB34C9AD7D5030B2FC7C83A2CD4C79C1A + 8: 86D8BEE44CAC35CD3946321796599F20F3A41BE28F161FDA062E4440CCC16E88BC7FFC714D525A6420CDBEBDF6AE9E12 + 9: 92417595F9974B44BB11EB9200B7560FEA3382CDCB8BA4C2CC5CFDD019C2B5956D3E78D5B186633ACB765E822B3D4E90 + 10: 2E87CF886036B7A66AE6581BA0DBB9AC2A39E1C7C7594319184FF3B612A165DC02B3A7133E3AB3D29634B1CD5305A46C + 11: A5CEDD2B54657832F946BFBA14ED5106E8EB5937EAC6C5405BE5CBE7C58053514E784E3F6668C20466A242D25A44462D + 12: 74475D913659C2C304BA49DD2B39B0C7AD7D537BB2240D8611876CF5955B347694525396C43CA73951E711DA38C6976A + 13: B0AEE82D70411F1A79DD7012421BAC1202D7C3BAFFA15B4D8B868A3E6F92B513F6B026E2E8FEE45DB2AE70C15E11D19F + 14: 7D06EA64FF5B9139662FCF9318589E8FF1F783754A9116E090B0B7A981A9EF1D4C1BF582C8EF5E71A49DEA2834447287 + 15: 8F52BB9B0A2B1066AB67603C552C17E983D15114C3B9776C548D747F7E24AC782253812802EC456914444DD67C0CDD46 + 16: 9DE6587211FE4A232F01D6D20554102D24D98EC140A05303C1893F232BAA2C07C81A10C25A95A50B38E87898900BBE1F + 17: E0175EB9DB2649801EC2EEA9DE2C1E950C129CA249C14326614E0BB8C32AEE67DF1DFC6320439DAE4FCDB4B037A53868 + 18: 0606A848086DDA50D031A585103478EED0259A9167959657050F8D7DD21B4D6B62B93AEB0009B1E878EDADEFAE9B2ADB + 19: D4A45DD1A6B613E3D2D72B35E6030E1531D75AF7C3F100934CF27EE9D0E0F0C236581EC8EE74FF759D7A19C5AA6DA9E9 + 20: 3E0FD11AE4933665EF30E10035B0E686DCA837F6D6FE2D5A10B4EC30F183EDDF3558309905F028DB93323D09A3A2F3E9 + 21: DA2A204C7908FD27A29415CAE3BD16A0488FA1D42CCFA2E2F5A1EFD6F99583EC6B3B36762060F547C629B9A332585355 + 22: FFE8FFED47933CC941A8E9233C037080B9465B4F9C25DBAC790825C013545D2344930E953187C77466437BE226962F80 + 23: 69FE734D5C69F34366E5CA6B095DE91CD4DEA29AD70BEF06AFE9BB232162E6BBB1349263087212AE3AE5D74A3B060F50 + 24: EFCF1B825AF87FA5199FB3C76783CCD1769E7DC77BCF145DB76FDC622BFA2425CFFAA40E6376086B2DBF6F5D9D97A534 + 25: 98C3DC50FC08D2A87ABE3FC16871ECB820D530B453C41F83FD304D51660FD29BEC6A7D1C63E3E12B6E80E8C58CB129CC + 26: 945047CD723EF4F25AAAC4A19FDEED463EB04CCB78EA318989143298DFA70D793391BB7FCEA6BE0D79187543426AADFC + 27: 2718D89F835037C94CD6378A3806614B85365A888B48FFD08C09F0B93360C04E43B7E7A19C79BCDC5DB9F5944579AB79 + 28: F714F16238075796DD43960E17AE0EDF9990132D690F44957C3DE9EEC2773683172FDCC44ED2104320726BAA7DBDA1A7 + 29: A87A96ED8FF0E7FD1F235F070CB5F14B41B2C4438A6D7A0A39D038C74008FE9C52497CC506498414835AEA1192439379 + 30: 31B029DFA85DF545B752506E80675E617549A6725A658CA8123D8C837FB71D8C9961BBC2460D7CCE0CABBDEDACB56C37 + 31: 0B1A9DD308E5E6E65E4C60861D42B628FBDB2C2280370EFFAB736A77A8004C5ACD5269D090B652B1D8F146C1D518D288 + 32: 2A160E0B2EC7BC927FFF813A2B56AE61301AA14933C659B3398C7A0B3CA506DD00FA6F1DE9C6D47AB0FB2BF2E7B4B83F + 33: 6893C0205F3F4ACE906F2FACC97E2B1624D40997370419E5981E6041D5CF34C77EF5ABDB1AA0D3C8C3740100C2711555 + 34: 95BC8C72DC8C70ADB7CD38311292ADEB9D7BDEC6A9580EF4E11A18317CB65667D344D8D6603C044454E67F97F4DDFF40 + 35: 3DD892A4E724376814DD5A4CBE96E4317AA8AF72478D53379247E77C35461BB92CF493851FF1FCF57A6704923099DFEE + 36: 3A5DEAF967BFA3EECA3F259307991F7DBFCEC1F354DF385CF0EE8D93291721553EA954E9D6593506E9F3E330E0A02574 + 37: E00A883DCB5460AAD611603614C7214EC4A566E0580FCAB1CA4ECF1386A42DCDA746D3AE1B0D54E0B9AC1FA336FE787B + 38: F437CDEA425E7A70CB4D197C0CA01562532A7C51FFB8462B4796A4FD0A7EC880CB0E5EDDD5F703ADC179374416592256 + 39: CE69E40F5B5F2F25E0B53281BE76ECB0E5B4558292A1C1A5EC56F2CF11B01BEEB1F0BA01E6A9B3D03BEB69AE0511F320 + 40: 41AA84D15342CD0675C8C0312C024352E99914C3E01C98F969AD04CB5705E9184F3821CFC6A22D43A77C928F6DB79D8D + 41: 74001D972353BB45FF3F7F405FC727CB5D0B00431BC76A57EAF17862BD52949AF884403ED6B2A002D618EA33523DE200 + 42: 968BC28223799F1EB92F1432B6AAF5CF6953491C3F959977B065BDB800AA438CC8AA7EE1304C18999CB5ED709431CFFE + 43: D067EC03F14D2D639C4423A311EC86B3DDC3693A2CF43C259BD0358F8D0D68F41950CB705249A59072A2CE7DF155F5C0 + 44: F41EB77179934884DDB56DCF83DC90C606D0226DDF94135FF8E1E0AA56C9A90881C4C380CC0AD3BD0DA45A6352BACC05 + 45: 27BF9A98F9E2732972FE2F35ABC80AE2E5A2BC1D238B9B1D9CE605A89144EE9766987384EBDCD63533E64BEE094E4503 + 46: 166892E106BBD9D16819D9BDD3601D24C0C11860DB13799F0797F204D07DBE914A7BD286B380EFAC34DFE3C940CDD3BE + 47: 2D85DBCFC431A94F8F50132DC8C10B25001EA10AA9DF7C53AEE9E8383EAADFCECC21202EFBCA556BB4E33CC68156B190 + 48: 086007E2874E779A5EDF0E176AC1A11D241F4AD8D02AA99DF2BC1AE3E5CC4775AAA92ADFE772CEEE89D4FDF1B601D05A + 49: 2ECA3144F4F9EA0F37C2CA5943F458590A1D4D19C0ECEA6A55CDCA648C99CD457DC57EAA995042D7FBFAB598B8AFEEDF + 50: 9C1F31F5D3A589631D8B7EF89A507011736BFC328071513D64E5432D24B1BCF47EB10139B6410A3103145AF67B5B6C46 + 51: E0645EDA004D9005399A2C072ED9959E4F8905D15C57992553202A3B53BCFEA0098E6B28BE047A4B29EED7B57602C0E3 + 52: 6CE5CA92F0B1E84D7578DDB86C96A10924601A3680BAFEE5A0B27D8390B59752205EA483832ED3E9343DE7175601C03A + 53: 47F50844C897FD910C5C228DEA1EAF456882C1115AB71DB15E6832D96607CB79C8B7AD1CDDE01966FCDDAA0B0BA9F264 + 54: C0A7EFA24590833E4788BB117D3AB3CE00C84CB4820AD9FD7F03CF1CE1A8983F9906BDD138E1943D75ECD9B98D5AD8D3 + 55: D056E9F831B6DBE97FC751453B1C52C8C6C4D18A00050F5AF2427C1123706375A918656D6755A4C950F4E5B5C318CEBC + 56: 462650CE3981EDD13D0FD2E5FDEA93A9A18CF8FA74CD6142DF4707E604D1F72745D7EE08AB13AFF3A9F8D166EA90CE3E + 57: 2BA5249841412584B161063087AF9F5BAEEFD97989BF8A0455E65C94B0663410F0E1BB22EA6402E59CBC5A23F24ABBFD + 58: C3B1E4B05A7593CC315AE15F63CE8D91C4B30E0D846A97B7D8F01FAA1B6BD7C9234EB153372F6CC7799A035E22A77EF6 + 59: 1E652653B9A3CE862DBBAF2C919E86891C5C03F54ED5970E8028F8D5EFB533B9C111DFD88ACBBDE516F0D4D636F5E821 + 60: DA773D5AAC336B6266D27A03AFDF3A151FAB302E894CC1D09B6E4ECD07C4AF4BE06A2D28D01669C7557FAE8E513D01D5 + 61: 8C8FE648A29D4BA78B3E0B944597E392A31E28F98B15280E1EC0A721C9ED5E3639A6A457744CC5AABFB3600501F5054D + 62: B443DECF40A5693F67B5BF5580A665DF6EB98FA9F14A661CD50D6635E0F78FB2943731AF363839FE6DFC0B4C49F9E849 + 63: B22EC4AFEE3EA69364701E5621E453A0C3988C1E2FDA54FDB99353F285327A534F7162BC54D701652744413B9A5D4CBB + 64: 40A22B7881AE8139941540540FB37C9AF27BCB164B6D1A3BEC709730BBBB413D1F2FD6BA4A7B7EA747FF45F3ED3336C3 + 65: 246E426C57E414575DF312223272819B0F49FF94953DCB94665FFF74FEAB049AF15160706AC5F702AF66478CF2BBA5BD + 66: 184E6E6D5FB55454EEB6DBE323BF28DB8CE60C271DD0ECC8BD4D3F1C2339B7828C1515F030058FF37BD53568FEA81378 + 67: 10B23FE1616AD5609F6F6C1D9266F702C1B5E6F7FA0B3A81406B5A766E2179D082854687701318A7B46E21FA67D2404F + 68: DFCC1280C5206F99A555E291AA1DE6F0A3AE4B49916FEED4337582B91D7EF094159556B01AC87BF7A8E84F9F53595938 + 69: 91BA9A641616449084A57221647369E2E69525A30B274EE5403FE95A43D0A7C2B301B61929D89222A3A03303550521B4 + 70: 94F59A7F5E68B942A5D66D3C642A78685F3BB400F4FF971BA576DECE94A353455277632B70D06EAE38329CC2298ED792 + 71: 21A9F5C4B1290D95A1F3F051A0158F7DD8A879E7861B61CC757FB5C729FE9A8BD46BC6DCE595D20649092B31AD27433D + 72: E4246F7DE67C3A08F18852F6159F5DC9FA4C0129A9F894EB610C10F1FB8B61B1C9947D742A418F03A00A7E11ADF436F3 + 73: 8D2CE8209B8362311D99D68DC2AAE6BE4CC8E52C03A97D99D0C5C15D8E24F1D3B51738BD27BEB6E773472CD22A1225C6 + 74: 7EAAB124A3C900F33DE06B84E7831FE327FD638C4E68DC8648EB619E3C7E5736A26BCDCFD3AA6AF34EB137C6A210746A + 75: 8B60F61A1AC2C6528C8DB07B6874F19B8D474859F98AF03503B115EEB8082E19D53F63D397647BC2D4278B8C2B741D19 + 76: A48D92BA646DAFF7D0F8CBCB1D574E9C19D396A30573A7404F6196FBD7E226731C8AB05138F7B1936986DE6C1F1F7B52 + 77: 2C3ECCA6E7AF0F9587E5A03D462C98F18B8C13C039D02D2D29E06B5309EDC82052EF72C94E0A5EB7FD35827665CA2F92 + 78: C9B659AFAAEAA8778E9E4E3B725F758768963C55151A54BD9DC191E1302ABA1F1F085D5443C46441793682A8047211E1 + 79: 9A76E83A301C14AC6AB8CFB29D2CE39E0E86B335F2B20C3C889651B4E0B94C5218E910B1DAD28474251D06D12D47072A + 80: A526CFAA2EE981A9A4D0EF12A6FA363F562057BB75A218F4645BC5E9BE7CFE7EADFD87386AAE1C607D812772498ABBF6 + 81: B747819B54CDFEAA751FB9F5C22FB269151028BFBC6650BC518692944C5F4195D26AEC45C9B4C987ECF4076B3871C5CF + 82: D45968D452B5349CA43A0FDEFE4A5379381625825A27259AD9BF5A80C46CB07BF1C919FB3ACC250D73238B11C3A07D90 + 83: C0B8AB0F8C497ED9562C65091DF1D80C32C57A018B00957BF53C41DF81A2F6371FCFE82624B2E84859114152B36B6AAD + 84: 30D2BF3DA80C0F37807F042FE7B878851E0BC4093D987438FC2B993F4CC4AF6F704669938B9E30E59BF8999883639F64 + 85: BB782ACEE42930922A98F65F319089E9B4F5D2DD2374DD76035E3178DB4468A3C04F5EF878ECF9ED757DF14DD89BDD49 + 86: 157424F30A10748940BBFAFB6D99B1B06A897E7DAA4F03387E5ED03F02D39AF59F96A20E4E9F3A4C5C07C20A8FADC8D0 + 87: B9ADED711B1E1537A35AF882F1F868D964B5898E85B07F5677DBF183232F36C14AF4D9959C2108D9313F8BFB14830B02 + 88: 7C4563BAC3C05444C3682039EAF9F9EC79B96F0CD36245F584647BC444B81734D7ED4380CC1F0A2BA876020E55660BE0 + 89: 9811A4A45CB28A780C063047EC6CF94328102DEED9971DB99E11C6FBCFC046EE38C1A00F290FF64356B9A304DC0F340F + 90: 09A69D3255EB08E9B3CF7CFA73D86944CCC91DEEEFC04214F8982836726CAF006A3FD83F8FB75600CBD060ECD639C388 + 91: 52D6D0943728CD2EED671736B6B3BE801B811410992E4A3BB50AB4269EB21AB945F6A9F7036DA654A7F2785869335395 + 92: 8C0E1052EF2B06C0C20F67D92E51DFBADF3655FC6475935426AE1C88F3096628EAB9858E5470FB98A546EB11C7B752DD + 93: B21351AF8400B9756F104599BA4BB78C2904959E2B24AC3E15FD0398627E6C8D57A7F9FEED63D8638A206BC1683794A3 + 94: B9F7CFE97C79568D62B07F1EF887C4391B48CAA669AA8495B71A326B120FA49652F02EC0D53441DABA1E104AF091E0E4 + 95: 69D2D1773208CE3BF02B38A7F14910187F3476817ADCC7A1D9830C9F25F112E604AEBB95D0237AC8795DCB23ECF52927 + 96: 57A9FA7CA61FA2FDBF0BC3E3E6463901B3B26E5D9AD79DFC0CC77F79EF3AA1AE3949E7D71CF794E067D2E38E7038EDEC + 97: FEE9196A0A1199DA8697D00AC8084D6CA1F867D105EE928FFEE14E5E36BEBEDE5C79509CA5BA05E36C3F0BAFDC9A755B + 98: 0E8DAF8BA4ED614B38808B4E468CDF88EC9B148017C6BE3FE593410D37D9B50ADF0913B7844FFDCC2F1917A27A58B352 + 99: C7FD40463E26D6A21373EAE14BCB7403B127A1E23E4583B2AC727106B07B849F74C0907804AA799C05D9FF324D04B182 +100: 16E899F4850512FF3DB0FCC58FEA960831364E5FB077CD8DA3F5B3F0F50AC626601917E8355E4847A00E0A5166E786D8 +101: AF2DADB17605DB3CC471C00D63C42F75F815594C1B49D9396BCFE7ED4D4FBB1CF15B542675DE8C9FF50EF81B72FF72CE +102: 1699A1EA2CAC707205A6BFAD8DFDAF09C8D6FCDDF2BC14A9678453463AC80054627F2C39B713861734B0974F442D707D +103: 186DA71D7E913DA49D8D97101882B1282841D41CA12F514C1B2DD61543E330B751E9F97490E18A4A37FF1853EFDD757E +104: D82050038E6DF6EAE9D2D4019827025A25BC8CB15812E0ACF4B676C799A3D80ACAE5706C0FB1FF72B2C4851DC9232B7C +105: 1657C99506EC8B28AFC1684C4A9EE4970F8F426E4BB0C3FC2795CFBA82913B453C87D84AE9B32897A4CE26FF4320CF23 +106: 9834E936482592BAC2373AA64806FE0D5C8FA92143070C61E594004F0D3B8516C2A5B0244F273124E83B20FE9A2CF5D3 +107: 5C4856A82C8E6E49BB81E89C26E355AFB75EF921E579EC4B97868BE2CFB4B1D93195ABA0500D774C5365C2269FF333A7 +108: 67B88FAD5085C8BAB8E194DF73153A5B1D334431227DFC619D5CA5D5605EDC7BC95DE33512B2F5B714F46F54E1E61B0A +109: 90C6A8F36D42C5F21A89417AA04D822A53110DF1D062E0C1A6FD9AE59C6588CC1C78469B94578B6D7C05EFFAF7FEC26A +110: 817C0E7ACD548BD3733792F4F8D845D7E4B3CAA0F0EA943B51235EB82DA7C8B77A733D756E86D57EA303F34BD97BA1CE +111: 7FF397FB43DD909AB80BC381EAA4BD50B7278DBF10F39FE718B421D6C07324F398BA5B1DBAAC64137267DE2C62F19F7F +112: FAC12B732122E18DFBCF8DC7382AB1B55353134F07E07723608825C907DB05B4FDE40FE550878D971F8B0B0953C88C54 +113: 4DB0FA3C105D64A9CAE84C0B5D7AF0955F6F58717F68366935FF9F478E94D3969B1264B1F37F8F5538BF116DE29438AE +114: BA6E693A6C3C5B048FB7F232CC5E12CA71662332EBF689AD75F6F2C54715A689CB1F75525313FB8B2713909EC13EE0D3 +115: 00BA656BEA25DBA36861B92B356C3DEE0DB1C86D4503C7FEB0A88A3541A7018EA456C95224EFC46AA31CB625421BC811 +116: 812622078CA3B4F59141569A0E125B36F7CC471F76B7B65FEAA1F1F656BAB6A3CD61A4D2456E2F5109274B2090C1F4CB +117: DBDAD8926A811DD0295C31D55AE0D41672C7F22B5CAEABFDA2C1505B084AD01440E9B8FFDA4DFCFBE281222AFD547E29 +118: A32EBC13D689B31617D24E6AC03CE6FD7B1AAA2BA78CAE2E24C36A8CA7BC74ED9BD4CF6C74E3C96DEFF048FE3964F0A0 +119: 095D2C8DCF88F69DA4CC49C64B03B2A1D2C6922CE0C6EDA12642480AE0DF35152B4E4A9AB08D6642DDC313C0FA01444C +120: 578A4BFC0CA83F1B38A0D2EABE2C7D3D67436B559624B92E4FBD9241B2CA8C1AB679B503A754D5029314AAC3AF225F38 +121: 25E321E63E4AC8994FA464B3E2B687150007D83ED8D6E1B217E86B0CA0D163B0B9686E4FA2F26C1839F2D778EDCED86D +122: C761BA17FAC3CCCAF2CACE92283DC5E5B8A6571958FC59D0070FB21CABC88A80A40DCD56318988F3AEDF38AEFBB84EB2 +123: 5EDF5D71D2CF85E7ADF9C7E964FD628ACF304C4DE3483F672666A583E3D9B1D86E9E096541ADA237D69A140571F5B3B9 +124: 401702CD847ECA2BC9208F52F27D84D07B37A86CCA5C3A877F24366CDB9719DE63670E850F02CD02C6227B7214D5DDA7 +125: 362C899156DF70FA189A66DAB6DBB3CBF80B629D1E90D9ABEB007C3C5010277EA589C4D73009C81F94AFF3FFACBFCB1F +126: CA43387C71B8245B822D3085CF029004E18CEBDFC9F78C276F3559D962635601957B6D2287089AD43F3179D077F37686 +127: 4CE8504297E21812C901E77C6680529103A017553F095913CFF06AF20E3D6DE7EFE911B636DCB5791B292C60147F6473 +128: 2AC71958C77E39D4DE4DACE92FBB6A093EABD191320A5ADA7114BD201DD026567D2B799EAC78C1F084BA9FAEC2FC8BD4 +129: 87487060C273FE18A2CF1DFF222658E1B50C3BC5A3F1F4575B3A4A6EA2F42238DEB68B3A2EC6A325E3FCA504B2E20E26 +130: 4A79A1C3C798D9F26D54715108279948EAB246086EBFDF0EAC9152216C0BA3A77AADF82A230AA84A7C884063960419AA +131: DB0BA43960FA6B763202B8BDF3FE4ADA0BAD78EBB3E6E8E57C2D5640D1ED4CFB4AC18ADB1B9770DB49A4252CDD25A369 +132: EECE296E258EA3583FBCAD1CDF2B91F4D2AD1FCC1AA339D8F591F89C7ECB5EA2FA644954006F0A58F2F3BEEA1AEAF7F8 +133: 7AFD95C86517BB6050D04BF3BB1448A0608411B612A7C2A939BB44B984E361C40569E5E57AD7DACB018689C2B8E2B3A7 +134: 7FCE7894C8E8D1FB187CC35CF5758269E286427A63A522F4BC45F814B316C1DAEF981917642C50EC693F3EF4DB8E66E3 +135: F67F56C98221892F64E2AE4325CCB80C2846A43E1629D40BB50845184E9C3B66480B3E9F792389983F2FC48FD2508F09 +136: 1CD915561856936AFCC75530DFF151F49A34D0DD0030766FBC1BE47D611F10502BE86C97B91D0E8767D4F38913EEDC1A +137: 80D9CC8B1B2B883C4735B3C0C19AEDAB78A0771753EBB4688A7E584BE7366B3C181C8532FB3A8BFC484C9CB0BBC1B4F1 +138: 8ADE2B8527C994EAB0807A89CABD5B075CACFEF42381DA3CC3D702316842E25151C65A22E80885E5CD5FB5870FCE501C +139: 2B403F2188D086327C92169871FD5A7B432D2EB999FFB0F2369B2B766E799AFDC1463CF4D9941F828FE42591D6B966EE +140: 4A0C18CECC0641C28C4136D42FABD0BC27FEC27C2587FE8A57CE0D279ADAD70F80C1E812E01B26F2BF3ECDC7673C349B +141: 8906762B63651DD5948C98DBB1B39BD6095C1438B2E4CA4B5A581D451AD3EF76C8A0FADEC9C0B0036A833D8F5C13F1C3 +142: A363BF2A479F67F949AFC151C36B052062CC2CE840974BE2F5E79C0BFD7BA29008A6BFDB55B46527D17F61531C953081 +143: 4E2AC5D6EE56567902CC1E02F119E33974762C03885EB7DFF7C58ADE22E56BC384FE74BD491EFDB2E6CF4021E3016E81 +144: BDF0AFDF17F7B014A61ECE257F8C7E0B52384EB7DEF60ADE785F273851D645E5D3B4D9534C0E6097A12C3CFF5C11D42A +145: 0CDC61FF0B3D8510C319020B82C1C5AA12C7B6F257D7D4F118A5EC3CCE03C63FFD38710F8A3C621DD8D66D8BF3790B63 +146: 19E35E1E785C7A41C523F88CDCD919EDC45F63783330D9033768546CF59D10AEBC77F013057C0E41D6FD0FE77DBF914D +147: 8AFA5DF52F6581794FF014A2E1ABCB05781C7F44AE6F37112B363AB13FF01FE1E8074F14466A365374C29FEB048C5B9E +148: BC9ECD12706BE5ADBA04DCE84AD53AE1B324F99C1F5937774DFE19C5EB4D6A20982E97B8F8E4E02EED13B25B8B13E64B +149: 8D02A1E318DA1EBFD1CDDBB7280F3603AF3AFA21B3D4E0727C7CFC576F55640B7A978B179EECDB8FBE896AD38E82F12B +150: 196929CF0849022CCE9CBE4EB2DAF6E5D8014C5A25E119EFF799A82053035BFDB8B05F6C125B1DBDD4E7B393C684FB5D +151: 58808D04067FAD72BBEEE4F6A355E80A2FF76EDBB5366CA43FF358A842FBFA2F9E1AF5FF266BD2E2DAB1D286AF5BBF92 +152: 4A548031093ABA730D8D99A2C1C6EC2A986A94167CF8C1EBE83D52B34BC2068A4C95665988FA93F5246D0FBACDF85FE2 +153: ED949965036F16A0B5856EA4CF69CEDA35C653BB56FD0F0B397E73FF4884B3E679ECCB19B07D6A93504E82A1613CB87C +154: DBA644B20B01E4AC5CD0A325CB063EEF53AD77E5A9E7095C1BE0EB0E6B7CFE60BF25F38CD57F2AC055D327EB6AECC7D6 +155: CEFD6165F70D9019866374AD7AF9C73F3041B932D61A41734E39AE8AA9C7A4FBF1DCBAE9B2A4E979C64352E3CD4E1B95 +156: 732C3B457F78DED89390BC461380760FBEF3CFCB9BF42A6C86ECF120C821CAC79D4D51C71A955309E33724742FE2FA0D +157: 54803568BAE2DB4F143C78FF53B85E6A9D42EC3894FCFB39BED8EE611B36BBCBED834D366A1F797B626DFF3D83CE963C +158: 35A1858E567FC8A11B92737E369069B12502ED3F44DB50434506F2E540FE643655CBF806C06F15CF2428FB408A65C04B +159: D1F9E930418D10043D0E83096CF717B79C1C9234C741C59436F42737AC73BD39B3F4B6D6439375E0D44260131B25FDE9 +160: D5B56A1A70C47A3F88C519668097B54C989E119EE9DD5B8B34F0DBC092FE7108C9D396CFC62C9322563EE72A0E324010 +161: 1578BB76F87DB309A5D3A2229A2B346DE39ADB623836EF0561348ACA7E315C16C6E31328BC70DD0B0D7D9B7ECE076CE6 +162: F8DF4C71F3623ED00EDF8EFC4E0EC154644E21E78B06C9C5ACB980480732E17E92ACFA059BDF299BB6C8351C6CC6AFF2 +163: 090DCE25595D7770753B78C410F10E830140B23D779E0F52FC451582CDE7511A390450F8B65D7BDA77A18CD95EE3DD38 +164: 5D3A56D23BEF1324B1EAE33B8255F904F7DDF131517200A505031D41A2EC3F2AB03912DEFF6BCECBFEDCB8B948CDACA2 +165: EF712AC1E6859F70D0D2CACE7AEE120A666DF9F210512F5C94AA7FB388F1DDD913A12FF92CCD2537675EAEC870203411 +166: A0E6443505B193D89595A51BCBD47A46E1B5AEB239D68B8B18A119E5C9EA1EB8863B373F91B9F22FA944C29365406A79 +167: D97DACBF80BCC76335C187DA29FF33F6D35EA8A8925709322EF3C0F6FE35D128D9D423F911EE31F1C38E1DF36046E507 +168: 67FFCF0A9F88F84B3EE85000B2DE0B7DC12A06160FCBBB57BA291DC04E14B6DBB3CDB81A40C2EE1859956DAD097C1EE1 +169: 7AE82196B46DE3E6948D7FBC7383A6F080903D6BE6E357700A87F82A964581D375006DE35169446B447537B4F11C5702 +170: 502E0A4CF125EC0640DC7E7264D9E47300814B00D4322F2F62BC1D5F1D0D77173B0E7C2874CD59FD8E056B8F38F78D99 +171: 74FDBC4532534DBF24230ED5677A920B12E328E3D073364498D80F0CEAFBEC774EB53F28F0934F787C56AB794B60BE31 +172: 3C9BF5EEC652F40AA0ECB82A834C836E495E841D337E1299AAFC067A2049C540AABE92CAEAE02F099BC4D3A383D541B5 +173: 105AC61F2D4E586E376524C488C33521C4D49D1F95B752D27F49ACD7181E8FBBCA2E0F0B543EFC0CBD32A5EED2CC08A2 +174: 5CA49D8B554D70B3FC467604661DF8FA51D9987F2A77B13DE44D7809FE2956D21485B36F1D17B59F2261B1B40553FBE3 +175: 1DD075C696DB9B07510A0D276F8BAD12225E00515D19E3B85583BF97CF82B5FE3F685502F64D91F4FEEE1848BCD0502B +176: 11A018C4B213BC67C09370C8A3D0B720428BE71C01C6EE9EF6C9C9DA8B2E1FBAEEE42FA44EE54D0F526DCDCD3C2BB2FD +177: E188EC519C6E0B8A89DE68A7648DAC6D9F84FDAA678B431794EB4BFE077901C95FAE25CA3D39D48EA0292F3F6C35FF73 +178: FABEE0B0A02BA622931A5EB82CD63656B47A20D3C0E703D5A69AFDB92C0A7EC5CF6944D9D7A141C1255D60FF9532B089 +179: 3C8E0BB55E099CA9F6E436BB3CA39D511AB9CE5674469DF8BEA4A20193084AF8561D5130FDFFBE62193A712D7C2D4B48 +180: 914BE8F0A58082B877AF0DC077ED146CCD8245339A170B4099B146476B0A580749D01F83FB52834A033A3822D12041B9 +181: A1B31ECBF451571437DE10330A6E9AB4484576AADC4DEE0B31D9C3AFE59FC6DE028275126D7882A2C225EDFE491305E4 +182: E4DD2E805A5BDE3DCD329ED9D35CAEC2D5A97082966186118DC46BCA7AEB1EF52E0C6007CA28131790838DD8C00E96FB +183: 785B81A972DFC6A4982E0BB76F90F26DBB7BCD2D06E872304CCF6AB2D639CAD85FB29124ACE411EA4742468A6663EB2A +184: EEC3CBB5AA129C7206A32A176482C9BA24FE60E71B46F7C3C11FEF8EB57682A3732680E6541D5878CD6A715A48D75F12 +185: 254E279B7C4F17B911712BF7138E2C6933815BAB18661CB47388FEEBDCCDFFFB6AE8B4B88072B90074704EB7EC567843 +186: 9A8CC3FF0D9637220CF2B4AFC9A8A6CBA4D0ABEA6A0BAEBF151380848E92DFED8C0F0E57B6D05095EEAB0A58DFBAED13 +187: 349966E1D59BC9B32E1BEDB050354177868FC07257A3A1800F0E711AD00AE388746DB1E4591E3ABBAD8F418E1AE627DD +188: 84ED950BE54768557475E6B1A256C30F444E12340C29485832439BBB9CBD219050D184624D6282728D4AFBB98CE4BCD6 +189: 2A7CA4EF1A9356E853329D336B6E7E033F2CA13677BEA67CA669EB7C78DBDDE67F9E7D9099C68F34E07B96DE4155AFF2 +190: 7C7020B0528F1B3F76BA258836A89BD27429110F0AB730FD741FE9EA2714AF827E71B731AFD53A293328788292ACFE23 +191: 91400ABC089F8888DCB22880B87A380FEFDAF81F237D424F057E5C4C8E3C8EE4E423930C1D3D9E16199ED82996BE4232 +192: 412979E13B3D143270BB41FEBC12196B981E99BFD6687B780812F409C78A5E2DB7AE828994B60D26CA4A1F7A3A44C64B +193: 02BDD417852D9B03A37338549DFB6D765EC4CFE4C2385002848BA4D46F88053FAD2A39DFF615ECFAE0D41F02E5877251 +194: 77845BA2210971E362DC117B1BB13D7DFBA62F81EEEC7068D3CB9CD093DF535448CC357ADBF0C2394351EFB07C3E7DE7 +195: 0F43AA1739359C14BC5702322F193AF89335887F9175289933B2BB3F00A777D1D1DA74F5D45FC43AA90C9FFBB0CD580E +196: D1D9A7B995B9BFF09252566D2079121AB12B0A5ED06014994464FA1AA18CB1BD8E7D5E07E1C71E2EED9CF081A537F28B +197: 67DFFE8A168B7408B7DDBD10BDF14F4F2244FC904DEC5850F5D8302FE35AD1752BAD2DE50449F9C12182A2AAB8FBC9F6 +198: 030B5E833F6D8703BD0C5E36354387AF833F466AC812D4E1FAB6CDCD3146FFE3B0E56722D671FB85EAB22CA5CB0309BB +199: CB992B3785E51EF3A32DE88073586DB045F356F18A09329E82943E29A12B2D1490B386D8CEBF7D90FB492966989A73BE +200: A1D337D363A0BD8A0F2342351519C62318A120FAF88F9B90330845DA682261C64627B67D2F533FC48D2BE394DF8F4F61 +201: 319DF6326160C7277A3D3C65995BFB729A69B71B40C149DB1241C0B2376B4205837B5770805C86104677917EE5E5912C +202: EBABE3BCAD828A9A3D5EE05C5EBA9605A67E1ACE73AE69F20BF435C3A14AC63E43B61021CDF3FC2245A14FC14A7AB32B +203: 1723D844C0558D58EB3EEE3286C48C133C5F6C1D8CA512F2BAF1FAD7884D4FD5C3000A6756DD1E34E83DD066AD2BEBE2 +204: B048BED188BFFB8FF1B14CAA0BACE82605AEB1C666283FB7A6FDF216742F9F64A89C50B9852B8119B5FAEFE64615C241 +205: 7FC6E8633CB9B16F553ECA3C75C0C0F7B610010853EFC94AC330D36977EA8722B970DC264D5FC4D69F39105E7AA0EE3C +206: BBC6F0E0158B6DD549C5BADE0FDFE415747F1FA2D2A85CC9DB758F34998FBC8C8D99D573CD948EC768540B363D67C4F0 +207: 5073FA9E162BE773AF5BA1CE5E6FC21F2F0F902C80F09BBC3AECAA6CB1867DAE4DC011D1DB987642949E8095909CB984 +208: A641BB0E1D20D5DB0C5CB33D35B73ED83216F2F5DDD5234A0BAA3B209A39E015B7245C40F9F372E618EC73450487B54C +209: 948806B7335EDCC7C4BBE751844DF5717457B223C7A3B81B57AB3A949D0A726BAACFBA228BF6C2CF94E942F9B2F1A7AA +210: 0451CD5EEA206D50A7897F495D648425CA333158C126C4DBA44ADC06447A51D3C7BF2D4D81779535CAE29792C7FE5650 +211: B4227FEE0A32009D60C9C30033C12B7143D4C7A1C25F39F3E4A076BC4943992AD299DEB2C15E27DF867BF948DA27C009 +212: DAAEA18FA433CF3E117F2D43303139D3F1D8C3BB8AE8EFB30B44B9D5D4BD4E553B9B6EB9019CC4E1AE5D0DBB6C23A102 +213: 4434C818BCCFD92189A3A466D2757AE2655BF0D6CD954706C85220A33B95B184EB560FF3CDDCC4DF557E427E60F9FBFC +214: 6AA3B44FA507B6D704A66B4D7F26CBAAB2B400C6BE0A8B61B50EE617A16C2C09CB36E72FC309C6E4DB24961B1785CE3B +215: 63AE9C02B96B4BC456FE5CB9BA35366DD69E78DC9CEEC376C6780703883D609333D45CA577A982A177515674B975B658 +216: 3B5DD4CCBE8CDF32009CE29FEE4F6EC7CCB1471A3F8E9BC9A35E8CC37F6C56957B757DA4C3204F9014977B93F9E30DCB +217: 04A6528CDE6BB9F425132CCD4AEA1EC6CEA482249E5F3782B000FB071A4EB2434597A7FCE2A364A9BC9E0643A8403DDD +218: 69275CA1F9F102925165A568C1F152D25DF8820A6F34595C4359159070052FED260C55FFFAEA2116AEE7A63DDBAA0160 +219: 584697C23C63904709BEA89F055AC592DF48034F908C9F06C706A51C3F6BE5F0F2A5B953AC2119FBC0855B785326C06D +220: 04221F0A6C4799F9CEA3C1D9E65B9F77F77C613FD114135DB019D8C497B8899513AA4B499E720CC11AECADD1AC071DBC +221: C7B878613C2F2ED10C8EA413970B124838F11F0414AEC89A3825DDC588629A8049E82B461A23F25C4F93E5BD11C184AC +222: 1891E7A51768E05BB1D03A1EC1B844C7C8EF77C433F700175998B2D8E2EEEEC4618F00003793C5873655E093048B674E +223: ADD2B81466BC727AC85DBE258B566C4DB56F6F7D81D7A4E43F86C125F2AB2E08C648E628B9CFE440F8BC06FD5D861D3C +224: B3684BEBA86D275745CEAF0922473CA581CEB7371C5747EB87B407468006BA50D69F9BD8BB7F214185CD0D0C548C5432 +225: 0C783882FC826917619C07FD03FFC46DE6CD87BDFA87F1FB872989489C32FE74E8C5660748E1E8E9AE19C68B075B0EBA +226: DF52553B4F7BD148574BB47F61BF8F7B2FDBE5B6963E29CD559F236BAAFC3DFD6A7EB5EC9968E0C2B3A453F982F16AAC +227: 45102671440B04027B1F9966C1013AA351CAA3F3CF42C4D98F5B2D030FF37836E9F5865421D7DC8B037644FE53C6B280 +228: 247396BF60C0FBA27B245CFCA061D1F6EC50CB87CEE54E8C4A7186A07745D255E4EF9457C0A329AC9E3FC913DF86A4CA +229: ACC5998C464A26C1719E9B17E1B8F5E3657FF0364C46FE87154DCD1C95A84734214D2B81CEA8DDBA501975281EF4EA9D +230: 163F5AE385500C1A6EA212D6925E48CE2189DB1DD47F7F2D2D889272D17449A1C33EB3970A5982EF2FE5F1255367C33E +231: E8BBFF2C5CDA88CB60BEADB8D04B88795B0CCD89057CEFF1FF588A169363AD453564FE7528D1FB7148845363C3E17824 +232: 5F8671B7C62A5EE9717FF80EC2AA0A03E557A2840C0FD0B59027AFC834C051CC9B7BEFFDEE3478165DB9CA303E2D874C +233: E0E4DE22993E4A6B4884163C678A23AD6349DCD4C16B9041D01F8B3FAB1E8D8B07DA78BFEB57F8C235C173B2D238C4B7 +234: AD6F58BFA15FD0DF1191171F86F2B4C8729FE407128ADB4FAC3404E15C04752F2A4B5F4BDD488378C56FF8D85A38E583 +235: 90C5A75642A1811D8FC1ECB84AF4904C6D9E613353C1B9ED0FCA37D20974CC2425052E2300738824BECFDB981AFF06FD +236: EF73A9E6D23CE43508400163CE6F3E8F7076CEFB94E549EB6116C2557F740D66A1727AD51CA645A7F9022912058FD262 +237: 99FA424E413A57DB2B1B851098FAB1B6D3337AC7FA85709121F0BBDAFB3EE291F44092EA7EB28E9BF0EA0691AA531BFC +238: A1E0A088A279E750CEC429D0AE320B638ECBF9EE387C65C66D2231C884D844DCD438D4D4E052B8D76998A444E0666629 +239: 0657FBA0E7A73F7525505235120C44AAC6D37CE974FF23F52872D6ADA50DA022D417D8DAE40E80336846E8CE211D5AC5 +240: A72ED7917F0F9D0DD888DAB10AF9091A380F518D5DAFC005D1EBF0013F57A7452AEBA98913F509509A02665F332EE255 +241: 74CC959DC6CFB31CFBBE9CE8ABF32D1629E0F578F9199B9A2E90889A2F032919923142AB32E1DEE0A53ADAFAEFE0EBF2 +242: 9E4D463D2E3DC2B98CBA40EF84B022A76D01926D8DE6AC05F995C07C5F07D01742C5410B240240459280D7D278E8BFEC +243: 0D74C427EE654E4790C7118272998C131337D0D0555B68F488AC7CB8DE3CFB461B0248E78340D74B828C80CA28ADF478 +244: 952F274ECBC66B68EA74CC8534A5D7EDB219B755C91266E5A779EC22F52DD2EFA9C447DD311E71C90E1419B4B2F3DAE0 +245: B845B0A56AFEC2FB399559FA77C4835D2BC4C3F8D62BEB1C45462BAC661D2E553B43D0A86073F0BA5AB85B129ED20B1C +246: E65B931E25101224A6933FAAE7DFCF22FE84759937F5F3BDAA90D9C8E8ECD0BFA1777B99A77E3232E38917F9432CCBFC +247: 4F69FE2CB97E9233BC873D153ED9D61B88C20FA333BD4137A532F4F703A323FAC6F8675D8B44EF5FAD2314894F7D60B6 +248: B36F43A6DD2917A1AA0C6B566599C274701BDF03A5B7DC65E5E9F0ACF882786F07989B106A50D0D89629136EA0E26EB1 +249: 8DB7B80635C53DAEF891B777850487E72B67F57576EB05F708786F7665F1FDC2A78F441636569D1E84058A43F0243A1A +250: 14A43F1882AE0214F56819F4AE9276499D39DB4A4A939275DDDCDDD80CB6B70999E6178C4EF295E69A807EE5FDBF9AFD +251: E5AA44CEA67F0821D4ECBC981F258837A243FD901653D484BE5C24EB7F08E0BF33525EE3DDF9A89E1263A853485B5A02 +252: 0191F0505CE5512FA08500BDC090570F0C430161595894528FE7AE5DAD8726E110B0676181A228A7A90E21B7B055361A +253: 76FA1230972E771661485546D6CE556FCDA23B6DC0FFE94DD3BF7FF13FE9B46DCBC8D8FFC617F35687903B972FA7EA43 +254: FE280E1191D21CAE12EA3B53D77E03EA4D96108D35555CBFA9B156253A011ED91B857B82D644BB94BAC8E4FC4E0142B5 +255: BEDDC3C0E168A4B14B023DFC1AE07BE9A418678494C2399695EA9B17843D373077A708F8C82F37657BDC101950FED664 +256: AA5D7EA1126BF16DA2897AE036E94D1F96875AD306B19910EFE3F17B7A98F9A4163E4032EFD17DDBF78FE3321047509C + +HMAC-sha512 + 0: D29B9E3F87809686F34109FBC718D6ABBB09C278CF05A206ADF21463E1170362122E58272A31679720B254CBD63A7C6D696BF9283F9C6897E7D792483BB0388C + 1: 5EC18FCA20788348244720D58E9532B4B699E78D48CF7D7BDD1A4E5C61CD09C075EA7F112DE379FBE953332C6A7D6273B3F6360BC07203A5175FAE618E4A2F55 + 2: 293D275FDD5021716117D2B85E6D38F8D60D4984BC73E2D8D7EF5942CF1287B65C0675E566794786FEA18AED1192A024FC4B3E0505D91E1F91833B210590BFDF + 3: 8D9E222D6B16C58B3862D6BFA556BDFC2A4A152BB2574C2294D5381F6E38FB681500A6A19D55525B337A467A2FC30DD1684832FFF92AD071EEF05BC4F4399FE9 + 4: 71E7028F8C4CE9C1EAEFE459771528D26993E180E616D68355B9C618153AFF2C0E9620B151C8F733E71180EB87BD773A512B945AA353029A8F807FB2A8FF2264 + 5: 589F462D37095693ED0C1F3E0DCB892BD19086FE033718911931509EF6195AD17C79939A87665889EFA6DC19A69BEC6E7058531552832CCBBC06F1BEC70D1736 + 6: D94FC6BDAB3613271522BA05C998A6D1C57CAF0E6EE929651762F257E7EEBC07F5CC7CD3D4064A2755E408B347939B3927434556B4ED49CA406C21D1024E6D80 + 7: 4D8A886A89E9C60EDA3BF0BC512A295196C3F62018936DDB24BE9F6AEC7AA9511B33CBEC8A22309B6389417F4E7FB0489981CACF03DFECF7D9FE5B91D62BB719 + 8: D0E00955F0FFF98ABE885970EE44F1B5D4C23C205C64B681381FA13C543106B2AB4E762FD71F47008B4C429C39ED3D66B3EAEA946674F08684AC99F957F50416 + 9: 4F623E52B5FA2D556D25754FD00BB8429356FD75FE2EC57EB4BA4E25CE03C5332D3A632179C9FCFFF140E6B443A4285F4A7CE881E6D3EEC4FB0DB26C0E2DCDC1 + 10: 5196EE8D442E5308F9D8911C87050DD3C4842D0CDCF55AC554412CF096EDA94BE1A251743AD5BC5F8AC902A38B66D7D57C90C29200984572D57C04F64166B803 + 11: EF77019B0F93B1598E38D3B1B703B52660192547353E7FCD5A7C8525DBB516970D3A6F2A94729D90A5A34CEA255F310C1F46546C2A08975AF477DA2F3689F17E + 12: 0A77531D7081095AC0D0ADF2B379D3F820DD20CD89610917E287FF57BCA5DEABA750E1E075DAACA9CC4DDC74732E6F7BCCCD3671B6DD27503CA855EACC63FFB1 + 13: F1E04B1F7B09DA270A44B62DBAD2FC0160BA1D144D7721010D77ED250A00986932CB6652D95B4A977494F11AF7E7FC82A70DFDACFA11232D653B1A052820185A + 14: 7BE1855550A49FF66D6D395DA7DEBDEAF674F1AB192DF82D74F6BAE8088F83EF1471F413CE00A404486213E41B42CF6C4F7FF1BFA17A1E28928B7179F0A966EE + 15: DFF2CDE8856D811494F559E9F4159065A50B1E82961628E95F04D595F670249A2B71C2625CC1CC2B1F85829255DA007F0374363EB749E935BB72BDA24B8A3F70 + 16: D2F7FE57D9583EC1AA733403527DFBB118DFE07B2A60C43039FB238A7205A053E0496AD0F3C1896090AEAB3088283C8FAF272D1D53B5F9F88281E0A53FE7F8DB + 17: 963F629ED8F0E7D6D4CA4DC8A8B57C825F726380D0BA9A9857459491BA82F64A929EC4ABFCF79374CA68BA812E3A83A643D05454E146E9F4103D17E20B8350F5 + 18: 1FDAE69CA4A9FAACDDF30A56B23F14768EB7D5616F6666B6F01FE5E216825CD4201A69CE3D2D1D2C3D03246BA7D32ADCAAA4A7D03B9AE6AF4CFBB474E1717BCA + 19: 2532E98B6D91D8D658BC1A1FE41AC719D648D47BACB423C031A8E2E9C25CC6650D3E5DF8046BC3532875F0C8DADB38AA911F216E6741E9FAD700D31269EE5D46 + 20: C81E6E9F4B75A4EB2B903C4DE28CC437CD87BF789F6BE60EF521491CC7E44AF26E9EFAC55961135F79B3591F5F7B92ECDC9917641BDC34943C6759AAD9437498 + 21: C0C2B9478F956800B64FA408BB0E077FEF48DE4B146926B3C577C00688829FFA6540AD7C211A807286C546F7D146F95989E77B62F5E14D62FE0C77C85FCB6CC3 + 22: 980D06C1B27EB2EB15069566BD1BD838FD3DA453751BEC564C05941C9BFB9EE8443EECF84CBF8AA7DECAA294C7D1A3FA4A39C20A4659DF332CAFFCB2863A769B + 23: 70FB10E482AD19447CFAF10EB9FCFEE67F9DF7164B2647F19CB220E7D83BF892AB7B5C5ABB73B779522012BFD464D9D1B18C37C3F6CB70EC4106FA94F8CEFECC + 24: 7AB19BF67380012D3A53B93AC15E353D477FDD1E2E8851CD5AB5F36EA0C8B128D3193934F837D23D232F44009AC60DDD358AFC8D3A201BED3EAEEF74C03617A0 + 25: AAFC1227AC42CC27BBF78FE26B3FACBB7B15360891C8EAA8C737AD42C00971D02B3A07CA751774D02F402F7E76BE08E2C1241EB66242DB5E11B342C22AAB9FEB + 26: D8CC3BE5B48C7BEE8522BD8872419932907B78392B7F2546788477C858D0C7BD772985C0B0D202AB7E69AB5F4E1A0BC848A512FDD79EC29F19BC4BA6D28DEB07 + 27: 6133D836D68C82658F6263F794073CAD9029F20CC11D0A6CF589335B023CFD66D708F09136546C6C08769139363AE5CB4CC2CC86EC6911237ACBFD8B0423E377 + 28: 833DAC9CFFBD62FF0749391A42324E2848670913890754E24ECC29D4738AF00A78134660A20078FE59C66113787F4A3E6C0E783740B2F2B2BC8D36FE4EDE39ED + 29: A2F3BC0DF058506805DCF5CC3006CC4FC4085FD846C7A7A7DD3A06CD6DF635359F4FBE90A676DABD7F9AAF42577C8E3B07B63B9CEC8A9AD05B38D16F56214E8F + 30: A49C3BB487C561E5AADA4FBA2D9F5B42681486AE2DF56087DD65B3D5E03C625F709299C84C64A68D87C92A4CC90246D608E692D1FFCE2C099348CD0A19407C2B + 31: C8D7B7A7FFAEDE88963B09A09ECCCB4CAE77DF9D8D242BA19F6485BC7775308E5D11C78FE9C46E609F3AF070F3DA8ED929C103DA1F25BE7867FD4D3E4F2757C9 + 32: AD4627AFB02DECFF956E612537F011E82CB0C202A5A11AB7AFF55A201016C02CD21EFB4EB197BC2D13D272C6A830FD77F534E800B0AF1E79FCFB626ED6A0D6B8 + 33: 8D4E232D9614EA1194E60748496CFD32A4AC249BB8F08E55A7C9DFDA708DE90D067FC433EB9DA2A6833D43BBA8E8DBF31137A3C9B26903060EF9217471E9F945 + 34: 4CE5E4055F10F1D2182A7892F98206D9A120FBDA3251036B7EFEC835C95B4D1FE0BE3892E2363087D01948AA426AA403ABE1CD79F0AA851E2D1195511C7A85AC + 35: ABD65F8E9A2B39BFEF6EFC9A9EDEF6572489AE82034EF3BF2AE5F380026FF4CC40AF093F0408445735C0E6EBEF5D7E7ECC13C98B59807AE01FFE1BAB040FD14D + 36: E8C687D7AF785B1E547307875682ACD82FB58A8259551D81F309C923C2B1FBAF5935EE059B89070B8420F71EEE3BE7B1E3B55B196872F06DD1FB890F6FED11CA + 37: A344BE73E6585E0CC31525BD6D4EC3345D7780CF180D0D5C2D5FBDEDCBEA050A958FEB13C21924E311F57FD6A498756146AAC58412B98E4D2A3B29D9B77A9F53 + 38: F0A088CC818F76A1FD6B5D707B114BDE24245CD55E48611ACC6AA497A0CEF93768501B5F280AC518CEE48C15373118BE7B72F8ABB2E9FD3526DD1C18D9CB2545 + 39: 4D56D5C9222BB78E04DC9346FA9C4ADC27AE08DA3E34F490A13F674264896E58F9E9839715F633C7195B40DF722441275C84AEF162B513E673809F7874E7A124 + 40: C4B3C9E8140F0D5589E326916462354827E491F3444E0C361512E6E761F5E24AE1873B238B73F32F6BF8F1D1D8FF9437A01DACCB749282E776FF66151A4F7E19 + 41: 7B4E07BAF338DF6479E169EB6CC64CFF88167958D44C5CB6606964B7F9ECF5F3F1B1F695C63F2BD66354722F81EE4BC90B9FCF5345642E264C66F6950CC8C481 + 42: 8571A8F76A1D5DAA0900A03E236FE965D085BE6035B7C0601EAD338106BE7DAFAEC82F7C3D8AD346FF749B6DAFC69901A6072CA089B7A5724C75CB0818640F7D + 43: DF516D84392E571C3FE39F4A0BA5D16D866553644B4C4627D3513F0A1C60D22FC5AA4276A71CB37BD6D6AD05A12BF812A2D5388A606583B78372B84DC567431E + 44: 535AF3C73B479B61B8B70E590E335DC4C1E22DCA656454213E1FDD46D026B6D36133BDD372FBFBB27B6DCA8E487F4A54BDA8C5F67B37C871653C656DDE9524EA + 45: DBFA27964DC6A80FF76112FC6CC02C87811DF1ECA3A8620A5030C600561032FC374A6B060FEBE0ED67421D9217D2719F5A55621736FFFC6F4F26DD4C6049FC09 + 46: 6F69BFD2C60AB1554023A6A2094D30CA78D364501F7813A2CB73DEA94AD4B94A0EDF3A3698D6A30C8A5E764B81F51CD0CAEF0F996B8C685A345AA630CD10570A + 47: 2769DDB3AF3DD650BC381D7B10CBC4353699A2A352E57FA5D5CC4FB610E498767F49104ED0F4E06E2BD563F7F8045212F5B9C49CBE050A1662F2262BAC4053CE + 48: E50169B15772017CD9FF93D1B46AF273B375A39D174E3B8621EAC8EF968BD967E1448DC3B2C72A667EFAEBF2B90D4E6640698CB866075E95817719E0EE61DF30 + 49: 4212648E8F9ACBDC16D48CD7B355884E0817A95DB03BD9B8AC5B28BE6371D8AF83546DC82550B8B23DC77F6D06211E3AF3B25528BE686CCA1672C91117DF9762 + 50: 33C71EECDBE503A6AF72EBA8D2B9AA7AB8FA8DE536C87643ABF1BC3EDA535BBA64A8A7F4BAC90ADB7D8C926DCAB1D7DCE15D356C5074BB3EBC7B17516671EC8F + 51: C8EE9E57EFA859DC5553D03402AE80B84B1E0032CE3F2CAC43F8422A80E3EF59126AE7AB4893735F9C948CD9FA8793571E4582908DA19FC723A93C7C36F79F9C + 52: 7CABE0F83E90CF9A497DCE45F14F9926DC714DEEF05A1A0603F6436E134FC7C8346A19CB92DCDE69D794B38FB22233577BA3905C94A7020841224DA888B9BE1F + 53: FDC20554A15B71BA62F896DDC4F8B354E5D2434B0AF719CCA7DC56FBC9BD280B0F80136C4336D605C7C26208649F38C1DD0004C6E0E787A91FAA6075051FFDCF + 54: 87387F89646B4068038E011D7E02C353BD5649F6DA1C4C46CD9F7D69EB3A2F6EE84DD42D25B67BB81666CE8F92A5B1A0F3EA58D4F0B5B6E59EDEC86B43BA0CA6 + 55: 6D0210417671B66D59B8F28CA0EAFDB493C30A7D7329DF29194C53887F05EDC2C3F35853898ED77394CCC650E8D350F69598E3AEF3DDF540DACCED5BBCBAF6AA + 56: F14085036C69398BC7E0CD8A9D4451A10B080E7CEDA5582ED396E5D54441125EB3EF6EDE4534E788DFE6DD3DAAA204814097987981EC8BD8E39E8E8B35AD8FAA + 57: BA67FB4D7D137531D3F4CD3D91975255FCF8EABBEB97EF0FC7C21C4E25FD034658C63881B0AEBEECD2B7D15357C14542D26EBA3ACCA944EB4C4D7E44E9899D42 + 58: 4546585669E343AD40792308AB456DF623A6A23CCBE64B26B953D6C461460BBA7A3FB444481BDB3F7FC8D5E825F2527D2DFF193356CB3171CFBB56C679AD1BB9 + 59: 210F8AD68FCD10BDB8773194FE57EFF566C7E65BCD82BE6196DECB40BF39774691AC6BA718E4B5FF0DDCF2C0510182B9A114C6F0117A0BB0E1AD585C69D38D0B + 60: 29003A048ECAC0613CFAE8EC8757F5E5CF80E9B0BBF538D7460765FE2D6B56D6251ABCFD42B56D64B56D8F219868DEB42B968E88D3F3BE3A161DCB43EA98349A + 61: A308F9E2B60D0093A7278B0645A471408F58B45B3683531179F34931D06A15F4A502F2F7E1DF8B47830F65387BB9F102646058AB456045267F2DC403A1D9A6DD + 62: AD484DDC270FE74E68620AEC882E86320D0D0753E713D9D5C9C7FEEB894DD3FD5FDF4995DDEF87B1126B36E92618331126F5852AA8C0D44404BF9F77B780595D + 63: B4BA7B2F08BC0FC901188B50493FD165F659D3226227E2E9892BD70B02312C12D195A73AED3A4009618E6E74799DB158D9AC27FCCA9BC682B09ECF53BD368C46 + 64: 0AF65ED93646AE826C79BB6E8CD193D5246BD00B0BABF8425ACE03C845B9AEE428045D5F8267F3EA86C433F1A9DBF4AD1883AF164EAFE02C07CE43079668A248 + 65: 65F899BE2C5E9879F6A3BF7B60E62591B5DC5398283229E4FADB1EE78FFBF962295C427BA0D50BBCB9E2F1DD9694BD36CA598BAE7C2EF1F4D0700DC95BB66C37 + 66: FA9ACC46F0841962D6DDCBF5D47BBEC43A0E1E9B2A8F8B7970E2E73C06612FD95044B8BEB58C71B19AF4169B7E6500500445490F80EA4E305B6BB00C7181810D + 67: E9AEA6E12F881A7AEC3AAF428BBF0DA3138EBF69C6B8E52621609AD340D6537E4A03E2B099B735FA82A3D300F782606EF58598683D4ACB0870D5130B4B3142FB + 68: 3558ADBFD411DB8436A1A8B40420EE9C274FA153AEF891290F79DE5714130A50C70EB87E8A901D540ADCFC37E40EF44592822F6ADBBE8E5CB4EC89909633DD7C + 69: AF3852A0B4E846B59A4EAEB7A7A451311B1E8F554042CEB2D253F10FCB3067F9CA927C7DA3E57BC9C99E4E7997856B35DAB0645C194AE9F1FA0A92BC218CC9BC + 70: 6BD90F0F8FFA39C2A483E8349D2A29A96AA7F3CB4B4C1325FE5162988C9DEE849B8E56BF1423B6905ED3FC6A82A067F850372414E2A4A7E5CA379AB80F1C4F23 + 71: 6433885A8A39F2E4CBB36191A038EC3E3227BDDDAEAE24FD396481332A9AD7BECCC4E9BDEA0C8A7F33180ECB1EC1DB49218D17C4325B661967ADCBA25B341649 + 72: C3235054A1FDFF2C0D218C3B54EE6A58FA5AE99040A64A90B9C8DE601B80A7C130168FE7484CE1FD9FBE22E6E794161826730B63DE794EC4ED1D653E40B27F7A + 73: 89F4DF5AC626665D9791A1E1C30D1F206D89C4B0C59916DA295931539B0A607A1261B4EF022CCDA6ECE02E99449E252EAFC8929F5074866C3FF59CC58268E2B8 + 74: 3F1AC15A90C38AA964518F176016FDC73A85B096EFD1FCDCCF38F3EC692635BD4E610F1B3314E068164D02168F73A307AD549E1E7EF07DD374F9697DB6A17447 + 75: 4FE16A3BF0534DD2E4DACC43E221179C9B61D7D50DAEDA4DA9C45CCFDC76D6FA96EB3CC1C184DD5DDF7DAAA413D05B2FE518117E2C9A880726148C7AE6052160 + 76: 1EA870E13B7E59B97045F662682F29DAEC4413566DA341468CC9F5CAB733D1897BBAD8E9520B85C43DE33B9B70880AB774EA636248CD0A1626C9CDFEC3F1835F + 77: 37AE3A9828B08A055B2E47A613D25A8D43D5A456BF741E7964C0DF4AEC6D8E5F3EF874F2B20606A38AFCBD307C104DFA5BF40BFBB3078771436276E777F645DF + 78: 48CB9B779D37299162D2674CE2C2595B2422071917C28AB48781DED5060E76EDABA56E7C538C3182F9D960DC21928E6B3069D510046608C976D7A113DE54DCEB + 79: A565459CED6C996C04A21FF0DA10A7F24B1DE22EEAD7FA7FD2CEEAF522A42E29395F771140573D684C94F61F19C771DF68FF8EA0FF727C55294C70E701C8E426 + 80: 3A0ADB5479E65BE1F00462E60C8F7F74FF5C996680A2A4CF787B5DF65BB2E82264004E396AD7EAFCF8A201E03AA950D42B9A26EF2D24FD2AD7CF57CBD08AFFAC + 81: 6FFC799781B2E9F3F573651EB2DCB0771073DA1875CCC3D2B4C6C06F43161195610617007CA9A943B1F2B001E62518EBABD4542E73CA131E20A167FA6E8CAE44 + 82: 79C9E349F1216FCB295FFFE5771EF54A024306CED9CA111DA3DC629722DF7FA5F0927152E4401E0358BDC16D9ABFA02C709B1C21F6D86905B0CF0D6EC9FD1952 + 83: 6876CC513300CC83BAFCAAE5DFE4C4A0CB962079523ED475B19568243A63B208301335BDDE10CEC90CA816960013E08271F02111BD18FD03C1B941543FF4A579 + 84: FB5392BCB60C1329D3FBEDB4DE1131E7B89326A34F34BB099A7EBEE42B985682F52412D3F0628AA72A8C2C46BA3FEA08D5765264E48DDDBB96CB598C9C0BA93C + 85: FAE655D7CC2FDB54349870B199FA54CF47BEF2AD98021FA27B968AD4C3AE477C6B2DFA9A10C75FE275D5A32C5E9FA06B03D4C908184F49FCF15ABC409106E951 + 86: 9B15DD192392017E2F4DDFCD30B7AE58546AB71EC44DB94EE66CA3419D580AA05B5F10E5D36D9E60465FB8F56665366824B5B6E9A63A13F6E83A026F5A8E0911 + 87: 1A0EC6F024130D24D9740E8037C78A176D9C5933C4073DE3C6B0536E9F7CD20E0E89705953DAC9CD44C85EA059ADC496A7A0EFC40F187DF676D2BC83F80BE983 + 88: 5E9683BD68FA16BE904FF617510AE99249ED3477276A0B410B269EB2E03A3505EDF653C725811AD9DCD7FCCF6F2411980784F4BE7407D68C02CF6ACD21FA1B52 + 89: 47CE3079037E396A5B5A1A3FFFC3C60A138AA2C6BF4FFF26D846C7E1E84E31A26270AAC5C688DA7A29DED589018BC349E3247B073B765FDBA4C8BB271CC6E233 + 90: 280FE2B5B0B72FEFA48A9B6A1B0A3529CAC9D6338E2083816930B14FEA5B21088B1009DE147D81FC7F29B00BADAB32B57E15322A6180D713411F559658FAC715 + 91: 527C2E33018CE9895C3F84BA5C072055730AAF767DC82AE236F1F7C5511FBF2CFCBE32AAEEFEADE38EED4C0895290D0EAAB38E3A5CF7B2462675D1E6B26CE814 + 92: 8C0E22F5BE099CEE31C816A0F5DCF9A548B0EAB55AE7CC127D172AA5243A5C73B5BD3AFD77C89370D51460CB7E84F1DD15774D1B8442C07AD21A3B128688E1E0 + 93: 6CF00F05A9DD7EBA5F1A755987F5678F80AAAF9B5FC44D6199100C062DB50D2DA89096389DB94A6D68BD8337640BAB60AFC8793E1A909624A4E149AECBE415C5 + 94: 8452FD4AAEB1AF4ACA8192DD59926E7B0D7B295B8FE18DF4DD21E7C7ABE8F4ADE7391753E533EDA2EFA13CBCD96948ACF26B658F1E72390BBCD7C1BDCE8FD650 + 95: C4DBE8DC875D00FFAE2AAEB3E0BF1F01529A364454D56D329FD493D327287F3E34DBDF2AD54C5BAC5E6059F5897D18157C7DC846F15F2CDA1B2F0A6EEAAE58D5 + 96: 6C88BBBAD961E9DD1418E9F8EC69FEB443176108F56FA2B0B686E93B0E5F505E56302994FB190787EBA7CED5EAB69DD24CEC39BD566D18ABE337A31414991735 + 97: 439ACC720E8CD0C4A119B9C318FBC543CB7B35FF12DA190D82A951970248BB47D0DA2171A7BF850A881E8767FBCD542039E483974F18532FDB57DF23CD18B1D3 + 98: D71EF6284984442D05E8B6B1AB636E0BA013A8D70029F9F1B9BA7927A582D5AC6899B9C8EB990CA93B49E460AE140564D40467A1368FB4A9EFFED4A467E174CD + 99: 8B5AD2DDB4F8C044AFE2B0216B7E7D830EBDD285E4D992CA022CA2F59644806D8B7599CEC51DC73786D98B7B6F7C10C3BB7D4CEE3740FA42DB21BB51A1269611 +100: 28CA7AF155E9E7E1F5EB64F211F254D624C6C42935E27A91745F2AF2EECFDCF1DBD5896F60520A527499432DD3D0F3981F0E5BA72EF113231A0319467BF5271A +101: 45B69480A77AEE3D83D39A38717EC1CAE1634D2D50D05FD78F70309DDA566DFC160FDA967EA6ADEA8BF45B74557DBCAE4D6187DE1BB82A053CF84B4217F9CCA6 +102: BF46E03CEAE3211FEAED2147B3F2909D406A767005F9C8A5CE6139133D41C2812D3225123B3BF0792288E4BB5C8B5ECE9BDFE0F8FF097DD64FB2CCB964FC9862 +103: 3CA25AE24E0D847D9552FD74E1D6FAAF91736603DEE98E51922A2923630D7CF35917916A1DB23A758E7F067F26A5DE9135871B3DE508CE4ECFEBCBBA1A958C78 +104: 2C4380BB9F29041388A0F8292D97482E1E96429B79162A19F01918DBC2DF0B36244ED9E7D015A20290877ACC4D2FFB14D236CE7FC92ED16C7C57012B0CF6DF70 +105: A0020193ADA7F57DA648C1474731F145E6A8E9E7F9550ECE1A841E2D735B18769738AEA78E7AABB8ABB51EF08A34C187478B4C5AB5BFF4932E97F4E246C60C6A +106: 60E81090C365DA5E69E2FC12256131F134F561C7A411F51F72B7649727C9D7E99795D18D1AA54D09F6B2DD7FC556512F49D582BA6006D951D474039095F3ED07 +107: B213DA3FB3ABD16B1CF5CA81574D78649382A6CFEBA5A88C0B8DD40B1C6E18520F145968C342DB13A2B4B2659F4F865E8CF50BCF2138A7B09A1FC190676E1895 +108: 6862BF8F73054DEF42EF38C4A362ECC8F13BE7E705573D8E9AC6B347EFE6A218950A5AB5ACAC3607C0C94301E0A085BFAE7DAD5E1863D469C113B790C234A947 +109: 2D7D3040A495F8C089C67FEE236A07C7D3361D35271B4DFEA5F17C7E80B888EA339B936C4475194BBE35DD9AF3BE112201AC21C9F5858E4F4C39A0FCFF0EB31C +110: 1F995515755C98C5EB95818DAF0C55B51192BD8D752FA35EBBF51176F05ADFDC32E2FA845C1821B6110F7EC1F1D1EA963433194BB978285CA4344A5F989113EF +111: 3F5855B07A4288497533924165E7EAD3D91A16F5E832FB341F5373C118D5ED7E0EF8D837FEF594C2039F08A7870EC1C2770B7C4E7185246908976B62A416DE5B +112: 1541B5A9C84B684BBDB543F77CF384473D007992F37498F07709EE68033E41829E29109E7C77E252C241C78AF41C790E40696206D58B2FDEE768E5B321362F4E +113: 6DA9AC8390F4264064947684F53A1ADB49314E0619509298CFFEA1729A944990BE2D4C0988BD6E8BD1062D574879218ED8FC4801877D637ED3B5383C069A29D9 +114: BA0A194D5078019B21910C37AFB81A890C4FECE7B1F4E722CF855A6F2F8B82E4EAD37B7B58C07ACEF1EA2B76B146811732EBE1BC0F76A146207B8213802DFB28 +115: 20631BF1D6555C7BA761B0581BBCDCA5A7B1BAACA1B3D3E5B4D70D0C9B0A279BAF00DE093AB1334ED5994FC17386D0B2BE9E0FB67AC1038704891769AE530BB6 +116: F31F66E176DF632694A6F7E16ED8F15CE88908EF1D1F0067CC8A5C805370B9CACE0BDC78B1CEF06630012B3A35D129C4E2AA4F7302E1A122C7E53C51DA7F795D +117: 18B5417DC4CEE4387338C63156C34BBAFF19A2BB962E4248B1A1AFF1FF145BA47D84C6C8570D072BBC57D912C8048E0ED50060CA33408A00722A65C194178387 +118: 2AE09DC52D7BB9E692822A6FB3D582B805E5ECD2C1C4813F94F555BA2210429B615A2301B3EB7C491153D68AE33AD9D28F2FC11B6C61700D79BC7DDB251BD15F +119: 534390ED2DA55D45402F828D6035819C4528768DBFFAE1039CF0D18F89BEAA867589F78871FBC746E43B59E7886FDF734364DEC4193AABF56E8BEDD801E60D89 +120: 231597B2B71E6BE567C86DFE31ADD7B31332BEDA930C4921C4817B7DEBB0282A12D23B076F4783EA840D890F6C571760E70E143F8565561062877D95BD0FF941 +121: D60A1481686AB8F889EACF2E9F66BC32271E70E3E04B91ACA6CFB90375860E0BFC5AD9A627BA0C763CD7576811CDE2921E9A63C0F0A7A26E763F7EC7902308E7 +122: BA65BE7D1EF697281736B3AFA97FF675CD776C125CB01028EC2894EC2EFB9908835A3882E5E57BD44ACA09DC3B0580145EB2265E1724DA6F01AF5F93022D5774 +123: 0DEE2EBEBAA770891C14346A26834CF40212531EDDD64A21EF9FBD62F4728A16E18C673DC8CE3883156F51854A0ACC341DDEE6A0B71C4CBF797CD5327056AAD9 +124: 0717C9EDCC2FAEE525A684EAAB79653DD83BF46ECB285E6B154DFCB8A0C9F8D4B28FA200A6C224B4620CB0AB5B33B9C8BE77B2B5A04DB1A3EF8A5951EC46607C +125: BADCAAE4F76006290B9090AC81B807E7251EAC041E6CB10A2C5B58C4F4B2386E065E6D55C46CD888396C86606FACC82DE2F3F88904E15D549101AC7FFBA057D3 +126: 751F6366EFC97218AC2E0675E7F375444C8D82AE7A139E78305E14148E07100F5B7EF93B576DCE546A7BAFCE24FE148B248BE072031F89B6AE7BA9CC559E9C9B +127: EC0FCB3E124C482CC8D86BA2CDDE931E521F0B6F3E7F333C4388E7448A7F196D95766CEB8A49A90E46B592958BB85BD7495747E71508877975EB1454A4EBD57E +128: CDEEE6EC4D67DD8698B72C13735657EE9F78BB0E1DD37D0CF06063717DA9DCD617C5F4FF7656AA48CB3F697E36B3904F496136A2B04E19726DEF9D3406F8A84A +129: 81BB692EAF7F5176B6A0E5F2DFC01A045A917649D0B23B22C180BD78672F37F8E562FD006A00AF2D7AF0AFE15C8D191339AE28FF2797E64A3809400E2E73A785 +130: 04A8456D131499586CF7B9FC45C2EC96859F3F4BB8240ECD93E439EFD5DDE1DE7B67B688B583598D7FD50CB179D318D4C05EDE04F6FA318AA1E9DD7D4E279307 +131: E5C9D55B686DD9D7B1819A6144F6272B1FB5BB3B3034AB9D1BF34391283BA614D57894925C3D589A7FAC0CA1B1E98A12E9DFDDC2BCD85D1E7F2980709EF25719 +132: 2C6EF2E1C179BFA8295197371C474081790A63AFAA194E459CDC27AD4453B3A8C0110F9229BBDD4BBA5D6E80F2CEA71059334A97EA34F96810A2EBFCC3B177B8 +133: AAD54FE02E67080851DC84E20F7661E42ADB610D0B105B3EA6EB6654DAF64458B7E0F756392196AE2B40626CC2B0D82E47D74D3C50A607F4402C6C6A62999324 +134: CF210EE9A800943EAAF4EFE15DB7DEB696233A4DD62206D46BD9C84A7EB13B5EA43FF3CE15ADD8FC4BCFF022196197D1D097B7A893A79C6640135929FCEF10F6 +135: C81761EBF3235F4D56697B19F62B4F7445C8FDCE3D7999F3249493D50C19CA57C5FC84CD35CF794F58DDB6AC86E8BD53350BA9676AB63B88214162C8E11C16AF +136: 8E56EB131EFA286A92078F5A3667BC6669D6A7FD9746CA5F208EE38D5265CF27076C1624ED0F98D486C55C28A4FB89C7B667AAC505CA1CFE1E841184615B7602 +137: B6CAF44F87688E9E3651C2C98E840264464DE9DFE1F3E4CE5C1BEAD46C7D9D747DFFE282D775E101591A7254112C2DFD543E44B41E72EFEE30B032E5E015150A +138: 8E7851F56585595ABD2B3EBA5AE713672093A3120798506ADD1ACAA3ADD92D737F9AE155B8A5166C0F047801A93731D4B807DFE15F08D67DEF31A7B808601D6E +139: B36B6689A5F391688DA3A0756A15AF15E6E66701E2132CF6F06326AE9C91A0BBAA35664B28BC5B936D2BF1E6653848C5DB57654685124A08C79FD03ACC0681D1 +140: 24A23CE3A90C8EC3D10330EBDA47763B1B03035F9E4AAE0AD336169A2F464E067B026D94ED4B9723E969C8AAE7F404F7B4481C48EF7545EAAE4E648525A68751 +141: C7ADE61F21133886EE0E0B14438F070DA398B3A5387CABF98B0802662F3BD3AAA8738D36CCC0D3EA25BBE9DD3B59062BDF4BE2740482BF6D4C21D0E0FD7B0679 +142: 17EEAD5930DB3A1F8E123AD2E72C38209824F977674A52F380843442F0A5C82B55F8A362527BF5324124401648BEF5E9E26E08050B1FE80886E3856F98AC1EF8 +143: 9DE4F43CA8F7E528FFF9F4EF5897652323AEB95DF80049AFBA189C3D142CFF55AE340358A71B01797A8B72F478276E6353421E1C0C22EBDEA0C044EA60865784 +144: E259BE34C467B471C94B612EA6BD99A3F7EDE58E237DABA6A6656F7F7EB5466DAF908B7759027C277BD9234ECBB23C5C62DD2C9D248C1AE52865D66B5C256756 +145: E49099FC970994F8293E71467BFB1D241FE99322075795FCACFDBFAB396392E37BA09E66BF492684642FF2A03F8CF92E0ACF4677C21AC1C236DDCA103F0B5A69 +146: 4338E438D419D8694FC40383EB1045FD9DFEBC6F18A9A03B4914687A8639322E3B050F48E872BB7E2AD9013D374D68BDBBDD0B177024C1185320D04598515ADF +147: A36238A5C795B23F42D0833A5152770A4B0094BC19DFA72C935D32D02FAF5D136BF55D92B022D01949FF04B78507FB203302833AA7103729771A112E4FD1584F +148: 47180F9E838B129A7732A8DAD763B8CC5437BAEF77EFD34D3B33C63C09F6314B87B3A1436C6866614C3B3A693BC7926E9AE876C7BDE9D712FB5198D6417FCEF6 +149: A87064FF5DA177F3651488A139E568F6C75722ECF97507316BDAC36393724525291682776843B8563A6B014646F6B19F040B17B62BEE4A0711A7B06A67DF75C3 +150: F358321DC6A376ED500A2DABA60096B817D13B59AA02B56C1F51E2C6804F5D2DE2028409964D5755BFC6424287504994C7605749A5E5D9D802BB42922F444D76 +151: AC4A9999133546B8452047EE31B398F623E01DCACED7BAE4CB0B4DF0DD53B8E4921109308DE53C0924E0006361BC8A480AACF798D6B403F338357E8DB676AFBA +152: 0E73ABBEB68982F163257C1145FA2E465FD6E720EEAF5E532DDD1ACCC690B37A8FAEFF8D7D41564A9C86C2F185E0FBD0FCE75259D34A5E96B8C514EC83CA1382 +153: 094503A1B90D71960F83C91D76754BA6B05D670EC6A8EEE1D3CDC652DA6E52B196E155F3BCB62A9E4EF8C507F377AC1321C4C0D7A03F7D8A5286C0019C358E92 +154: 12803349F15FCBD53F2FE11B67DABCF3F470B8E3AFE8A855D7A918E611A2D5F4DAE8FE847ED1FAF834BB3678C6253111636100A991A80C1EAD0D35E28DB3AC85 +155: F489665F4D8A4AAA679D5E5A1B7C501DECE2E0B228630AEEAA1F5643FC4BCCB9E2F018FC2D7C44ABC4AC0861EBA8B7700A49B42486DD13263D978F8A7C9CA306 +156: D9DFBC3DBF0E3D247C95E16D376E7098A92EC59A54FAB482C330139EC6E06ED514D5C74F9604D1171A127502811A16D1D3039BD03C4DBED20BB765EFD34C5F0F +157: BA56A64D01FCF392A6E2F73D791D6C5A57AB40A376E73388CECBFDB910402043B4DB2F2D2B86E3510986CF1DEC3880E3C739175D5C0AA1DCEA18959135E2CF48 +158: F4B07B0A063AB240E5A64F1C494FCD9839276FD9689AA6720A94B83E579EF1044997F6506C1AD82C2CABB9384CEEA0B77D3970C1B7E13F8DE98AFA869F1F4D2A +159: CB4F232024B2D0C48E415D73193CD83C1A6BB9806CA336AC4F3B8FF7BF992B200504ED5E539CAAE68B1E47D4D8ACFD2E6B4BBC1B518689BBB5BB4311C96FE06A +160: 1E67E36D2EC5D0591C0171E7426A88919EA5A17470DA305CBA7BAEE90002E23043FAE1F4BE003EDDC2520A404E639B03880E3CCC68243C60E243A0E7A02E2CA0 +161: 40E46A8F257265A1E57A09B43890FEEFA57F56BB47551BAB38BE2BA8D143C176749484ADEB2D833EC9D6B70FBE872FA53618E64CF0AED24D51BA982D29E730C8 +162: F399712E5EFBA3FDF6B7D04600C16F69260179AB79545F44EF5849308E6FA589721CF7E6FE384461D05EF02BE51E50FA93C5FEEE9279A953C57EC07CFBE53E1D +163: 58DEEE13BF73ADD8B49EBBA90A8EDCE7030C17D6E6C449726D094F90A35A07759A3BEA031EEAF963C4753522EBBED1482789833D15D6EED7F5214E1AB93C174B +164: 13B2F766E6B796C44429A747CB46D99A9866115C78D2E94DAB52BBC9269B6584D26676CFECC2A9F026AE8E0162B6BB8DCB2242659EDA67CF793BF66963C69021 +165: 992B995865F57633665483C7C3ACD34BD108B5DDF151CED97C0D7AD134A8D9250CA8DC17C5C2A76C1C07989228F8B474814FB116C98D25D8F291D10CE259570E +166: 1C5D5E9C29DD91877E279DB679ACF0EFD8464B0A58EC9A3036EDB2621E8106FCF2A81719FDD1B89F13FCBD20960387754DD0F12876DAA911E793DF8F1991C043 +167: FE7F98A1D7839BB417CFF65A45E2DE806C74ADF2636385FEB16A34C890B524A75452EC096849EF0F905FFB38A0319D31A886DD840FE2FA66E16AC7C68B0D7FCC +168: EC67530458F01366BE95049FCFBF65465CEC9AD7D12332CF898DD72ED4D275F9C9EE96AD02603E8032F9B3B12615329CF0FEA564D278B1DC3B47EF304BF901B7 +169: 77BB3F5E58AF174DED0B31627648A1C7B5B8092C829020A6FE4CFD42CB51143E9DE20E3D827FB070DEDDA94D39BD0D330604DCB190E7252B12B03F48072B7E27 +170: CF33E5358E518807B70D6DCFBFB1CBAFBA7B2BDD20931B2A3B08BF8C6755367AB3BBB2FDCAE305F04812460FAD37E9AF70F1905D2F0D3E7628DD1FA453E5AE63 +171: 0739D32112107994BF3E6EC3A107AE3BDB9E2BBDA1D7C10D9AD6AE32952649007F68D28BA0DDD1F1C45F7128C1D3C42EBFDB1975A143A42949C7D97D9F9D3BA1 +172: A4F0B775988038E50429428C8526793AD8B6EC1F0F3AB7F6B33F716C61B7DFC49E254EAA01FFA422A31D30A8268E1BE99D385907479C7E2E0492681B6851DE1B +173: D2472E93989E1F29BE0DCF991A65BFE0E772CE77850A2F96FC6114EBCD78252DFC17712AF193FC5ECBA371B8FD27B0DAC44AFF6140923885F403904F1664AAD4 +174: 6696E09A153B0077D3586705E4A19FA6B3B2DD8621F5D13D7003017A0C569B7483C8CD9218ED1A252EB160C3620FE96A00E267DA0FA8996B417F64DD4A22153B +175: 2337E38B460CDDB026CB81B59B99572D45BCA4A43949440AA5C9F2502DBD8906453FEE23AC0AE47AB77214E52E7CF06ACE73DD8565BDD315F49A460996E08DE9 +176: 068CAEDFA329C1FB00BA02C80877E0E2B1CB6127FA2224BD14FAE5AD0AAE6FBAE052A145F5A8340B446F54AC9BB2108CF6582AFA0FADE91CD3568B604F68F470 +177: EBD69C96F4F2DB05350B74A475CA8C1FDC671B018A47072A11A8DC082C418EB20466720AF12E113C2D507F02596CB022D2BECC4EF8486CB54260020EB6C36481 +178: DB0770922005DE66FBC2B05B1F863ADA569B76DA9B8CA433C99C2F2B4AD60BD28B19A5B3820C0D8B6B2E443CF54A942B961E5EF1D53BAC4CA379964D701070D3 +179: D435D7240B8C6A6AABCB026EA53BB8DE58C5DB471EDD8173AE30C81BEFA9CCDE8E30758CBD7DED822410576115C2415D9DA7FD8A83CBEAE337E5908A012AE1E7 +180: 838AFEF97BBCFF7692C731D55442140D58CABFBE81BE76D41652106E215AF4E934691DC20F181C2123CF091B6D7552115F59937E165F1645CE0E14DEDB864B11 +181: 771815708A3D7BBE5E00FD677E4EB76B2B9A03A09412284A236401E7FCB19B340782C81D1A49371609DDCD7E38F9448FA657533D53280B3D6B492984E9C9CBC3 +182: 649EAB3244AEDAA18CF0A1FFF6619D63BBB66955C5D58E3A592E53F537FA74C60616B9E4483BCBB08AD7D1F5B6B91ED3176E89C03C224F94E5D3893FB6D01CFB +183: B4B6C653D90EDFEC3BEA0FE1FD766D5736DAFA184C360C8B036B7CC842E8C76BECFBAA7046AF087831E322FFC181073C19360A269851FF4DFFB4712E68560C3A +184: B0C0061EC50BBC67DA4765FEBD4033B8A204260177F9CFD451E97B93F19736D4B0B7478E29FBE76BE17AA6B0DFE9C4CB9C6E4734DCC8AA5EA825F101E5C9B02C +185: 54EB4D2C9B26B8B17818AD702E065407A19A711E22C8E66163E7311D8ECFA54448453890194C3EE892A599125AAFE1CB230C6EA268ED68ACD86DBBD17432352C +186: C049743F49D57D9226AFD26B94BFE9165BE5A8CEA9DCCD101F837F29C63A4201B1D4478EB5C4CE9D8F5D6E91BF89D09E6A0D918EE7A6D58CCD0A46D36963BCAB +187: F11AED8EC2B1C003B8E35F8F2A05861D9DD6B7DED02E28EFA4EDBB0BDA0DAA76EAD810CF1C78F50668D50DBE2AE65009C2E12504DFCE9F9BFA9A14969E1D0622 +188: 1CEB4106BC700F76F4825E6790959CC6EC85AD93D6FBB9783098E367E5C9676AA0D6B8CF9A7DCC67565284E71205551650557D556870B421273772524463245B +189: 9711275100A787D9678CEB38981A2246112C2FB1F0EEC1F844DF1703DE5B0FAD995FAC983526E7E3336B8CDC9DCE56FD66B73811201A2DA6783309AB6B9C0546 +190: 81E9DC0CBF71797104A44E72841FAF7F9CCF35C18EFEEF873450A25AE56564B0E9DA98598C527D5629EEF7F0571D9AD929BAB87A27539CE9898ABF4C57C9EBB5 +191: 28F4214D1C8C5B9291F2E1F7FCE732C3290A691432A65A01F7EAB1A313B83936DC98A3B39B5F7712DDEEB8968001C93A102C7FCFB8AD7D49B29661C9A9867109 +192: 78C7A025ADB85145CA8C6E417C4E68A9DB83FA78A23D0CC3DF20AD1409B936686FF756EB51BD8901157B1D031DE6848D97DC2E0F137BCA1D49EE3FB2D5A5E83F +193: E2C25FC61AFC794F65AA57DCCC4111D4B15331842493F93E9500AF01E2017CB226444E208BA9C841DF6D7ED28955B318511335F842AF3C2C0573227AFD790739 +194: 50D768C744CDD318B950986E305BF74B77396FDABCAF63AB786893B5F4104C2525F2F69905955A35234BD6BD85DB17B94AE7008F2E2C368E9639ABE8BAFEE4CA +195: C4F1BF6C56C494351A880172B9CBB59BB0D1A5955352E10A868D3C33BFEA0484EDF6ADDD009A20C8D7B59B7ABD5115D595B026CCA6442921038D9BE860C44CBE +196: C782CE6A141EF9E6CAA61853588B8C75B3A39CE191C161F43D7C5F88FB77BD5055B21F37D4A49D65CCDBD0E6BFD98193FC0092A34C21D5ED0CAA5F129D462073 +197: 1B2F68D7DC7563C286612B3D708AA725923FC9A2FEDCD4B1F1E2557CC70F3BF65944A2BAD9705303207B00F6DBCCE245C6E653C38EA0896DEF4150DA118A699E +198: C1248D0A6B75BEFFFD70EF17F2D0F3CE3628BCFB6A634C93E8F0ED97BBFDB48F6E5608511AD7091D7B062B795EBEDEC67696679EA092F7B84A64C99BB224D387 +199: 20A3D3F3676947173C7FB824B40069A202ED3A5637DB41C97ABFE9E7036D6C009BDDD5BFFF97FE80EBC40355A535D7D3A4B2FDC09B809D3BAE2DC31803413B27 +200: B85500CB777B14592A4562A26B13AF3F08CE74E03372D9622E29C1FB7988A86B8C00DDB2049C1395B43B17CD5C415A5AEDD71E05CC0980EB9520D4CAABBD6FDC +201: DB553A36A3EAABF7BE6FAF85DB96D3D0F207EA1E5B55DE589A116DB80C21AE5B1826A5FF3BB9D84C26A403A1E5C00BC7D2F6DE3F6A9661899D6D75373ED76B71 +202: 5580422E6393475B7C1F5010FA7F4395B969E190AEA056ECC88783A8B5FAB8ACF130DFF39DC0175E9BA8B63B4FABA7E4A36FC55FA1504468727086B2D26B5818 +203: 1CA3DD194E7BCA2591AD1B95D0CD4CF7938334C95A1EBE2C8C1A9B75E6A85F534C094E652248048923CBAB97CB1581E9A2D1AB8375C506159B724F74447A3201 +204: DC525D0EC1E62EA68C013470D77B61377398EDCA82A91C1C3E4D7E5D910A9D556B3AC810FB1457BDD70A18B063523C39BD806A2227C7E057CC6B018DDABFF73E +205: 2F0B9523725B27245D2A1B635DB5A3A3800099546ABFDD95C8E86C67C378D91E4711AD1927E90CC9B50A1A7BE3D60414E487E72445936FD0FA2BBF541F1394EC +206: AB6EB21BC802EB0854F61346F7BFCFFF738EA39829AB2785976D869830DBAC367D59D50C3873B960AC5185F3DBCEABD4E4E594C5C2916A8DC304207E887473C5 +207: 8E1C160A334D41F08918EC084BE12872DE79D00473D1B6ACADABD67E2A6827FB1DDDACAD9BFCF27430AA84F3F7A0D6CF2FFC91E7758F471F2739D51B60125D46 +208: C135532CFE84849FE9F40799E1F2CA05568868C0D44E6832A05C29ED17C5F6D0FB844485CBAE5E50A67F2319C30526DB444F4B45CDAE01A9D0542427731DC175 +209: B1FBEE68843D42FB558D1D9E0B759C168D6F84D07B2E90B646F45F1708B0D6AFF7BA8959EBB6AE4D5DF9A9951D139C81BBE602671CFDC618AA1EB63288DAD72D +210: DC11C3D993F59473F64F16F87D5F085E834306FC1C40D12CE7D6E44C59C31318C694282B0FE53B4B60E1E5DB546D930AB741A8DAAB8ED67C3D87E8E76B8C025C +211: 85BFAE07EEA80F939D52CB18C970C8ED9D4035B57391739C44D7973223C51344B9BE28C16EA29B35AF74A2F8F7581C766D61525DE5922A83A1BB600D97F7A3F2 +212: 26E52AFEE0F11DD79061EA3E4F97205729E6B61E50B69CC2894CABB08CFD3A10C41662CA6F6FEC9B5B80ACACBF968C5B75BB8CFA31D06C82D9CFE97F6E1F43FD +213: 74F18E92D85D9AE79BD62C4B8FFB2116DA8157E17A6927BE2B2D0D79CA101F7CAD6A25CD623C8756D49B9CBB903477B9CAC67734F84F0915ACA9025A9D5C6DD2 +214: A51B45BC09382F85334EA58CF7E7747457B517118042D53D773C66668CD6D5059B9997DB183B1C0F2900AC9949028D8F76DD8B7259149388FBF340834A3BF4FA +215: 59DC88A518FE44A7FD0F316BC8B5C865D370A8BC82533037C9872B24390F7969ECA530911463520218D00B415409AFA90A63F88EE729A252F1B747C414414091 +216: 146FBF362ACCEB8DF79A761285A0653484C38585817E26A7B8906FBBEAD70031160C7B924D3BD3A9ACE28A5712ED0E6E89CE4E71493B27F87BF73BF592D80600 +217: 74B6738B2F0904FD59F3A680CFBFE4E466FB5094037AA1942DB3A0017260D75AC5916E044CAC6BD0E25D176FDA267542B2C7EA201F7237E18B9D00723E98A239 +218: E821A4033FAF0FEFE525115109D0B836A22C287E3B157EC302768BEF7989AACE853218E5AF7DEE9F6E234AD50ABCC8A9658A0EE4D9FE050235341C94308D7A4D +219: C3EDD652D2F831B1C783CE1B8BB8CEF9453FC71F519A4800EC2362ECDBE9EC142F768185D55E322A32AF421DC84EF84615F7F3DBE6BC6E702B4BC8625CEB5BF3 +220: 6A3CA0B5A43EF42A1D6526C2F1507785248374C7D2602079A923C841F775A652724C29E788695B52387778CF2E2BBE2213B2FE212D729E3718D946238FF0E57E +221: C425148335AF813E36D072DC64C7EF6782D7DB981C5142B5D32D6D4338E06AC64363E86E88DF018968FD659DBF50A4B77BE2A02E71B243D65024B36CD71C1796 +222: B796D1F5AB11389EC7EC8DD4D1D5AAF17262C8522A4AACF454B44A7ED71E20F7028169F3164AABEE4C716B38271D72D7ACA3E54B30B9E05616AC51594995F61D +223: 113A56E96ED6F8613705B5CCA6CC4F2138204D7BC0C8965162597C1FD2F6E8143F57FF1160F4B482F7430536A349D20918064AAD2BB38A9D4403C16977B9616D +224: 9590A3BD7A0613381159E1E26342C150DD9B0A937855BF78FBF625648448B540158196A2855E7FCB967F22F5AE927D60E97D0C1C17A01E8D07284FF985F54B8A +225: 74B11968CC7CD925E21037DF011F1C93B2EC34C34A3224AA281ACE7D6F1B10F2A755DD6DDF33F1A4630123BC1CF875894FBD8D8B70AC05F8C3C1076E346A45B6 +226: 85A08D6993B7E5C014C3CA957D6B53EC1B8A5CEADD5060BBCC350915D3278F28E238425DA3A95AEF725A23B1BBD43E5D8832382BF76603F7E2E4FF711D540980 +227: BEFB08F621281473943AF153124256386570261916E5238FAFE44A72801D7C204A974B38696C102748CD1DF65BE3EA8C45A40021C28C7E4BB143800A3F38A93F +228: AFB97494318F31A4C6813246D125217242247D4EB6CF884B244E59655DF866B2820A8E1A7123DCCDE98ECBDF1F6125EC5B95A0D9F85F05CB09537B3FCFC2CF3D +229: E8C2E1D342E6503D77328A2C1336F95939B0E8855F75CFC61D4B03F4AF2305AB57C7DB383055A51E61AFB75494C222B01967BC74B4574B8208FC337E09E57075 +230: 0B396D0F15F49E60994DF4FB1E7E526A272A5B41FAB67EB8A41547CA6CE5B7F3FCE404B6A46BE79AAE37B4DF2C2EF68EAB71F39D5908760FB2124C7C83B0AAFA +231: FE86580438E8EE3459A62E73AF0E14F00F4F0FAD0447921FAEB2B77A0D8786784659B1F6D3044538300C759EBEF7066F9218F9386FF6C8099E6C71B5EC6B721B +232: C7E45B1737EBCA62C87A8F0C46F661BF7D3FC020C3B4B91988FC36C38BBC8DE05A22D4BF148F96D31115605D7B04D4CC8AB3F8738B652E933D76CD6966604CAE +233: 2C43F84381FB618512EDA0278FD382AABBA41FCF5546312DA565F4503CACB86B8A704B3B49C0C86B2207E4641F71FB5E72654B0AEE705C52ECB2E8FAF109FDF0 +234: ABC4EED8635DDFFD9900F5DF8C6246CAF12D8CD9333F38647255DCC52A20B6DE8D4109957CBCC2F48F52346579E008091628FD7CAFA092F2568828F424EABF26 +235: 14672F19BEEF8896F751B0BCF40FEED78A8093AA4DCB590D7AA588DDEB3170460381FDEF3CFB608D55F9E8A295A36DD64DE058C9EFF30B1D1F1A3671388B0AB8 +236: DB87424F975B03F925D8B99A1DD0967D2283E408B6B0155851DCFD53C0C00B05A42CFE14B10408E0F5985809813D35D7AA7C70C1A7BC852C7F254F0303103628 +237: 095D34066A6E202C896EF29F3481EFACBBFA622676F58E90FCD5A0591124E489BE3804AFA9BD3E4C92A9653EBE878A88B275BF9B5C8EF8EA0F01C89CF40E5FE0 +238: BB5BC80C718B85BB3C3DCE95D186711D5B90827B2097DE63C647E5B6C14B4766BF8EE8ED395103030F72ADF0C8992AE836086571908DB4A6258616EDB4BDA878 +239: 9A18D6DD0F97B7407DB0F17896DB2A2751B76C69B6F91E821A0DD717DFDEF630EEC1427C2D190C095DDB07601DC0EC8687B7411D735A9A6EF0EEB84A60948BAC +240: 60A614BC40A7DE580B6ADD05279A68DDCAE79EC3DDDD2C6FFF7B77BE9DD0260DA5241660982B77BA9C4B904075F39612F514BC86DF6F68E189FAE2C84A32CCE7 +241: 5CFCD44DECBE3D74708C620C70DA807C5AD58072F7558D950F519691FC96F98B760B02897C3A85F68EE37B2735931660106670C4DC7FA98EE2E18B6DED532A9F +242: AFBE6D9871AFFE6D201E2E61435703856424301ADD5152DC745D96D1BAA3ADD4C78F2D7C5057F1AE8B21FB91879562050C84144A2042AB2CD273025FA03839F5 +243: CE9C1B19D0E0FFD3085D28C5B2176A741A3034C1B76C54740AAC3470C1C8C6E77BA765AC4D6D90D4DAB0A89AFB17A8863A2917674F5A189A5CBF721C14F5D637 +244: F2F065927839C22DF56960845E27868BA8F272A464619EFFD9AEBAF1E40A72DDA81CFC67DEE13C351736C407F59DAE8EE6F2BDA17521CF66F10C73566B7DA891 +245: 24CD3AFA2218863437C5518021D1B96E0A80EBD14EBF2FA161A5E7032FD985BF71EA59DC5E35DEDE5EEE3098EAF6A16698F5BD5903C4ED218868D1E96E4B8096 +246: 1C6AC311730640FE427C1F23B60E817C25E1318109643A8AB51DA74995FFC3F156F098AEF97F37CD9746002DAD22FBED1A1F222511B92AB5F39DA9B53BD62AF2 +247: 37609371EB63AEF0CA6EACED8388D187203A88C379F24970434D87950C9B7DF9A68B618E9E83E3EB10376504F8FEE2505830EFE3FFBD23EFBE081325AA171482 +248: F0C06F6A2C7AC3F0EE428D7D1BA893E73D4D2F417999043BEFBB3CED51F95F7EA3CA882B9E8C1C973DD8A7F450CD60BB5A0B30D44A574E43E71D2533EFAEC6B5 +249: 3A9D1BD43CB3B7D3E9364F05987DF4CD99D573C036BF1337988751658EAF2896244DF5E4DD8984DD494709E587A75EA8AFF93681787AD738A95C5E98616115F6 +250: D42E2D57B36095F0CFE8F771A9B198C7B7E0433763341D35033F32D21C638CD948D8DBE75F533391347C440F208D17F20614309DBF1091DCA10801E16F5D03B5 +251: FBB964B7865A889433E99C4B61D3CD069DEB99E44673068771030EB1B8F1FD3B3ECAED1DCE8ADFA44F9A625472CD4D987EC7ED7FDA0DA912C8AFF5B20BED7F04 +252: 13F67CAD96C3304FF3C2E45D71A2D69301695516EA384F6001850A46A7F93CB74C5A4CBC1C56544166ABB6C9BBF90B9559320F5F75ABBBDE34C7B8B45C783BC1 +253: 78A609196BB40EEEBEBC04A8794C840A6F831680864D65FAAB093A499A3CF152EAC96865747ACA28392E9F102962C49247E0EDA424A345C4AC6F4B60CC3D2597 +254: F199515CF806EA25237EB93D658BEDC994E61EF70F5665CC2F230E7A40EADA14BFA00D56C1249F2E5C8920977A6C85017F8663BE9422762CF88487B76EE7EF9B +255: E8702ADD4B9034BCA0590FF897C10022C56D08FC4EEE0A43BA85E9E9C2086616B1BE7B6F928A3C53755506ED2D9D62DF5BA4A1862FBCDBA20683931A2244AFBE +256: 6E6A3CDE12F2CB3A42EC8A5D21B435C4DA4DF6CA7E41537D361D8169158287BF1D2241581DE07F88FE92F5AE4E96EB9C489FC3B258EA3842EA2D511CE883883E + +HMAC-rmd128 + 0: E9BF401EB338AE9ECE9F2DE9CC104A5C + 1: 9536B19B029E60F979B3A6B3052685BE + 2: B52F90B48846959EF56051CB6ED21588 + 3: 0811D2108413D9B64ADFA78B05EDF1C8 + 4: E06414189CCE13B61A2FC3CE9BC11938 + 5: 8BA02647A4914BF4248F6C799055ABA8 + 6: A3D5D44CBE30E23D20643E865F28B7CF + 7: 459DC8A812BBB840CA10A49E10F240E8 + 8: 26131CE4DEA7D66E5B3E6ECB1DDA4329 + 9: 5EB41B6A8F140E49BB4EBCB76EFAA0A4 + 10: C5E076890071C872B071E2D068EAD1E3 + 11: 476474365DEBAFE39DE7830A0BC3ADCE + 12: 3E9E0D4B41D740310572562E5F7F0CFF + 13: 9BA99B782F7B79C9C19D40EB27033941 + 14: 8E9931A75435B113C7E17E94E22D0B7C + 15: 1977BEFFFBF378633AD22D9E489FFB90 + 16: 9CA06536713225F3A5F67CB6510FB165 + 17: F46F54B012982621E33BA13A871F82F8 + 18: 73F925BD50E603A66B17D8D926CAD1FF + 19: AC74EC692DDBEF86570044E1B5F31EF2 + 20: 4F4F95BC7487A8F07B23C11F700F9C4A + 21: 02CE78131B27AB77474CFAE5EEA37055 + 22: 1D66BAD41487BA6C238BDAFC04E9963F + 23: 79058EE7D70C9D19058BE2E1D5383F39 + 24: 773EB9C677055286C84B39D2344C43FE + 25: 414A4816C124BB62DBA3BF65B6276208 + 26: 350DE5DF46801BAF8B12D4516E82EF43 + 27: F31C58CD73A3D8AC050BFFA5FDB6200C + 28: 5D7489AAD6537DB3DC27D43F698F6E79 + 29: EEF7FC37DCF2AB96328E62B8097203B6 + 30: 8FD428368B9B52F25C47E74C0327DA52 + 31: 923B6ECABD0337E39E6D068CC98F71A8 + 32: ECF2239FC767105FC69F46FDA5BA37CB + 33: EAEEFEDEC3B1E74A029683FC21F03B40 + 34: 9620C4913123F3A718D61C956673FB23 + 35: 59283EDEA3804ECD6471EA41EAF89A8E + 36: FB5B60685DC1DAF0C6557325DBBB32C4 + 37: DB71D12AA3B97C421FCBE45F8232F3E7 + 38: B0849EE5F1F9484514F5512BD928148C + 39: C73A777E20CC49AD33DBCBB16DC59A84 + 40: 600BF6FB779EA2F7108D1F7B8FE89F45 + 41: 0BD76F07D4C433E5BB9FC98B7FE49A2C + 42: 209E2124DAAAB3B5C6D2DD9A79A36E4F + 43: 907E4E2540A6794D6526A44FA08CAAC3 + 44: BA1BCEBA60F32ABD0EED0A1A56748248 + 45: 31F8527CCDD022CB9439F8B39ED70D11 + 46: 05F429D6AA9FBB1723D81AB268F95963 + 47: 7B91D5409357FF13F9B92ED2C6D63B66 + 48: 30AA88DDC6D49AEF0D4058616EEFD9D9 + 49: 16C0B4F46936AD501EEB5BEC8C699EB3 + 50: 782DDC3AA9B3E498767AA310D7C32CDB + 51: FABED92C454544588965E4CBBBDCDAC5 + 52: 7B04EC847F160BE26FB4A7C6B111EF91 + 53: C20AC6220BD352F8D53F0DEDBCA97862 + 54: 2EB8A89C854AD2412E5E2DB8638550C1 + 55: 390DC3D1C6EA4CD7A381BDD9F0B505A5 + 56: 1D86B9AAE5246182EF76456E9A8F2CC3 + 57: 1759BE8033CD082D771127CC81435696 + 58: 4F230D4174BBB11231ABD4AB58D6FB80 + 59: 9FA21699DE8CDE39FE4C9DF25271A87C + 60: 7658883C002D62D33EA21AC43E26C355 + 61: ED1CD4C63C40453677804FD66BE3E068 + 62: D715E8E09CF4C5A34793FCFF0A7EF0F9 + 63: 86C450794C4F920138A8CF2DD9221826 + 64: 2AE1A808F63CF7AFF39FE9595BE540EC + 65: C8E550F520B0662100FF767FC0FC38E4 + 66: 1A4CA5249BA8BF8E4AF50BD01B89C13C + 67: 25A3566CEE5E0921857048F4A54BF745 + 68: 4D76448CE2C08EBCF6C21FD304973DB1 + 69: 83BBC6D82633974D76A1B0994DD8891E + 70: 9F322885EB927B8C4F93AAC081C7F378 + 71: 7E0DFB22C9433A0A66A673ABB3E81B4A + 72: FD3DE62829CCF2AC389581D9932E1B94 + 73: CADF66BDE69903E9E3117DFE75EB1C6C + 74: 71DD9BF191A5A1A0311BA19BF0568727 + 75: EEC05781AEED255A8DA730399ABE8929 + 76: 07E7E6E57A239F659A6B17B695161878 + 77: 6E7DC67642EB72C295EC12C009902577 + 78: F6AD3BF571AEC27B2C99AAD4A22B9654 + 79: 0F38A5596BC9BFA1ABB7318A35E5841A + 80: 987BA29276694A84DF6F3448D2FA36B1 + 81: 3661D8F157DCBA761D1292FC2FB332C5 + 82: 81834820599DE6624EC116A651FFA2A4 + 83: 59E556C023829D31F76ECB5D2D5050FC + 84: 9389597634228E243808C1CCCC71627D + 85: FFD30A17850DB17BBDE7C3EBC8482A95 + 86: 0297895965B8C96F95A77E6A1BEB5FA5 + 87: 46185FBA371A282AD8251A8DA93E7A10 + 88: 34940377228A73C2CDA178635B8A4827 + 89: 0737C31BEFDE68780EB3A5504F295809 + 90: 3DEE2B38EAF96BC620785551C926E9AF + 91: 719B32410E625DC65AB4E422E24C8663 + 92: 5B9AEA802EFFE00D19E746E0684993CC + 93: EE96F9B8F8FFC084C0EF8C28ED0EEC4C + 94: C6575E5F4CDEE50C0C2F41ECC33BC9E0 + 95: 000DCE0FA82C1422ABF37EF1971B4B1F + 96: 83D1C6EBEF52D1B9DFA3F439BF8DCE25 + 97: 657AFE5CA6D54F9083F02C257CE7E3DB + 98: 9E65239503BEAB92716D5B504358352A + 99: D8375320E32FAE3BBABD4620B1231315 +100: CC8914472A9B5862287D695AD0A88BE6 +101: B0E0D8EDA1BDBEBCD0A78678AD7D6A64 +102: C8EBE9364129E651BD4FB491FE035433 +103: 2A6DF032E0D615DB3BE890B0B6D3349D +104: 975F0E184517902F1C239684EBC06314 +105: 5A86E403AD3D0B9EE5CF87C32482C6FA +106: D3E986B5231A204C88D7C2FD1ECA40C5 +107: 891ABD274D024F8B04143DE588A02AC7 +108: EA619405003DD17F13ED5BFB29587568 +109: EF5CD5EF1164A2E5BBC2D96360E55B87 +110: 07C74397955571A7E4025BB9EC555846 +111: B5F20FB0AC1C1DAA0DEF8EF78A9BDDB5 +112: 88D91C18A4AD272B4C1E2C76BE217BFA +113: AC548888F0E5E559777568ECE71E2007 +114: 816071E2B807CE6EF526E423BBA252D5 +115: 0585A675BADFDD749ECADE66BFFD0546 +116: 964CA97939664EE55B8B973D044D7695 +117: BB8FAACCE9D3238714C3934E6FEE2386 +118: 2BB26CD61B24CB5CB9E2C5FF40C51A00 +119: F5332DEBA64EB35CE3B5C7134C4C8495 +120: ADE7A5C99757D216D10E1F13E3A91F1F +121: AE98C3C4FD874CE0B8501FE4C428282A +122: 04D7625B67AC3F9D117AA45FEF6C6AC1 +123: A05D3C933DC8C8A1CF48290A5D52644E +124: 078F882264317B0C00383FBA7E079301 +125: 44023F3B109763A53FDEFF1822488855 +126: CA535702BAAB858D5FB5B79895E0E1E0 +127: FE1C2C02B7665895DBD2F4D2C22A7232 +128: 75A182DB4FD99599022F5A03F1427289 + +HMAC-rmd160 + 0: 33528FDB4FD0640B4C4363CEF1DE795719EBC7EE + 1: 514DF566C6204373EEE6020054AE7DDE2B0934DB + 2: CC8A5C8D2EBA02BF4474A4CC05CC2D863F1AA392 + 3: 27D731E218C369A32BE4B2BB29D2F1A0988BA583 + 4: 091245BFADF5C6635298702F233ECB3265E85460 + 5: BD2C07FA2197201DCA309063881F2EAC9D925A21 + 6: 480886856354E6FF34B3AFAF9E63FB794BAC4521 + 7: 258D58532BEB5EAD28E9BCA52AA4C0444CC2467A + 8: DB7513F824B42A9E1FFC1369F22F61054A3EB7F0 + 9: 3A4A258F23675EE02E1AC1F72197D1A11F32DE21 + 10: 9315ACAAAA8DC91A9AAF8DDD4CD000AE04F70E1D + 11: 57D60D77E1D78D23D3F184740D9DE392FC6C3C40 + 12: 950395C815A3D1A4A8BB25322333FECA15445BFB + 13: F8201A01C30F3B569B7497B5191AE16D1705085D + 14: 08DEA1A0CD4BD6C9031C84FD2005F15810FF088B + 15: CF41D88EB3921FA137F0203C2CB8BC5200FDE7BE + 16: A07100AAACF5253501A6643452D07C7DE2EA824E + 17: 19DE22082D1F4535A733F16262A135358D651737 + 18: D50BD92902AE0127AC8DD85E9A81ADB7EF3F1E64 + 19: 3FA34A3C02E06DE451794AB87C4FCE6877458CDA + 20: 5928329E4D830E8B2F7608A4ED46DCCFD5798425 + 21: 2825DBD7989A8978904A654E6AF125608B0BEBC1 + 22: 9C812424417D47ED7C78C7A049D4E6CB906DCF3C + 23: 9518A473A902DB6BB56F7A767ABA13C8DF306D37 + 24: 439C444C7AB4395C4DBA32E4F8CF4F76207E5BB4 + 25: 9021FCB087269457ABAA8105D4DAD8DF8904A2F6 + 26: 8B7B686199BC73A175940686BD57F45B2329D895 + 27: 0F50FB7AA9425975BFBB6AD65CF96284F768BB75 + 28: BAA1B7749A9CCAD7105E9ADEE499058A7BE4BA70 + 29: FBD3413CE89DFFE2F0A869036F5C4265D5B14743 + 30: 7CDB257E051ED0EFB761A5A044ECE5B0C1F12033 + 31: BB1E5D495074594534AD523987D8438CF1632425 + 32: CE6D7BEAD1496190F0F0E99B0B0C9BECFB7D9173 + 33: F8BE617A3256EB1C4BFC04CD386EB7FA46603926 + 34: D1A1F489434C458344239A75DA4241A3A94BEBA2 + 35: BEDD951DC98BD5C4138C1F8531D8288BA3C51B87 + 36: 9C2357E832CE87A227F6919B50A0A9D3A29B7CAF + 37: C9FCBB9A1AC48B71B2AA20AC992821531F1141EF + 38: 0B58D56923F9620BCD072703FBA71EC2172EEAD2 + 39: D97480E09FA6473AF9AAFA14FA9589AF65E62328 + 40: 4D5C56D0EB0BAD64FD0B0FB7F87D05EB551951CE + 41: B7EC2D13EDD3603D1BBC8CD29F32B43AEAF6EB4E + 42: 9BD5300B02C9432F686842E7900F3D2A085C5008 + 43: 7E8787C8780C64009216324802958E1D845332FB + 44: 1A3BC1AE95380D609571B01D8C3458B2566B74A5 + 45: 9672BD12EBBB12F398CEFA089BD3282A2D2892FB + 46: D5D3CAD705E2B0B6E0CBFBB0E8C22CD8EB1DC4C5 + 47: 408D84FE0B28A3B3CF16F60D6207A94B36219F81 + 48: 0B7E3D35C292D295797E3ED1F3D8BD5FD92A71BF + 49: 18AC1EA3406D69CD9E9C801F471AEA3A31C69D51 + 50: 98E40CE293ABE4ACFADE7D81371FA92AFA69248C + 51: D95E38F2D0C5ADB478A9BFF9F8E7B10064455C31 + 52: 6246C69FF502D453950BFEB5DBEF68CE76D70F12 + 53: 9D788F02EEE675F47AB4498B1337C6D83A37F64A + 54: 139387D749674D0E84F3C2BFBAFB3F0CDC4CA273 + 55: 09406CEDC1C37D275EBFE02CC707229244086CA2 + 56: BACA138E6EB6E5BEF150083CE0EFC64FB163EBF4 + 57: 87CF4CC4500A691934C2C6607F3296A0BEC980F6 + 58: F8E4DB4FE6879870E9F47BA29F0DA843342953CE + 59: 52DDF305014F1C68A34ED514B10FAE3B1B91F383 + 60: 0D568164C300BB14A4571A73493C02E4165383E4 + 61: E1DD806961D718F8C085CEA11A140900FE8064A4 + 62: 6470CBC7FE079B684D108550698B7C5D265736D4 + 63: DAF83273B2F16DCC69FD55DC84835931E75FF5D8 + 64: 47F4D7724BF49DE885D23D84D582EA3A00E1C2DE + 65: DBD6BD40F804E38963EBD2E81CE5196F6E69AC48 + 66: BD96E9391148957BE64FE6DA89CBDFF45233FBCE + 67: 20975680C2E31D61D7F303215A25CFAB4479F646 + 68: FFC321ED45ECC1A9FCDBC28ABAE0DA1FD27A628A + 69: 99F90008F139FA442C152706E522CEB349EABB00 + 70: 288C57DAD9D1174F4EBA92F7815B93C0916E8157 + 71: 8380FD083E742776CC32971B9E088B894A6A0071 + 72: B0F44C66552ECE94502597B6B100CC64561E6F1F + 73: AA0465458FA1F285F5A4530035F84F844D545A75 + 74: C90EE3BAC92FA4986C850DED11D728A78BE85543 + 75: 3E525BBEB158B246A3F4918B6D634CE8EBE4503A + 76: 7B42675AAE1D0DA5A84623E47C618744249384E5 + 77: F50AC31B43BC93D1BE2A4D9C40FC4D3593F2551C + 78: A31AE398E0D6668A52DAFE37D019F7571E0F681B + 79: BF10B29B4DC7C848C5192631E59E0EED32B8D81C + 80: 77B214EB3617C372C191D1D284FCED04F5AE17BF + 81: 1B17DC33F5966621F4BFA93961B1A8FFEE1AC820 + 82: 5A07D9861EDA6D8698E12FE5250CCAD882628B44 + 83: 176F46FF2202307828D7F62D39330444D688FDAD + 84: 59E94CFA3AC2BE8DC6098840E888306764308DE2 + 85: 679F243847C647FCC3F4589CF87972558350DC98 + 86: DB97F5EF492C7380472E16E3B055567DAB630153 + 87: 359CF9515F6B2192BF0E85EDBBC81D51232210B7 + 88: 30B59B3CBFFC08DA7D9514AE7627460BBBDED722 + 89: F31D5E2866D9726051B6E5AC9B846DB36EB705FD + 90: 860A58DDB6119261646907E251D60760099CAA07 + 91: 22EA0278EA053175C2F12BA4ED172FB0B518F3BA + 92: EC68297334F421AB3F2EF3518684E8E1B548BF56 + 93: 5C1405CC33D9025DA265FF4F25942853721489E2 + 94: 8AEA8E9EAFBF3BA597B65BBCCEE59013C8E6AC8B + 95: ABF7CCD01374D5DDAD6EFFB19412EE772E663DE2 + 96: F7F28E05FAB93A3D089BBFF56D4E462F0BEDA41A + 97: B6C4199D504E72793EEB49611E28A82DF5CD7905 + 98: 0B0916C89F1D9F1134E9106FEBAF4169DC49F752 + 99: 4F18AA0E88A01ED162D08F35300B1C3FCE1FE8B8 +100: 5D4F3C473D5859C16F70C1566F9800B3DBBBC643 +101: 02C1A5F34232B8900E6C7DF2BED957BCAE529784 +102: CDD46E434331D7869A27EA096CAEBF586D93CC2E +103: 492C04E69F0204F150B63022C7DBD28116458F97 +104: CDDAB90168E934E69E942B1F1EC0D0AD7BFB5B43 +105: F433642FA8091FB2517F3357DD30308B4A2AEF53 +106: 537B2118792B6A419C438E58CBB6C5BA887AE257 +107: 753728CB39813C27498033A07DEC03D1FA720FE9 +108: 119A6C5BF3EA8F7A78DA9ED2DE7ED9AE3942964A +109: A501EB611542A2A2CCC68AE754D2EAC17942BD8D +110: 158FB54E37C7DF54B29928B5DFA53A560DC09A5A +111: 15F5380252E23B5C37EE7E8D1F5963FBF8788577 +112: 735F2C3CF7680C63F33AE2D4F3569FA8EB45EB93 +113: 67AFC501C6582DF2A9DBD713F206041E5F3E1DEB +114: 7CAEFEC1C6E8232BCB90E3FE3523EE06496F36A3 +115: CC90ADFCF3F9AE777B30EAA6206A34EF54F74C02 +116: 974E0E85B47CCB870A511810DDEFE81CB85B28D3 +117: 516D6BA01E0186CB7D796FCD9DD169C45B63A93E +118: A1CE534BDD6591AF4EBF61ED75636C7BFF670658 +119: 1E4B241D6EADD77E046BDCCD25F70AAC969262D3 +120: 7F2F1B4B77C3170A9E015DF4E8C6EDFE736DFFC3 +121: 89A3BF181EF195464DBEF9576873CA2DF7D16268 +122: E1F96A7C9115E3DBF28E10D62F2D6EC89415B6D7 +123: D75C1081B3C2720D030EC5DE13093357A0EE6E51 +124: C11603CDAD8DF271093CACDFB5AA4E113A270EA5 +125: 39A9E659DFFDC2ABC88ADA2B6A7445090C7EFBF7 +126: 4132330C5E3344818AF5C054AD55309FF7B767A2 +127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D +128: AD090CC9A6B381C0B3D87035274FBC056012A4E6 + +HMAC-whirlpool + 0: 5C36BE24B458FD3713761955F28353E433B1B818C8EF90F5B7582E249ED0F8C7C518ECF713410885E3FA2B1987B5DEE0FBAC210A007DA0FE995717F8FEA98995 + 1: 30C66EA7CE95764F4CFCFBBE4C166E80A1F23E8C88D2DB7FAC118BCA9EE28299778610D94CD545C18C114A2A144F9E933CD80238E9F1AC737F7149BA232FB846 + 2: A61FAC4DAAADF3DB746DCDC24CACDD8C2B74429CA812D86091B5E7F8186753B34532047B3263D2E231074CCDFB18188747B657E0B685693901CBBEC524949244 + 3: AC3BBA8D998C234F9BCE9A96643E8EFC342F4772DF5606A812C1C6CFD644E8F2B8F9BD724CBC8D769B74C52669705BD3AD390CA61DBC7EBE4438726A91FB2455 + 4: 59AD4171B4C33E09312A01B97B3BC2B7DA43F8791561E32A9186C9B0C418BBC31DF54D6A9ACA00910C0F3DF5D7C2DD7CF5634B76506646B7D4EE5C60AA7C7950 + 5: EDFD9FB5B7BCB39811D87A890171096AD2237B78862C4921191F8B0B137DE5178BE8DA898B6A895FA6C4F401714D2AAC743F512F8989E39081F02A2A0F9F6137 + 6: 6BBE26824C7582213F89F773C520710AE400F01B99BCE126C5F3ABDE79C8B304139352427A3E25A313A5F753A94B55F1EE9D3A0300E8E987E98004F58707F73F + 7: EB89DDACA2BA68940C4616B3B1BDFC25D94A78B8C3A533F1231A259BAF6A6706E1B90CBC2F21A76210C0322C7E4286E393B167A2455DB24C6B52B0CEF3EB78A5 + 8: E8AF385440589959D67746FCD40E295026E942E44259169780B3954D20CBFE2586D2A8BBE408AC2D707B0FE539DB43B3E9B29A8D26D09A41FA6F191999A45186 + 9: F6B9CF6E0A337906517DB09EFA31E91D57D6B908ED5116C13B49B8F1F3C3A872EF42DED53F939CC4EA4122FD8580D528AD2DA72BE063251CC89FB52741E2AEB2 + 10: 274FEF3E5EF7AD7AFB1161A29492F0DF44BA9E1C30E1E88CD708A5D27F2B35C45085A200E9F42F340B0D9B3A1A354B1F5F6D0D1A754D51DFC39CB2EE213112DF + 11: E2EF7A0A64A3F384F95823201823BC95060707F273E395F46F3C0627E1CD2BCE97DB2984C0EE7A11B22E617F0CF64A3F44BE9FD6B38C3A07A504DDC1D33C73B4 + 12: 681D72B9BCA446200BA7578E038A8FC418225BE5F02D8DA3CF085182628B7BE587DCAD4851863CE1CE8653E4916047F8E92E91A6B0D7FFB065F316DA93C4F44A + 13: 2CC82F237ECC1B9B0B9FB76E6B9651C56AE57CAA072A0C20B968F2A74FCA6A9749FA264331F4F2612AE0DF32810B0CAE95E5861473F4675766459B7380F7B9A7 + 14: 1F3818CFB04AA3882442FDF1F5CB0DB2FA9604228D3CCA1F14DA16B35D9B2071B372996A176AF0592F00175EEA4C16A6E0162DE62DE30E8A80FA669FAE9A33CD + 15: BFE4BF868A8AFED289DED5F6E7B21E6856107EBEFAEAB5CD644FB5634181D52D8DEAA203C468ABD279E9BE73507A690C0B715869F6E722C4512E815FA4EF641C + 16: CCBA3834AC7BF06B16675376ECCD96A0F91E3E3C588C5BEE1711A00C107B35D603B20DA8E5CC5FBA6937A24DA53D8F55C907F3E53F0F255E080396426E7ADF9B + 17: B09F6898640E5CF77B6DD3D5A8A4452F4F1D25C90F7AA55A205EFF2C319EC0BE245CEB4190F11D85C2F7234BEB899BDA465C95A1C59568987C4C020B9A7AFC00 + 18: AA7FEEC56E16AD79990B003AD51626C87C9CCB90EBFD748DC268C0C8C1DEE1BDCA1C8064FE7570A5C624AA0CB6BEC163E63680377A16AD49D1AE166090DC0D80 + 19: F755304A4694DBBEB0E59B978943F3D4E429F8123B3D6CE27AB400D3C4BD81A13A8C3C0BA0FA7E5F13BCB0B48290933A05DCB49A5907C074039427F0EC9004FC + 20: CB8B5804EF0478645400B1655DC6E194C8DC26112EF76C57823A02F39C8ADB42F1225B130FF0D40F580DA8CA95D82C0441E3A82C206D9D8D6DBD63B4BB1BCCE2 + 21: 4EEA4AF294C458BDBA7F49AC0826BC295BAF5B16D16F40D379F6B7C3456EF4145B5EC7F7CFB85638F641CF4D07FE3904DA891E68288FC11C0C72F54430915024 + 22: EC52FC8CC0F849E633E3F7339031DCBCEAB69B6634D3E54E7C153CC63DF7D3D3F93B13C8E751E79290ED4845FAA3D5A79A7DE6B100F538E0FFF470A51CD630E4 + 23: D44419C0A36FBFD0FB441B596E8821D3F543D80FC7EB5A3389037BE0139921027571502B5C53BA30D31D4A053E830E610A394842229E08485A2376CB9766313D + 24: 3F4BDBC8A4C86B3F646CC445E2CD54B4C786BAEDEE9FD91A879640B4085D46FEBEECECC95E819ECF6AA9085C2309E79DE1A988C6B68930ABCB9BBAB90F1C2F85 + 25: E5EBC015269E0E61BBD1717618C15D44953AB6F854D962A04FE88865626DCDDEC5F094AAEDCB708D947A9547A985F0B287CA0FBBE3FF2ECCC4C0C4FEE4FE74CB + 26: 010C622DF84E677805108A2C5FB1E8BF5922D35CFAC2408F2AE174D353AF169A40169709C39BFE90E51B095C8C0D2886B4F10B37BEFF805D384E29CECE89C4C8 + 27: 3E9C7BE96E03C48DEA773204E1EC3721EE817ED2403E3C8F950A4C447949438037E2AF0A030CDB983D3FBE5B82226F510FD91CF8830F59212F8CF26C2B5E4DFE + 28: 8797C9C14CD2DE3CB1D29808DA9F23A5502A7BA579586DE9513B980FC06990DE0E29837ED06E24B15DD0000697666B8D3DDC556D818E87F84D125697D5E2F8FE + 29: 93DFA3DEB3258FC7C4F5362D36C2AE21AC0471AF8B895B5AD1C407E8D50DDCD0111AF76EC500D7BE035E6F9CE932190712A3F52FBA4BB0DFCE74400C82D1BD8F + 30: 5587EF7A31353C0E9C346C837EA645770BC5F5C541B72886844B4B0789FF1D95134F558B29385B35960AFDFEA7E3AA40562C12683CB7DD9A410873565CA10880 + 31: 052CB0FAABB263A49516E39525023E2A02DCDB2D5FC78948E042E59F89363FAAF1869D42EC9D7AFB0DADB7D4E99544BEDA92E3270544900A5641F059571B6238 + 32: 2FAEBF049CC4C9C2770E859739B1774EB6E6AC2EAF1AF7D3EB55774C03ADC4C865A65C82E795959CBC4BF00A64AFD2AE0CCA16D58AEB874E253FB9FB9A266790 + 33: 82FBFD2A46F2102AC27089B6889024FA9172FA691C1E3BA9B44A394D52EBF5A7A8BB2321708ED9AF2776D8BAEA13A5F2E9EA4AAF420A24B6F59E2F583D54A797 + 34: B306D18161C766DBDC734FCEB08D14248EBCC63FCBB5B9CC0AE9D690E20E7152D771B3D623D7ECA1CBD305A31EE10C220FCDDC2CE76B578E2F15DE4741E9C9AE + 35: F527D57F0A5F13D7FC6A30A84BF414712044B56FB8F6C1E1375A09783968A851DBD495D51C693590E7A8BB570A7F1C0C9ADAADB74EF8EC71A0093D8D1A4285EE + 36: 0D9F9DB43A0FB4BDF70487002943A6CD3BF200518500B6934BA518B3B0958095930EF59BAC48C84C1E1ADB815A6569FBBE7E61F039BFD8C2F727EF4636542A5D + 37: 614CFB257400128FBBB7B56550E86198155A5647FC11111FB4D36073BB57AE4D9C0A54BCF0DCDB8B54ADE4FF8AE5645821CF9C83F7FA9468FC2CCB552E30BEDF + 38: 7032724503FA5B0765D610D3FA4609F4537F6EAB75D7CC4E2A15D2B1421293D9411C9E8F38999F7D64D607EFE95224331E47FAD4F9BDB6AC19CD3ADE47C17E7D + 39: A8E4316126475B429E72432073CBF26E94DA450DB553D46667D597F0AACB99325C9EDDB94F8CE33551857827AF3935F2DFFE1EE69A20884D58E095390C04B925 + 40: E7E90B19E76017EE80E4979FE56A488AAEEA011DE9DC068DBE53AF06ED44DA4CA3BF662358F191FE2842B083BC5DF2D4183668F4E7FA9E2750869DECA7302202 + 41: 818D734A02A0AE76A0012D7BFE983B17CACE37D4890214C7C53A81CA9F42EF0A472101D609BE5D3DF4F0A55DAF154C20A1A97D53112E22D136C03004FE09149C + 42: 0B9F5B2D4BC3DF781F55ECEE149470F3BF68FC51D121D021DF0CB8D4A5EDA42EA6840DD735ADF8DED72B325662BCEECC6195AE831D169A891F6663F8D7C6E0D3 + 43: 7A5AE42C635B250598C536E531FDAA1746DE2EC7984DC1BE488DE4766D0CD544AB51AB1E62A8A170D120999A61CC6920DB96935F295817851A4CE285D2755112 + 44: 95093085CFE52D746C54DDF8D2FBE33EC00D71C39BE0865B896C331C7E5682FBC0DD84ED15B3F790166D537A9A68EEE5FEEC63FC761EB854018CEB68245CCB90 + 45: 8BA177C495E9832CA8EB55E67E5D7F34C59C4C59D56D50BF6982B36AC341CBFDFBF5A98BBEBC26A9509FBDFB239312DF3B3D5BCE70386EF0E593E17A621F41F5 + 46: 6DD39D94235D012C89FD030341392AE42BE7702C4D8E725C4229940BC273EBB8EDA7A6893B4FF86D1EF84DFA119058BC6C8CA47675492A0D37C859E6D9BD5471 + 47: 13A2FBE3DBAEFCAC5AB8BBAF91BAFDEF5FE38B7F2EBA8BFF0F44B4BBB236613B8BB122BECAD9852BF7638E48F0FC656F9C432D9A66C1188DF3FD1D2A88161139 + 48: 33B9B7EF63B302C1C79E0A43D77487C55D38C53F29C800B4CC287A99A440435121C7ED78BE7406349E65AAF991EA0EF19D06C1AFBB814FE4E0BD68613AF0C760 + 49: 720E1005ACE28903D9C2B6EDE02A52F89860788AFB35208B4B7C147E43BAB3D06445DA138606F334624C606DFF288B0C70B487679685D1DDD26F1DA0A5F6839F + 50: 2A742F1E8CE6CDB501E8AD9BD256786A42E7F1888D9803AA8D5750817B3EA101331D7266298962FA28AF2232BF956FAC7C1C0B1C3DE4C5B3FDDF8E63BEB02185 + 51: 05CF6361A4A238091A1FD011336F7F53B9ACF78BA1B96997EE49B99FE36F0F1163E04B446EEFC117B377593EE078B85BB9588918C76612E2A6F9515E0CA244B2 + 52: F510C877546FD2D022051364A09F2051523F8E7FDCD3E9D2AC5158205FB36CF25A9E0FC394ED2FACA7CB4F0639B33B706FD4D072D62F6EB229E4D7879DFB45CD + 53: 2664476D94776DB52BAAF3B2DE05A36D3E35EF44ABB6F09670F37EEE00C2C54B38F70D06359B20F7E40E22B42901863864EF89EA473A1F3C834D22176E87E617 + 54: 62620CBDA92EC8241DD3A6A0EFB28254B0CEBF3E2351B10CF93029244A6A3D1DCE10D9A895EB6E8A33108DDBAA897DFF2703757DA3706209A7871F4274901E3F + 55: 51282A90B63998F7AE7ADE4787D957992A81D3009D6AC5BF824DD1507B53F6918E9AB6AA1F36373D5E5D3EF8D01AF9D05FBC224781C62C1DCB4A2089BFF5496F + 56: FE1C4394AE26E4B85752045DB14E0AD378726BC1C985C8805222B614C62721E40B2A0D21983FF40AACE8E5F9CD57BA62C37C8F0968EE12FAE14267D6AE906A7A + 57: E570E1183CC6AD7A2C73D7D0E96D3AE0605039603B6F6467FA5CA62E4C1424BC14B17E9614F0ACACCAFC2B1B39D8C081B05DFE2B9796F32C0C742FB09DC7B8DD + 58: E690D667A94344E267A6EA7F3F7A6A5385C961BB6139800CD5257BFD6C4A672DB576B52335D22160A372987D652741EC3AA9439B35D8975AEA49698F8D5528E8 + 59: 59FE977EC1D9927FB09389E3D31272E625F089AA75401D1B541DDCE8C6983A363622CA4F2AA9741F0D1484195CA31D6D315DF6B66E74888D111FEFD249FA0174 + 60: 2CAA990D06814CA73ACEFE0D9A815589958398999707BD52C3773F61B2DC2F20EE7AB7F66D643BD9686C4C460AF45D58BE9F8DFC1B5CFE3A5C2DC2C93D9491A3 + 61: F198E9238E9592A97DDFE1B0B56DE5DC05D358940672D84F15E1CE71ECFD3854CDD38762DF11E1871EE615EB6080E329495B37B23710DCA9F4179F5F95F3E2A3 + 62: 3D7C45603510C6916226B192C81B90EC213D30C11AA21C8520437CA5639D00EAB529A4C443C9A39C5E40DFEEA0F685B3D0E1277BEBDDBF80C3D5F9C8326765D9 + 63: BA081CA12FFBE3CA8F1E2703C96587634F8EB3BA140F93D997B6D0FAD1C1915ECF7D77CC0421E639B083451EDA605571D68DE81E7A4BFC183D7A53A07122168E + 64: CEFE2203F6428D267CD2E284C3B8C31E1946558A56A33291508093DCBF64FD5FA4D33FB723ED49CBA02D97743312138FA77AE960EDF5910E3ADBD02B1203FD97 + 65: DE0379336B1C7421AB4A7F5708BAA3D4E15CE75CEEB8C7349265E71942A963216559FD628C52F71356134AC328D0315ACB63A06382D4251A28127380CCEB08FA + 66: 95FD3399270415A80C2F295957C0BD8E33E35C679C31B2118DFABD542EF02F6E2E432559ED4066954AFBF90C982F60D73DA8BCC94DD48BEDBB00A8E458CCB6B8 + 67: DE49AD8262EACF733B567D8F7752711ECB5D0FF5CB18E5A99C6C35442E652643149A51C820E6D4481AFE63F5B6955105F8173DA57DEFA392E43F7285799A32B9 + 68: BED41AF0733EED85BB26E8A06949AFA1CBCA9BA87C085BDE29FD38F94709F4AC20360F7C7958457D2C49BC5A38FBA06D6A6AF77ACC883783B357032FBA9F93CD + 69: CE72D475D983EB5E528C4D71EEE48EF337E1723DEFDF142598E4CEB3B2978B1B4E36A69EAB6CEE8F3DB2EB353CBD27BF7D41F73FB184CC8785DDCE8EC22E9741 + 70: 24A8A7C759F59CD3DE2E3BA953EA975B60079D9B331AEC4D1F4586FFAD190EF53C2EC6BAB566660EB5D652D7D54265B8584C6BBF986537F54F9D8E4068C01F67 + 71: A7CBE72C99EEEACB387D4532BDB651EB46B8D30A9D5DB8095C9B3422D9D5C9480AA820CFAFE4047AA0546C03DBF07424FCF7B812274B3CDFDC76B9FBBBF08190 + 72: 16D536D1D673F74D9E298B16AE65C65E467131FDE5B4356FE16E3FC36624E19FA7B55727240C51C20491F3122A1AB073B98E095A24F4B3260EBE5211EA2DCB0F + 73: 692189C1FF6DA5862657623BC862F5041D63A2A1EC8986139CCBCAB114427B1A2500B152CC611C5D5599E9792F014A640FBF7C6D944EDA811CD92374326B2C52 + 74: 273E18F4B94E624988C47CC45820E4552DCC53BB40A9A24F744A14E56FB1DADD3EA4087A785AEDB5400A65971709DA1AAB9C18EF534087EA73A1FC8FDC865170 + 75: 8F048230B202743FF1DEBAFEF8CC93244687A58A8E5E3E6F7D85237ADBC724641431783E63FC8EF2FBEF9DE9CD50C9FB294341654706DBEFE6B05CA8588E1A3C + 76: 7AEF7701439F9DB556AD3B166B0B25A51795638A83E0EE25E5244BBE9D2E8CB6A8242D81E78E4906AC9CA0AD4FECD1006D89C5A8582D1BF51C278EE7A357232D + 77: 55CE718F7686A0692B3727BB5C24B16FCB87D8E8EC943A80236CF3E9B37A4A20194243E461B453CF03AD846A0B3287A2005D6603D5E080D700ED2FA25F0FCA87 + 78: 3378B07E0563CA7BCB91F29C8ECA876AD748760748AD07DE0208BAC227E0EED4A4834B8879F3DFE51FFA27B70AAD1F3E9FE1586B1D6B2B9757D545D9CC5DFBB2 + 79: 040E1EC767CDD85FEED2AC6767F0B3C17CE4579FD9525213A682A9B49ED03979144CCE2B94026AAF7D401355B90B25259954163E0C9739CB9E756177ABA053CE + 80: D1CAE0E4FB245C1AC27659C2EE86BADCE26228CF8EA24AA62B69995FF02F9A59B1ACC1C959EF91A7B6EC90EA9D57F49CD0E7621D09E4016676953A3F9B9D40E9 + 81: B41EAC0850797959C62DA2750F2BCAECCDFBAB843D56C034E4E0DC15C961FA611C50F22BBC135E5D99DC4E4B7634A8DF4B0262829593A8A86EF6C265DB9AE907 + 82: 66BE82FD1582736D0DE7861D9DF74715658CF3CD2BCED12868EC4D92F4B015B7BACBB331ACA8D58386AE6B0642C3740BF5F3CB26E76551541AD57E1C303D4527 + 83: C38BC2639AFEC1964C89CB92DE5ECB78E0B2994EF37F839D0A61EA688CCEB068B1A590D6CCC929EFF1145F5A5925A17BF2FC0AD352801CB92651F08352A992D5 + 84: B699ADFC29C54F178B3EFFBF8FE8BFBCD722F2997AC30754A8FC5CC6D51352AFFF7F31D7F71FD9D136E78D1C1E040B05E25CCB75C7AEEF714018F51663C7AD91 + 85: FDC4207E97D12B7A8D05F5073D47EF32BA32961568599ED34CA160F2EDC87726C53087711A63F6BB7E840F305477B931D1CBC1939A8B80205565D453675FCFD7 + 86: 07E1DDE64790A279B69873C6887FBFCA69B87C97BC25B969E2B16040CDD2051BCF43637F490EF1B051CD882B64E22DA55C253A5E796528526EC62A305FB05621 + 87: 3ABE353A4291A3A0ECF204994D49443C1FCC60C80BF6096026551048533E02C475B905046C7708F4852645168C88125221504E174A8B7E67AE424C0077163E0D + 88: 33793697140180A04DA72C0F74E1F845139937CD6F05AF74E3F3C5031D1D2DE571BD72916CBE67859FE501C0E56354C1360E3EBC36EBC11D11C1EE08D158247C + 89: 9E5A386AA9C4C5A2419B902D239E49ED84E542A6F949895C88129DFC2844FC77FB132592C7C1474E619C55FC2835F0810F227799984777CE99D586C158C8F9ED + 90: 6E0D9841C04BB47DEE30F6AB430E53FA1637421E460BBBD7BC8EA167B9A341DDC5E933B6983A025226B1FB3CC663EDC3477F8F0C8FA109A8B97B4B17AF3C2774 + 91: AA0218FD54533314F62390B8C02219D26801C249D394E33981E3B853C5735E331826FA02697DF54C9268B891592DBD876E25C8D985DE8752ADAA0CBE55AE7FFB + 92: 23905B9273CA17D80D9C877DD78150B5382744896B073DC636618C540876B9BA51EC60F5E45DD53BE210B6076554238A3B5EA95DCE3481F0FCF2825B852BDE3E + 93: 1815D1AA4018626EAFF051AFBB92E91F6D6D136F58E8DB160C9E85BEC027B6CC92F0F0760DFD722BE12A97F7D29EEC341BD309F230B55B81D146B409EAEEB7D0 + 94: A2358789A04795BB20D2EDBF95D5DA28A1FBAB329F99DFD0B103304F868CE5AA2DC1F52FE98CC84EB095B9C5ACBD6DC05FD03CFBB3F1D26675D0A8F652D38236 + 95: 2C4DEF028098A0680DF15DEBFE6A7FA42C7A7D75CF410340ADD5257037F0B2F98FB5A068361DF33010FD48A4B41E0E40A2730FF2148C45FA568FAA182589A543 + 96: 360F3B6819EAFD9B3D6BC469F4272F9458C0791759EC1136FAD500F3FCB4FA0598204669E865D7D5F8C289043A2A1CCB47F55CEEFAEAD98C7FDEF38FB22D3A29 + 97: 1CB2E98EE8795761EDB7579583EF86E7223A2109267E5234663BCAAF9FBF28EAE35FE362AE9AD075023C1D36672002E08CB36189A603C174D73BB9489E13355F + 98: 9B3F2D2B2E3D0401229F11E6DED451A1289C631122684BB32B8C0450043ED2267AAEA20E950F52B44EA5941C507F38D23CA76E212593B65BAB347841179BED1D + 99: 2E27C53324017626F7EE7EE26BB0C88450B3D882C2D8823647ECA7650CADDFF3E4201D7DFA2A07A51B9372FCB04C1A79A264DCD3D260DE135D08DBABD2C5869A +100: 0B3D7FFC5DC1CB18B867D995E3D02FB2FBA0DE27BCC85E49A3B01C5581EB3B14C19254C87D92D2EEF952C98E4E6F51C9662CDB982BC95B88C11CB2EECF032576 +101: 85C0B9C8AB8C670C01E179F495DE26F818EE772AAF6FCE4ECBDB4FFADEB1CFD8EA86E42020B47894301920B86082DE52A7E7CDC6DB4904F8F0D383D9CDA312E7 +102: 0C6637D399CFE2734AF7B63F81B7493158B7842E3C5B72E6CEA4388A5C6DB7222D46727B92FB82D88551A227703B8BB6A1AAF47247661E074CF6AE4277D586DB +103: DC54B4ABBB7942C502BF3275E37570947FF7162B6831AA430566E69AA80658C6E792B78EA081611256C64552A9E15A66000632116AC83769B7C58B809FD96021 +104: 532372848D0F525884E5ACED9A727E96A8D92B484DC2D4089206B001CF9EC52902E49E6FD9FDE634941BDF5AA2B45B0787D0B183B895470BF1E79B57DC976EE0 +105: 4B6CEB5AA2174E6486ECB185044629BE6C280807F102CE52D2CE2DCCCFE96E5586A6888DF7500614896C9FE70CF7BC83FE755E88170B3D39EF9B218BE809E495 +106: 6D506B4BD3F079EF4818FCFDA519E7E2AB6A03293525711142C3CDC5236A7CD82A880D9CEDCBC089F7A3D5D3E48BD75DCCA7ADC53B13A2FC9CAC80C037F2CE5D +107: B8ABE308840CC901C6C5FD908E2680886AAA0BDF7085C1A6ABC257186AFC52C522528BD7BF4E82553D9E64CBEE09B9318995E13715AB1F7809EF185E8473D70E +108: 9790A198DA7616F4D8ACDE68DE19635A555874EAE77AD4ECFEF7207DC305D475FD250F308F466B189425AB6A9722D744AEF14541FEB83698943E87E8A39DF838 +109: 816678F1D7484660F4701CE77F4C5E13E5DFADEE6622411BE86DBA4EB71A110DD1087AF7D3F37B8ECB1B9C44A3BD5EA73901C21AAB51E569E61EFF25B5E955F9 +110: 51881FF4B150EDC3542CA12CE6554A40415AFFAA1197FE7CA4B8B065A4FB1DC3B924A444CA31776CED52514C525261269895EBD8584C29747F8D527213534E49 +111: 6D8902F285029EE683CE1803B2D9C6BF6E4B7B59C0ADBFBCED3346782A35652DE3F304ABBDE9F22E4960DF6049431139EC6AA023EE2B013A426DB9A816D92699 +112: 06E5847A060BBC4FCE1375DCC15AEAFBF514EE1ADCDF42AFF932AA277DC09EF614651255E35C499D6BA1BB875EA3E80F80AABF8B7710AA5696B058BE91B99B01 +113: CB1859580DCA13556FAB791572E523C2E888115C18C043B0E33F2268DD0056F9A60EDBB65DD9C8B552CE2299E847ED4617BEF3A453ED2AC3B5366B4D9A651B61 +114: 39778F80D346E53D1B0E60FF7B36A92639D9E7F11548C9326A59D9311D57BF09F33BFD6AC5352F2F041BD07A6D26A181419F5FCD1D5FF8AD38E485DA7DBD5419 +115: E508C9A77F53E36F76F0E477DFF076DE810F9F1599A16A3EFF1840332B26D6C7CC40E03CA8CC212FDA776F4DF968FCF92CE492AEBAABD65F069D1AEBECD11B7B +116: 4659D0E1F9E5318D7B92FCF7700C467429B63F27188C0BA168F0D5696DC764FBFE2C5EFFCF6DF11EA77A17B0565CADC04F95FFB0485CE6900161B82608B1647B +117: B3DB7FF2F08F57F0CBF2195BB9600E9AE5D86A15921EB164A98D25D559BAF5FD740D68430653DE73F3277425DD77CC3FB0CB44ACC5FDE693D59D5FA6DED84597 +118: CA4559843946A7583F944D51E31FDF32BBDBBFC049724454C090A6DB9C356739F2B7E254CF9746521D965593FBBCFB26092069FBFB0D17A1593416D69681B687 +119: 27CB8A2143D1073AC17009C31B28DB95DC195E20AD7D245D8AD880789898F043F0565FE41485EDC239C7129E4B7FB693D9044B2C3D34C5648E4FD8447E85FD71 +120: 99811490C7FC83A10AAD197E95D3618ABF5018E9AF7EA0AA2CC0C771FC11FCEF9FD6070A0962A563D260E8CCFDB77B48745C8C27018F9140870F146F124FF14B +121: A1537FDAD7E18F732181CD9EC9BFD3993FAF5F994A8809A106B59D13BB70FD8D7D4E6A4BEDFA806A9D434AAB0368DE840FD64395B4A9A874DB39405707AE3AE3 +122: FB0D6D962055B47D3A72371BDAF77BE7BF965EA7D53018CAE086E3536804AC748E706E89772DB60896EB8FE2ED8F580866BAF3108CA0C97938B69830FFBC14E3 +123: 3C947F4136D9E780A7572CA4D5D7998DD82D3890CC3F1BCB59A7FE230E31DE322DBA7CF7C1DACB33A3EB1F7E75297C056570D2846EDF756D36C1AE92F8DF6954 +124: BC1BDEFFC6AB779A7ACFE53A3F9DD588CD3C77C740F944C69E331C38F162607E0D4A0CA874AC3D1D74965468843133AA9F961FBFCBF59B58818577132B863181 +125: 51143DA8F5D6E68EC97CE22A4961EF43B3AB658711280587D9ACEE701CA65CAE90D34B66DB52D779A8E2BB6204FFCBCA945C6B98B2C17C8375551FAAFE4C8A44 +126: 2550FCF54872616ED31C60FB3FD97B9AEC7A27B3CEC07D774FCE694ED9D60C43A968251C5F3C5B50E6214426B00C55D7DB1DB31CFC4BC07F6ACEA222052AB796 +127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB +128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/ocb_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,331 @@ +OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout. + +OCB-aes (16 byte key) + 0: , 04ADA45E947BC5B6E00F4C8B8053902D + 1: 07, 987354C062CD6251CAA6D93280EFE9BE + 2: 1CB7, B9F1620EA8374E1C2D05110878D93069 + 3: B98C59, 3793FB737C2DFB29E73DD1AD8B8F71C7 + 4: 8978F240, 5E25316ED13D3300F2EC12D718A0BA8E + 5: CB4D261594, EDA252A1A5C7D0A4AB4620F771446DD3 + 6: 30D6B6688D59, 684037DE07832C6FC38CA42BDF2A7D53 + 7: D0583F9741BFA4, 3DF53DFF73431C0245982F4EEEAD432F + 8: EE3B9596CBEFF520, D283D1B9D990739EA05F4BAE2E96BE4E + 9: 6570FC25E6103AC125, 90D3F1FA6595B775749FAE7B00A8E5B1 + 10: F56750C98C370DFDC4A0, 19389A6875FAB432B72D64BCDD6BD26C + 11: 3344AE6D9528603CC1E4E1, 87AB6FBC7F919125A7DB0D17D19056B8 + 12: F3D9D816A727D3E67330C779, 07AC0F3841DFCFEC58A5AAC22270538C + 13: 976651E63ABC3B276799BC1FE4, EE603A8C66099AD6FF8667B3F34ABF29 + 14: A48E3ABC31336C6B717A96170A9B, A9D1B973D84D3125F5F9D7923BA0A8FF + 15: F60E9B2A911FAFB0080FAA3ECDEE42, 4902F8AEB7685F7B255ECC45B5B7D3D4 + 16: 0855DE488940144AF18C65A9966DDB66, A66B3E7A75D394273AC196FFD062F9DD + 17: 172DC1740F75AB2A27B2B80895961A69AB, D6986BB95F7E4137430CAC67F773623B + 18: A414234DCCC61B65A79B7C618A6B91ACA410, 6CE32E55E158BC3E51E94116A615F3A2 + 19: 16A1B16BC0F63D63179901F1CBC772D612C102, 54007EF9822E0E4A4F953838577C76FA + 20: 539788EBF85C15B3A638017B4054D71315BFF25F, 9B2511322E16CECD53E3241F3D51EB97 + 21: 7E74595A3DCFE1EA2C91B67738765463D50A22924A, AC9C9B526251C16F112E769F9FBE74E4 + 22: A2B61792102B2E44F1DC0E48B40472CE883730504FEB, 76452A49C2524404C8A4B098D6390F98 + 23: F58174BC06A022AB7D81991E9346F5E4B0AEC535D93473, 47F96374BC094BB2C1A5D1D291806912 + 24: A3A7713895D178A85D9092EA6138323DC2FF9090D7F01AC5, 3814208FA7009A2934F9A172D029667D + 25: 385525DAF9949DCDEB22F7518AF96438E40F7D94933706A9F2, 1249F3DF50084A6D1A76AA350FD85B0B + 26: 6838E207D98A5BF8D8E41454CF51663D8F8B76FD26092D45D1D9, 301723D0F49BF8CF37828340B894689C + 27: 736413C025A549CB2550E93139DFD5DC3CE241C296C9FE641FF520, BE07259963F251743A85DF51EB1B47FB + 28: 7F2CD26367A885BD9E2B515D4E871272AC1BEA1C650B530E5616B2D3, EEB37E8451597E5A53CB49072EDA9346 + 29: 68F23DCDEF223B60B46E3D724A93BEEF8B110D4394C990AC3D0E34E1B6, 9A60344982F852EFE02CBE9CBBAB60F1 + 30: 66C5DE3EB27139983D48BED81D0E5FCE6BA1AB402C357062FE989D31C69C, BAFA0A7997A529039F0CE8528E670415 + 31: D3B9009C1A930EE288C61B0B15C7E92CB73484C345594DC5A3F377147981DB, 1EDAACF7F1F3AC7EA613F94DA4DEF930 + 32: F7818DF15FE6FBC42A28FDE1D55A2C07EC8D82AA0E7A680DBD3CF26C13448F9B, 67FEB344108008A88067E92B210766D5 + +OCB-blowfish (8 byte key) + 0: , 07B7752047F9E0AE + 1: CE, 7D69017C42B06204 + 2: 1D6F, 4DFD4BD58439062F + 3: 30A011, DB49D988798F8842 + 4: B71C8951, AA3261584B0C20FD + 5: 06F89957DA, 88BFA80D36427F64 + 6: 45BC4CE5FABD, 4CAF71136ED166A7 + 7: A7405F124D0296, 5D8993CE64FFF0E7 + 8: ECABEFD9E6574E4D, B69349673CF86E41 + 9: F7D26A7E82A34ACC71, AFFDEE843ABEA68A + 10: E225C5F0FA1D649F81A3, 03AC1D5DF1323EF8 + 11: 58722FBFB86C2697061217, CE731D80E6355710 + 12: E577EB8FA70225C5A18D31DC, 2F08B140F0D3A255 + 13: 92154A94CD7D42EBADB6CFEE14, DC949170E84D3CA2 + 14: 5A3C08744FD85CA262D51AC6CD25, E83CE45547403BAD + 15: 8B2E4980ABA10A20573A402D89AD12, E3D978611DD831D0 + 16: 3EDC4A0FA95BD8F944BCE4F252B6470C, 87B54BBEA86A5B5C + +OCB-xtea (16 byte key) + 0: , 56722ECFE6ED1300 + 1: CA, DF53479333DB86AA + 2: 9529, D0B5A859106FCC9B + 3: DDBAB2, 3B31FFDA57CF51C8 + 4: 22EB7DD4, 2BB34D04FFF810CB + 5: 108693761A, 7AFF6F52574A019A + 6: 391FB7C61E76, 616C5E66297F2CCE + 7: 3E22E4A4A0BD13, E84C385ABE25C8D8 + 8: 94FA11D5243EE34F, 8F017DE96049D0F9 + 9: DADB6B5D27049240A7, CA69E14047C6BBA7 + 10: F79C8EA83C69DE914DAC, 1EF042DA68106C64 + 11: C5B6E04AB8B9491E6A99F8, 143515779A55C972 + 12: 33F493AB7AE62DADA38C5B24, 531BF7799A778620 + 13: 6DAA66BF02E66DF8C0B6C1CC24, 6CDF72786C5EC761 + 14: 4940E22F083A0F3EC01B3D468928, 185EE9CD2D7521AB + 15: 5D100BF55708147A9537C7DB6E42A6, 78984C682124E904 + 16: 744033532DDB372BA4AFADEA1959251E, 438EB9F6B939844C + +OCB-rc5 (8 byte key) + 0: , E7462C3C0C95A73E + 1: C5, 83CB00E780937259 + 2: 1533, 022FF70566E0BA87 + 3: 57543B, AC4EF15FC83BDF2D + 4: 01E4474B, BD817C06AC2141E0 + 5: 4CD7E850EE, 7BB6B3BDA5373422 + 6: 489C0CD1502A, 23DD4406F87EB164 + 7: 0CBAAE08E07EFF, 92569C958B722413 + 8: 073612F283F8A6E4, 1DD978D01CE8D1DF + 9: CDE676B1A3AC98B00E, C033F099E2620668 + 10: AD3BC88EEEDA40A83685, 36DA44E13C0C8A4D + 11: CA60E8B918F73E99986021, 45634CA0E43E4B13 + 12: 3B3CF82157ECEACAD8658EF5, E681F57616146CC7 + 13: EBC1A7068346EC1B7EB815A7DC, 2C806D2A909CCAF1 + 14: 97CDB3EF8276F1E7D6B6677DA2DB, 53F00B9A2E43DE08 + 15: 44169B3EDAD9506C51A6DA055EF9C2, 5BB6DD996130896B + 16: 35EC29065B1FC640015B0F779E7A358A, 867EBD0E86823F09 + +OCB-rc6 (16 byte key) + 0: , 27B9E3F544B8F567EEBF98ED5FD55C76 + 1: 92, 219FD2D74D7E3F21AA6C2A507C0A546B + 2: BECF, 96A656A16FB3C4579E6955D592AECAE1 + 3: 4DDE09, 7D1882879B5D6FD8C151502BD8AB220A + 4: 0D6B4FCC, E01FBD1ECA2A6A8DC6697A06AB12BDB0 + 5: E5E19C973B, E5A86AADF2F333D5DEDCE410688CC6A4 + 6: 90BA7D2A6965, 80523A2CAB2A7BB2E90B121DE80F46A9 + 7: 6FE258148EC8D0, B7254B11276A77C5F99FE5EC91D81F57 + 8: D887080095DF8817, F3FB938068A01EF89DE0F1226C544362 + 9: D9823313289D597614, A547764EF20BD4B4B303882B64FAF2C5 + 10: FF68942112CF01701E86, 94F3860D4438428EE296CEACB3EB67F5 + 11: FFD390D3E0B64F64D3192F, 99D2E424C67EBACCD4E2EB9A0CDB8CDD + 12: 3162235748BDDECC84FC8C94, BDD400A58AF59100A731DD5B4386444E + 13: D2A0EC8B1F20672289F7236C56, B245CF42644BDAC5F077143AF2A57BA7 + 14: 830929B2850E22F6C1BA2027248C, B6B522F7D6BA3CFFA92D093B383542FE + 15: 2A5FCCCCF43F845AA77750D3BC6B1E, 53A0A0882C7844636900509921661FCA + 16: 8480234796F9EAC313140CE014B0265C, 0656CA8D851B53FD5C1AAC303B264E43 + 17: F011A67C22F16A42CEA5E493CB766964AA, 830B8158B7A96224A53FB7F3A08CD128 + 18: F76274A730A608C2AB37497A049C3699882E, 4DC4DD4DF39D0E68D6169F9DC7F4A6D5 + 19: 7B38DD237DE552A72E4369A81C30AFEA5E5063, 01A62CBD30153702A5B29FB2A1683899 + 20: 58EB866F1FCB060ACC821D776AAC4AD9E87C326A, 25AFB8FC48605E1396EA8471F55C1294 + 21: A25F2C0FAD66B3580627498EC66C994B49C5445911, 0182A951D9A3DA53675612DE8EED1FB9 + 22: 8813977F092F07F251A1497C898967F3F98F5CB878CB, 80BC353E310880A83DD4DE4FE96AB6F0 + 23: 52DC8B76F5A6F78D51FB7DB51048E2663563335EC876A5, DC3689AA079C04C19D83646B272F9DEC + 24: 965437D3FDF91784B63C73C8CD001BD9372167963DF36B89, 9FF84E2845E3C1E3E6711D1646B18F21 + 25: ADD40F674BD56FFC8F9B4047FAAD2471F0A48F4544C894F806, 9D684F74F9734F1C497E33D96A27E00C + 26: 7B049B688839BC62785082397DEC7AA94B837D094AECA4B14571, EE711DF1C15B5C9E36B6E38B6F7152D2 + 27: DD4681F9C498A3CF69A9AC876E02BD9CDC4FB1F6798F772013B62D, C5A50676EFAA2A56CBDBE55CFED3050D + 28: 471B5E89A1337E75E88AFBAACA1C011790F1657425483229E55C34EE, 20F73F2AC452FFEA423BE2EBDF33CFA1 + 29: 71812C83DE34DB329C8DCD98890AFB1F7719E890DAE5CEB7AC9668CAD0, 6FAA03E10C6FB67D425C683C6D85FD76 + 30: 4BC2DB33786CFD29B5CA5B804454169906138E90E29E7BE9197971027AF7, 75053C433EF5572A70C58EEC96F56C53 + 31: 5E3A0AB41264AB65365458ED3B7E6A25827E50075A9E347F1622ED0723E229, C8F1ECD19AD5FC970CF0D31BF46B0F2B + 32: 2E48DEE4B379CD59F5367D17DC397C1BFD53B8C4CE46A8202518614076174EB6, EFCE758ECCB6BE875D16B7E03A498D31 + +OCB-safer+ (16 byte key) + 0: , 88618DEF98FE588E23107E9A5D89C26B + 1: 39, 2B01B202E751F957E331ECD1CEDE3456 + 2: 13CB, 17071E5AFD5D8CE953A73F49412BE8C4 + 3: DC4428, 4B0B1881C2540FF92E7DE63C479A7750 + 4: 120382B0, 0BB11D57B5BD9D846CF31033CD4CCB92 + 5: 97F332F95B, 335E0424D0A820F60DBB968B8B5AA057 + 6: 3C7AAE72037B, C8034C2C76C1CCD7C1B3F36DD8907E1D + 7: 8A99E4A1B89B6D, 06A8165DFADF1EA5ABD89E574422DF7F + 8: 676587065F0342B8, 93ADE63994DF2189079234DC204BF92B + 9: 8EC394CBC6877B245A, 1A89F0AB0B44BC708EBD9DE489E2EEB8 + 10: 5FB5366E5CAE4DB72411, 5CA5881A5805D53ACA4904A5EEC01550 + 11: 72A1994028F09ED6A4E45C, 0FFC0052996CE45DF4A28F7A6E9CFEA6 + 12: 1D5EF20F52A9B72386D1A601, A697DF1179628DE1120D5E8D9F39DA6E + 13: 79BD002AA59D74F125AD9E32DE, 2F02CB6F70BF57BBA0DF100DE503F633 + 14: 442C6F9016DF4C090056258756A9, 58C6FD3180B9B74459D70B5684BE3F4C + 15: 4FC5543D9A892B44ED04EE8B25E232, B8B858B3D3EB4B26E867E429F88A56B4 + 16: F06E7503167C2210AB332259BAFD6AB4, 73CE2589D1DF34CA3DC2B14CC9FA6276 + 17: BCCC260BD4823B64090FB33E6816F9C330, 81ABBDC83B2544907840FEB5AF4479EC + 18: 450C1105B76F960D1A5F33D7F9D37DAE20C3, C41DDC8980E88E3986D9C84857BBE1E7 + 19: C9F36EF3A990E0554EDB59E6788F8E9BF1DBC7, 90DD543E148D9A0B79A8B376C5509E09 + 20: 3666FEEA98A4FC434EDB7517E7FCEE2320C69BCB, 99F11B360DDB3A15C42110831CCBF21C + 21: 126F39C19D1E0B87F1180F6589A75712B66209E2CE, B4D268FB8EF5C048CA9A35337D57828A + 22: C1B6D14EE8B6D0A653BFCC295D5F94E6BCA09E181D8A, 4B4883B614D5CC412B53ED4203EA93B7 + 23: D1F2A10F1A9DAB738C61CD0EF66FE5F6D1DA95DC671128, 3F1EFDA55EFEF1A0B24708E132BC4D25 + 24: 9D457216C584F43DBA1DD55C54822A8B6A86D22DBFFA14D4, 53402970B128E98A5F0D62476A38F959 + 25: 012828614B5D67C9A1EE24A1EBCD322FE9C8BE0C3F20A53714, 2BFF288D90DBDC638084F80F3F7AADF3 + 26: B1904AECF599F6C74557475E409E75E646271DEDEC7A830260DB, BF119BDBDA27773E038B7067D2B0EECD + 27: ED831771C4346FC19435354AE29F7A9436D6E8D4D42CFF26207DBD, C3F029FC8AE690E84FBD0EF806B801F3 + 28: E051B958601223FECEADF932A277BCF18C25025AE4DA791155B85035, EB75E56BE7856F1B5ED3D125C092D38A + 29: AB3449537C5E22125BC32D483F74C3A3DBDBD5232839A85D300F65B4FD, 851B0FBABD080F783BDE4F47ADCD6D76 + 30: 4E68550837130652795A8C9D68530717D2B0AA5A17F3AEF92FFB502E46AC, 10E222706527A64E757EDE4B9EFC09DD + 31: C2D7033DA7A1857D79497EA6C64779EB969046CCEE6C74E6592FEE6E7C94C4, 2015674ECA80AC9B67AE854E18A7D56E + 32: 2F3F0374DDC24AE21F02D4DA74D46C71F0CD2269A68F32F7FAA0BAB64AA8E9BC, 737C8BA1677A8CE97D42FBB07530EE99 + +OCB-twofish (16 byte key) + 0: , 2CD8EF22E5457C7FE4016B0FB82FD204 + 1: 64, EB7BB60E4932C0E97A7A5906BD044ACF + 2: 3A59, E3D2024241666369BB542ED096F20C71 + 3: 67C038, 7E6F1EB3F2088F6416BB675DCAC0D484 + 4: BB36BF02, BDEEEF07EBB7A50A5201C8A2D72C0036 + 5: 6F06C0E293, C63557681D84ACCFFBFEE87D82EF1D3C + 6: 2015F94CC5AA, EF1DEAD4134D2A1A47A20F26FAA3554D + 7: A5F8CDD07964B0, 672B74D88C8AA7567C6AC4A896E0F6D1 + 8: 5EFC9D8C3B9E7F3F, DB9160C53AD429D4C22BC0E2E6C509C5 + 9: B62CB80F75594BC54F, 20020A798FF59F0472E750C796B5CC94 + 10: 970983B0F889760EEEF0, 360AE43CEBCC27755548D4984CEEA10C + 11: 75C3A8CCB30A94CD57D1F8, 79820F3B1625E216B5BC1D1A22B198F9 + 12: 033DA41CCBFE3C6897230FCE, CFE3EDD11627270CD63916508B058B7A + 13: 15358032F30043A66F49D3F76A, 98B8056A7991D5EF498E7C09DAC7B25D + 14: 71FBA7D6C2C8DC4A0E2773766F26, 22BA0ECEF19532554335D8F1A1C7DEFC + 15: BD761CD92C6F9FB651B38555CDFDC7, 8E3C7E1D8C4702B85C6FCD04184739E4 + 16: EB6D310E2B7F84C24872EC48BFAA6BD7, 12DE548D982A122716CEDF5B5D2176D9 + 17: 8DDF6CE25A67B409D3FB42A25C3AA7A842, 3E9FA2C6C65341A8E1101C15E1BBD936 + 18: 5563DFC29B750FBC647E427C5480B65846DB, 90881C6820901BD41F7B3C2DF529B8A9 + 19: 93343C1E9624321C2A0A155BA8B4E66FD92BE2, 71A641DDCD49825E10880D54BEF30E91 + 20: C256BCA0CF0ACCEEC1AA4B9372AF27D2C3C65AFC, 91D45C4DA49BBAD1809A11F4041C7D09 + 21: 3DE69FDB72C93518A3E317F7B26C425EE3DD42DA7E, 85E37B3E8EC3AF476DB7819D739D07D5 + 22: 676AC7885C7C8FBE9862242FCCC46C181440EE49AE59, BCDB42B53AC4FDDF9C3BF8849AB96EEC + 23: D71B98B88F46CC47D90BB931564CDF0157F0ABCB5E6954, 289CD5799D9E49F36D70F67726A59610 + 24: 669C16DB9DC175200C08476832155DAA52F1F8969DF3B79A, 835B210EBBE5C9D34C2E052E1843C1F8 + 25: 2F39346E14A34BBED0491929CD9F1FB3CEC412C25AB703372A, DC4B42E8BA676BA100B87BEE328C5229 + 26: 1FD0F8BD0AC95E91881635EB0CF0E4FB099CBB214CE556422E2D, 898CEB3CA8FCA565CE5B01EF932FD391 + 27: 7FBD32B3D88B7E002BA6055585B5D0E1CC648315A81CFECA363CC8, 804820B1E3813D244164F778B9C2A8C8 + 28: 877A5F336A1D33AB94751A33E285C21666F0D8F103AC1187FC205372, AF9F0AC165EAFCEE8C2A831608F166B4 + 29: ECCA297705B0395E71B9E4263343D486B29207DA188C2F1BA626EDBF46, A05DC873406B236E4DDBC038DC4D2627 + 30: FF3BD8D4E1108E98FBAE2E28BC12819CD7956BC491C0B3A291FBEE739599, 68DFE58473BA2818A23095D1D6EC065C + 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1 + 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47 + +OCB-rc2 (8 byte key) + 0: , 1A073F25FF5690BE + 1: F4, 3D3221E92E40F634 + 2: 2C76, C22C20B7231A0DB9 + 3: C647CB, 3E6348D996399629 + 4: 2021891A, 8EF76B24E9D55FDA + 5: 1966CBCBBF, 310D24024D573E8D + 6: 42C15AC9AAF0, 217E83C0CDE4F077 + 7: AB70F3F73DF0B6, 16AB2679D96A591B + 8: B7C7DD845D7E76DD, F33065EA531545CA + 9: 468CC16A37CF63EA73, 88879733F70AE3D3 + 10: 4F769E25A7346E22A932, 26E1A92FEDEE0597 + 11: 304A8B53B1CD24C6C27C17, 48B46E9F091B0B2E + 12: 4E3DF867FEFF0B8E06D5FA70, 53BB48BFB8AB4750 + 13: 2BAB3F0A8C38A3BD3C49DBBA5A, 52303CADCBB6D312 + 14: 3D04A29924589AAEF93A29003EE7, 120EF9364B83748F + 15: 486127A80E4EC599C461451CF1D79B, 2245D51599CAD629 + 16: AF8FB3FD2DB343F1AFF564FCBEA58785, 805BF441E660B0B0 + +OCB-des (8 byte key) + 0: , 8A65BD7DE54082AD + 1: A8, 3A83897CC8EC7CF6 + 2: 9256, DC66C39C7DD87D93 + 3: C145A0, 45967F3764F62F48 + 4: CD314BAB, EF38B0213259C3D4 + 5: 7074014741, 6748F4BAF06DD7BD + 6: 9A874CAE01F1, E382DB7235624104 + 7: DFA0D86DC4CA84, 627ABB432E50455E + 8: 685C2B2CBDD8D144, D166082E085063BA + 9: 53515DAAC7F7B8CE1D, 6680B6C26E1B0994 + 10: 2B3967812BF4155A8D36, AFED7F38AFEFC543 + 11: F4E5AC3CC5913B8A7F35FB, 6181DD3C46A6C24F + 12: F3EC89AD4235287D53715A81, 12CC354833FE5BD8 + 13: 66D554AC2CA85C079F051B8459, 097F31088CFBA239 + 14: 8746061C26D72771A7586949A3E4, 6CEF3565D0E45C6B + 15: FB3BCC650B29F418930A467EA4FB73, 64D12723E100F08B + 16: DE1C27E9B3C391AF5DF403291F2C084A, 6BADE4638AE46BE2 + +OCB-3des (24 byte key) + 0: , 9CB7074F93CD37DD + 1: 4D, 51541A838A154E0B + 2: 5C77, 60E86F2F1F4C6F96 + 3: B3D2F0, 7D74A9E6A061457D + 4: B3556075, EAF7A89A07453460 + 5: 1B61CE7230, F90D18620E1AB877 + 6: 3987FEC8D0D7, B5EF04DEE2E528F9 + 7: EBD0A7EBEEFF3B, A72CA24DD77A5DDA + 8: 429FB38DDABF76D4, D0578484C37227C8 + 9: F8DF28BF5C4CD28B1B, 5E7C4DC8E694E3B4 + 10: 2BF436BBE063F7E830C2, 8D919637C973C71B + 11: ED21656C8878319F1B7D29, 8813280C1277DF26 + 12: F45F90980D38EDF5D0FEC926, F9619341E273A31F + 13: 52F2D3CACC294B141B35D73BBF, 7BBC3F1A0D38F61F + 14: 2E6DA0FB55962F79B8E890E8DD8D, 8060799DCAB802E4 + 15: D6F9A6B2420174C499F9FE91178784, D3AAF969ED2F7215 + 16: 4F1CF285B8748C4F8F4D201C06B343CA, 203A2692C077F1B5 + +OCB-cast5 (8 byte key) + 0: , 77E8002236021687 + 1: 52, D57DF1037B6A799D + 2: 31C9, 7E781759B057D695 + 3: 5C8324, 56965D6CB2C97C0C + 4: 17D99099, 7C52B5D09475F5D3 + 5: 400082C475, 3CA5CDB9B4A0FAE9 + 6: 4DF0E4000C24, DCFEE2C3384F9731 + 7: 10004C3CE32255, 0A6832F985F61658 + 8: FFA6EA76B346893C, 6202693B153254D6 + 9: E96378C94D246AB51C, 5B259FEB715B9159 + 10: A9BED2D59A92D3D9418A, 1E7E066C098A023D + 11: 4EF144B7D4622BAD4DC840, 5DAB2C1D0DF56B08 + 12: 6DBCDF56E57CE47DD3D0CF44, 2A24F2A224368F55 + 13: 43241A0AD933635D7C8EAD47DC, 86B4B5AC22177F19 + 14: 920D6BDBE073F3C75052420C883D, 10943DBB23BD894D + 15: B2C75DF024269833B039CAB19EC865, 84B7DBB425E45855 + 16: 6A9424B6A873BB7155C01DC87E23EC52, 82C5047655952B01 + +OCB-noekeon (16 byte key) + 0: , 72751E743D0B7A07EFB23444F1492DDC + 1: 61, 41BDE9478A47B2B612A23752B5A42915 + 2: F4EB, 90EF542D89F867CDFB1A0807F8AA3CC6 + 3: F5A59B, 1BED873B613096546D4C201347CC3858 + 4: F454610B, FB4035F28AA75221F599668ABBE21782 + 5: 382FC932F1, B40270E2084E8DCEB14C6603D080D7C2 + 6: 18F921441119, 47F1F889B307298150750E81E94AB360 + 7: EF01C70C9D1810, AE0439DBB3825F27CF846B43E4C3AA80 + 8: 89863EDCAD471C3A, F4E8AF73BFC4CB79AECBBB3774DAF8C2 + 9: A6F494092E066A70F6, F73D3B04752B7D913420C17E656C7F86 + 10: 342459682E0A8D53AF4F, 61E7CF14E9878E0726C64B1E8CA08BFF + 11: 65E520D5A99825DE2441D1, 7A2AA740D786EB7015C61B31959E55D9 + 12: 2F96D0BB72E37DA202410302, 1A313242527FB522289094B9AFDB5F7B + 13: 3E8F8A1FCEE3F866EC29128BA0, B8065DA2DABF04129E5AE28ECC11A15B + 14: C2C15976D3C2499ACB9454878131, 372CAD486E104098EB1AA78A2922A1BE + 15: 1F12CADABAEE80E448B7EDCB42F8FE, 86A38DE5363787F55B16462C684E08DC + 16: 3B9ABB3304E75BF5B63E7F5B5A3F3980, 1FBD6B93E457B9779E2D12D78301EFA9 + 17: DC0CD805E43675A4317452E378AD48AC4C, 40AE4AFA4B3E580EFDB4AD0AF5BC4E4A + 18: E9DD52EA7264C6C7BBA39B761B6E87B65687, 4061DD65D5E7FFFE8D3D4261494D4F8C + 19: 80A9735CA1175072823828123413CCE772D521, D3378A12E79C49A37378DF527A460AB2 + 20: 09AD495AFFBF7CB8841262E7E5E8952878D4391A, C25D7A98C6F260B5FBCA3B8B5F7F33C1 + 21: 3925615707CC40C351D4A49794778545BC1F683175, 97622437A7208383A4A8D276D5551876 + 22: 5BB0D41ECD7BD2CF0B12A933255D95A3FE35E4C896BB, 4B8AD84EEA3156765A46AC19C68B6F88 + 23: 1EE71FE23CBFD5683AB1B391FC12B4E5952E4E6AA3D189, B0FD75996F28E071EB6C86BD7102BAA5 + 24: 0AA3D8C98AADEEE1867B13B017DD263BD16E960DA64FD071, 5204780963A62C2F4F7B3555BFF73836 + 25: 3A88B6F2AE321B226DA90B98E04A6A1589411BEDBE994632D5, 5638AF04EACF1EB986AC0702B4373A22 + 26: C2731661AC634A4DC0345F040DA7AEE507A3B9D019B5958543BA, 4C67D3FE37ABEE928B3BB812E7346823 + 27: D3E7651AA6DA035D05D599EFB806E8FD45177224593B5974758419, 5814E84258E1B9BD56A188AAE6F25138 + 28: 17818E7102B8C123230C5D64F18BE94C3159B85C8F7B64A7D4712CDA, FAA905B587A93DCF600BA8589A985432 + 29: BCA4335C6C29D978032C216114D39C01C6F161BF69D5A1CE55FBA8C575, BE24424A162E43A19755E2EFD274DBED + 30: 24C33CEE022F8A633DE9DFD009F535B52BCF64F390D2375E5BED65B70D08, 138F21D54B6B7E34628397DCDE0D33BF + 31: 838FE950C8165ADBBD6B61E9732F9A727CA7AE74376981382F0C531C331915, 0742E769CCBA2D1CAC7CAD4E0F012810 + 32: 57CD778DAD477271794FBF763662D97F8A10B17D70A69FDCB974FFE67E558519, 942C7D1C200C3845748F8131DF71AE26 + +OCB-skipjack (10 byte key) + 0: , 90EAAB5131AEB43B + 1: 2F, 6274B82063314006 + 2: DAF6, 6A6BCCE84FD4EF02 + 3: 5C2A88, C83D54C562A62852 + 4: B6E8FB5E, C44459EF41C8F296 + 5: 6C0888C119, 269DD7657BD0225F + 6: 1FD9AD7ECCC3, 3CA090F46B107839 + 7: 1EDBFF8AE458A3, 440380BF9745132B + 8: 04DBECC1F31F9F96, 2653620A4877B0E6 + 9: 908AE5648AF988A896, 00180FF33C1DD249 + 10: 53E63E0C297C1FC7859B, 36616209504C4230 + 11: 407BE16144187B4BEBD3A3, 4754B7DD4DB2927B + 12: 9961D87CFEDDF9CC22F2C806, 5947FC41E6B9CEC9 + 13: 9F5254962E4D210ED8AC301252, 97A392BEAF9B3B04 + 14: 379FDA76ECCFDAAC10F67FBF624C, 1D895ABD932BD5EC + 15: 1D5A7AD556FF3078284BB21A536DAA, 01FAE2F4936ED9D2 + 16: 4B8B71396924880CB33EA6EC6593F969, A0F4B1BE3B9B4CCE +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/omac_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,331 @@ +OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is +of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of +step N (repeated as required to fill the array). + +OMAC-aes (16 byte key) + 0: 97DD6E5A882CBD564C39AE7D1C5A31AA + 1: F69346EEB9A76553172FC20E9DB18C63 + 2: 996B17202E2EDEBD63F414DD5E84F3AF + 3: D00D7DA967A2873589A7496503B3DBAB + 4: B43C24C0A82DAA12D328395C2ABD7CAE + 5: 9B902B6663B5FEDC6F9DCE74B35B91F2 + 6: 06A9678C65D7CE225E082ECA31788335 + 7: 7D67866CDB313DF65DED113DB02D6362 + 8: 259E28CF3E578AC47A21A77BA9EA8261 + 9: 32F23C8F93EA301C6D3FE0840CA8DB4B + 10: C2B06388AD6F8C43D19FE4F6A8ED21AE + 11: FA8622485DB2F62F84FF46E532A1A141 + 12: F312D9B2E6272578F406B66C79F30A0E + 13: 7A5DE06B2BFB75ADA665E96F680AC098 + 14: C3B00380F0BD8E2F5C9DD9945E0F36EE + 15: DDD87974A5FB2E7A4514241E94526B5B + 16: AD24FC47A0FEA84C54696DE997A94F4B + 17: 7538713D8AA2AE3726307EFF087BBF5E + 18: 7619A52B4C34A98440812F5F28F8DC4F + 19: 7E797B8846554888622CC5E400B2FA44 + 20: 61E8DD3E09145F5657DB4B8F7BD2D7D8 + 21: FDAE2A3FE60DDF1871C2613A293AB6F1 + 22: A186D6EFD10DFFD2C088480B0A784185 + 23: 3119D337865618CDA55C06FB992427CF + 24: 413E3EAD7E3F169A37C49F9CA92E235E + 25: 37A55AF22373B9A1E2F8368B2FB992CA + 26: 4941F604C40EEEE1A16CFE073C12D1FE + 27: 3E8F4A0876BF12A2DCA87157F15DC884 + 28: 5DFAE292D8EEB13D8FE5725E5D169742 + 29: 59160455E0C0B35D950BA67C77F9FB05 + 30: 5AC0D736A06A7DD146B137ADEE78EE06 + 31: 0CA1178F28B953045EE76E2E760036CA + 32: 025616215F870D1EF838AD1D2AE0C649 + +OMAC-blowfish (8 byte key) + 0: 2CFB5DE451FFE8CC + 1: A5AC339DB44D020C + 2: A3CE0CF62249444D + 3: 3076B7129CE3F6A1 + 4: 9E091A637DDF70E3 + 5: 275199AB20A5F09C + 6: CDEDA8D16A401E62 + 7: FC980516CF5C9E30 + 8: 659D0B31D21B622B + 9: 8306847B5E72E018 + 10: 7AD029BBF1D2919F + 11: 133181425C6808C9 + 12: FC5AC60E367F413A + 13: E0DF8BCCF0AD01D9 + 14: AC5015398FA64A85 + 15: 1F068F22AFFECEE1 + 16: 8E6831D5370678EF + +OMAC-xtea (16 byte key) + 0: 4A0B6160602E6C69 + 1: 1B797D5E14237F21 + 2: 938300C83B99D0AC + 3: F989B99B3DE563C6 + 4: F65DEA2A6AD45D1E + 5: 1DB329F0239E162E + 6: C0C148C4EE8B4E1F + 7: D82B387D5DFFE1FB + 8: 1D027A4493898DF2 + 9: 196369F6B0AF971A + 10: 2A37A2655191D10A + 11: BD514BE32718EB4A + 12: B4DBC978F8EE74ED + 13: 8ACCAD35C3D436AE + 14: 73ABDC1956630C9B + 15: 73410D3D169373CE + 16: 23D797B3C7919374 + +OMAC-rc5 (8 byte key) + 0: E374E40562C3CB23 + 1: B46D83F69233E236 + 2: 7CB72B1D335F04B0 + 3: 94457CBC97B31328 + 4: 543D0EDFCDCD7C76 + 5: 5164EFA8412EAA5D + 6: 13CA0717EF95F9A7 + 7: 2AA49A7AA7719700 + 8: C9E7C56125C3D90F + 9: 2BE3E15FE58648AA + 10: 77D0B90372D6D0FD + 11: 17408F62ECD62F57 + 12: 7864EFFA59DC059B + 13: 3212E76E25E5DEA8 + 14: E2424C083CDE5A6A + 15: DE86FFDBDA65D138 + 16: 85482C24D61B8950 + +OMAC-rc6 (16 byte key) + 0: E103BD8BA47B7C1C010E1561712E6722 + 1: E51AEECFED3AF40443B3A1C011407736 + 2: FA6506C5ABE03381B045D28D1D828966 + 3: FAC4237FFE7772E2299D3D983BB130DD + 4: 3A7E24D41121A5D4F96FCECF0C2A4A10 + 5: AA44291E5500C1C8E1A14CB56E4F979A + 6: 4B8FDA6DA6B3266E39111F403C31754E + 7: 4DF5F1A1C8EBC7F56D0D12EEB63FF585 + 8: 46A6DDE419355EDE14D31045FCA1BA35 + 9: 71756D4D3DF59578B7F93FD4B5C08187 + 10: ADA292A19F8636A03A8BC58C26D65B0D + 11: 703190DAF17F8D08A67A11FDF0C2A622 + 12: D2B94CAD1AFC5CD012575964D1425BE6 + 13: 45FD0069FCA6F72E23E4DB41AA543091 + 14: 36F652600F5C9F226721400A7199E2BA + 15: E8CC6389ECF8EF1DBB90A0FD051B7570 + 16: 8125446B975DBDA742A903340D6B96C7 + 17: 00B55E4399EB930E592F507F896BF3DC + 18: 33E58F42A47C9543A851D6CA9324FEE0 + 19: 9F28FDEA3EC7F515128F5D0C0EB684C5 + 20: AC1DAF6C01AA28BCC0A819189FA949D7 + 21: D0532B5F54A179444D052A4D2AD6E4F9 + 22: 58B80A66549404C7B9F64D5AE3F798AB + 23: D0D6D586477F92311DDF667E0749D338 + 24: 0DFC0FAA67FF114398CE94D0688AE146 + 25: E163B8C00CF5CC9FA23ACACD62B53D64 + 26: ACE9270456AF9BD388BA72E98825CFE8 + 27: 4302EED9BAA19C7A296585E23A066A44 + 28: B3EEABEFAB25C7478419265564715387 + 29: 9F0630ADE9C74AB2981D63F3B69E85BF + 30: 1215A9446A275CCE2714F94F3C213BB7 + 31: AF43D7F748DE0E3458DB970BAC37E98D + 32: BF871AC9E892CE0DCD7C8C7ADDD854C6 + +OMAC-safer+ (16 byte key) + 0: A2C8C7FEA5529D01C3FF4E9359EF74F4 + 1: EAB87021118FF24FE79B69ABCCB14A8F + 2: 789566F467BAA68F4CC3C4B61901D6D4 + 3: 369F41EEAF7D628F9E0D77BE43BFC1D2 + 4: DC46A20E1F36F45006ED5B43BEC20DA6 + 5: 8F150CE34F57BBA2E6CE3431B78E4ACD + 6: 61CD154478BE20F33B26CD8FC58091A5 + 7: 4E6DAA575CF28F1F48B256262B7D558C + 8: D21FA4F1859571DB91E92767C5487AA2 + 9: E3D009DC7E71FBBB030B8FF0B544A2C9 + 10: 094C236EA48ABF7DBAE5A88AA3DE07D7 + 11: 00C401996F8224359566660AC1CEDAA1 + 12: D580EC60F712558D875F01643D96653F + 13: 8482298027C7B4D5969787A1DB1B1F2F + 14: AB726AE3DA95CB242E63EF876A4BC446 + 15: D668ED4919003F5E45590663FAED41DA + 16: E4CFFD7E0E7B176867C386001849FD6F + 17: 37B3C6DEFC5573879006D15F982A397C + 18: 0AB8847EE6A41A0E960080EF0D1BF1C5 + 19: 2C94FCA2A685F276A65ED286AE12FD9F + 20: 23383032032D7B5165A31ECA156DBD23 + 21: E1EECFB3D671DF694FFB05AE4305AD4C + 22: A0F6CA99B96CD1EDD04C52828C8A4D74 + 23: 12D6B7053417AF3E407EFD6EE1CC38FE + 24: A566D1C39AE7A1A0A77D5A1F56C5FAAB + 25: 81C9FAECEAEA326140AFCD569668F669 + 26: 6A00BF1D0DC893868378E4347CB4A1B9 + 27: 98842956DBE7AFB1BF49C46497BD54C7 + 28: 88EFCD5A1644B75BB0B3F5DD338849CE + 29: 77EC62C278C61163B1BEC595A11F047A + 30: 147424E817DC69413CC657E0CB292F7F + 31: A2946CBB910743EF62D8A3C7391B9B9B + 32: 00EEDA55520B8A5B88B76487E80EB6E1 + +OMAC-twofish (16 byte key) + 0: 0158EB365FCCFDD94EBA6BE42B6659C4 + 1: 17DA580917D147D10CB73DB6800B0E59 + 2: 3F185CC15EF3328D3E075665308C07C8 + 3: 5712A97ACC9D08FE9D2087D0CA16B0AD + 4: 90425A8CC1C026DDD896FC2131AF654B + 5: 30A43D4FEAE71F5396308C16DA081B4A + 6: 6839FEF605704D49F1A379A9E9595E6F + 7: 56A8F06DFEE543971B351B07430E2026 + 8: 36DD0E4B55C5314F9F2753D7EB6F0849 + 9: 8E319249A3CD456460F410F518F8CEDB + 10: 463978BE2A063C22E71DC71520723517 + 11: 1B735E45FD3DF636E0A6104D4A2E9CB8 + 12: 628A82213148AD9791153D5AAFBDDFDC + 13: 21AFDF08A36ADB6659B656C8EA0800E5 + 14: E5C3E58803DDBE174E0D4C2B8171AEF0 + 15: FC6981F2B4359BA05988D61822C0FA88 + 16: 7B03498FAFB04A6542248852225F9DAE + 17: 9B173E91E59A940186E57BB867B8307B + 18: 470BF2EE614C8423AA3FDF323F1C103E + 19: 6E664AFDFD8306547BBEDA036D267B79 + 20: F61AEC1144C3DD646169E16073700AC6 + 21: AE503B139707AFA494F7F2DE933EE81A + 22: A0A8BDD4ED0DCAE4A8E1DCEE56368FF0 + 23: 460B8207930DA434AE6AFECC305D9A26 + 24: 7F03F8C7BA5365CC65F7864A42693BC8 + 25: 31448849D6190484192F29A221700011 + 26: BDA941019C75551D858F70FB1362EB23 + 27: 2880CB3E62447AE8EACA76C17971BB18 + 28: FC8D710FA3990B56357E61C2A302EB84 + 29: 793CD15348D7DFF301C47BC6E6235E22 + 30: 6FB0CE69A15A3B6A933324A480077D35 + 31: C24FCA5DD4AE0DF2BFF17364D17D6743 + 32: DC6738080478AF9AF7CA833295031E06 + +OMAC-rc2 (8 byte key) + 0: F001FE9BBC3A97B0 + 1: 8F8DC9C952897FBD + 2: EC82EAD195AAC38C + 3: 53DD52269B19E9A4 + 4: 9B86F64BF72A0647 + 5: 664A88A29F2898C6 + 6: AFEC3F71C1415666 + 7: 9BA1F2C1A2E765F9 + 8: 402A12120908B436 + 9: 03ECCD4C6AF44144 + 10: E8CA3529B5D9D6FC + 11: 951EE10779CC585D + 12: B9083CA88E7E819B + 13: AFFB9E884DACC5B7 + 14: E942E8BC241343D6 + 15: 9B190489091344FB + 16: 9330A9E05554A15A + +OMAC-des (8 byte key) + 0: C9085E99D74DF01D + 1: FAC84F0EFBEF8630 + 2: C37C5FECE671CF16 + 3: 45B2CBEE8701A5B1 + 4: 53665E1F024EB001 + 5: 357123CEDFC9FF61 + 6: BD2CFD33FB1F832B + 7: 1AAA9D8C9120BDBF + 8: EB9F589AE9D4E78F + 9: C8F9D2ACE691922D + 10: 81ED6F3611DDC0FD + 11: 2965ABEAC46839EE + 12: 2208B1E095F7AE2E + 13: C0414FE41800113E + 14: 653A24119CF43D97 + 15: 7FB7CE0862958B37 + 16: 55097816B10C549B + +OMAC-3des (24 byte key) + 0: 7F07A9EA8ECEDF9E + 1: 4E2A652EB5FBF5F8 + 2: 4F84E3779ACCB9F5 + 3: 7134AB3463115DC6 + 4: 82327BE8EA2D7E0B + 5: 24950B9C14D87CD9 + 6: B25A097BB7E0E18A + 7: ED51BAE55ED925E7 + 8: 56B79E7644556975 + 9: A65BD98E4D4E31E2 + 10: 11145BB51514482D + 11: 397486787E676BA6 + 12: BD1F6DEBAF6D9AEF + 13: 5CC3921F7DB815CF + 14: B0C0E60DA5F727F3 + 15: F8637AEEFF10F470 + 16: 0EA19531D42706EA + +OMAC-cast5 (8 byte key) + 0: 7413DCDB9F0C3100 + 1: 423799EDF1472B79 + 2: 03856F0CB4F11606 + 3: F152AE6360813DE0 + 4: 853998BD980AD146 + 5: AE6C3D667DB8B414 + 6: B5A4986A34BDE20F + 7: E5ABE5B979798942 + 8: BEE8DFED4555F405 + 9: 6B5339E952AF61BE + 10: 5E867CF34D9C1149 + 11: F9C55CB3BC655E08 + 12: EA09A2929AC7D915 + 13: CE8EB0E4370E1933 + 14: 749A424B2AA91B98 + 15: 8DDA93C2B814D5D1 + 16: E8B0B219D4CB699B + +OMAC-noekeon (16 byte key) + 0: EC61647B281C47C1B43F9815064BF953 + 1: B100B1B6CD96DCED8F47A77E70670A92 + 2: A96CDE3C48831A6B0A5ADFECA6399BDB + 3: 14E75E7CAD840208834918B29A5D4430 + 4: 9577083713AE6E44EEC987C77C93C072 + 5: 2A738C02841E461238C02F5CFC8E66A6 + 6: A901327E451BE0D2D9DEC83DEEA9A022 + 7: 5ED7EE1BE04A64A689D15F6970A821A6 + 8: BA053E24FCFD02C731A8CFCA19EE66A0 + 9: 57139CA8C91072555B29F85A19E2C84D + 10: 4585EAC7EFB84869FD96EE7A5FDD350B + 11: 62AF6C415CA73E54E82EA306254C1BDE + 12: 75304F9724BD364F84371EE154F5210E + 13: 7FE5DBCEE826760434745D417453182B + 14: EC98DA2A580E9131218D1CDE835423D4 + 15: 631BD9EAFD1AE445F2C1C35E2B4416ED + 16: CA2D902A1D83388FE35BAB7C29F359BA + 17: 0DBF0AF7FCBEEE21FB6159C0A2FFCD4C + 18: BD7CD2C49241032DA33B1975EE2EE982 + 19: B30B090EE8626D77D310EDB957552D46 + 20: 64F608AC5707C381AC6878AA38345144 + 21: 28513CA7795B23A02B37DC3732413D23 + 22: 9F440700094517847E9E013C8915C433 + 23: 8CA483F313D20BFE7E0C089DAA4145BD + 24: FA44872743E20E5E0A069B3C4578DB50 + 25: F6DE8FFBECD52CC1F213CD9E406DF3BC + 26: B9702B7E846735A3DCC0724255F88FEC + 27: A1DDAFED2B1732C7BA89C2F194AF039E + 28: 2549C5F0E30F8F4002431D2C098805B8 + 29: 52E3836181BF5C9B09A507D5330CD14F + 30: 01C55DCBCCFD9D7A4D27BDE2A89AA8EF + 31: 3CF721A0CF006702CDA91F2FF3E4D5E3 + 32: 6D264B9065BE98C170E68E9D2A4DE86E + +OMAC-skipjack (10 byte key) + 0: 84EDFA769040603C + 1: 7DA58A4CBD642627 + 2: 118F60115CFC8229 + 3: A7F7346D34DB2F0E + 4: 35615CCD526CD57F + 5: DE471601A3660844 + 6: 15FCCE6D6D883D1F + 7: C6F694861233151B + 8: 3B762B397F16E807 + 9: 976C6AB59FB3AB12 + 10: 6810791F2C595961 + 11: 7FA3478286917F17 + 12: 73DEE44A51C6B610 + 13: 89EE8B253B1ACE81 + 14: CDF2586A56C8A0B5 + 15: ED91F98DA98F42C4 + 16: D8D0FA5CE96B08BF +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/pmac_tv.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,331 @@ +PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is +of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of +step N (repeated as required to fill the array). + +PMAC-aes (16 byte key) + 0: 4399572CD6EA5341B8D35876A7098AF7 + 1: 580F7AA4AA45857C79BA2FB892228893 + 2: 24D2D1DBABDB25F9F2D391BB61F4204A + 3: 083BF95E310B42A89751BC8E65ABA8B5 + 4: 69BEB9268CD7FD3D7AB820BD7E226955 + 5: FD71B0E647ADB4BB3F587E82B8B3401A + 6: 07EA46271081840737CEB1AC9E5E22E3 + 7: FFA12AD9A9FDB5EE126084F82B381B10 + 8: 8A11AF301AAFEAC8A75984ED16BB3292 + 9: 368BDC3F4220E89B54C5F9D09FFB8F34 + 10: 8B6DBFF776FD526147D1C4655626374F + 11: C538C09FC10DF38217CD8E799D8D1DC9 + 12: FC1264A2051DEF73339432EA39443CFD + 13: 8AF37ED2FB2E8E30E9C4B75C1F1363E1 + 14: 4295541FC62F6774068B8194CC9D9A46 + 15: CFAF4D8EA09BB342F07131344DB0AA52 + 16: B6CBD6E95959B2A8E22DE07E38B64D8D + 17: 3124E42DE3273B0F4806FB72A50F3E54 + 18: 252D49403509B618AB3A6A1D99F9E9FA + 19: 9CDA75594CB696EB19C022DDA7324C10 + 20: 33BB8AE43B7BC179E85F157FA19607D0 + 21: 12FE91BCF2F2875379DC671C6F1B403E + 22: 416A3E519D1E406C92F8BB0DDBBBB6BF + 23: 6F98DCCD5A8D60DEAF612ACCEDD7E465 + 24: FFCE7604609B2C3C050921854C638B7E + 25: DD2BB10AA07A5EC8D326BB7BF8D407F4 + 26: 468BFE669FCDF354E4F9768FE1EAF8F6 + 27: 01724D2F2C61EB4F380852218212E892 + 28: 2D90EC658F57138505598C659C539A3E + 29: 6301EAA0E1500FFEB86752744EFFF23D + 30: 3CCB177486377616056D835F6F857F7C + 31: BFB3C7755C1F4543B516EB8610CB219F + 32: D5C505847D7CFFD8CED848F6CB613105 + +PMAC-blowfish (8 byte key) + 0: 3B7E4EFE92FA46AF + 1: 746840017C38C892 + 2: 3B6A92C731465B64 + 3: D89D3B05143B6704 + 4: 43F70D54B808B7CE + 5: 84E4063AB32F046C + 6: A7E78CD5CCD23805 + 7: A78FB083475FEF10 + 8: D4F6C26B5386BA25 + 9: 184768A079853C90 + 10: 0702E6C8140C5D3B + 11: 786D94565AA0DF4B + 12: F6D36D3A2F4FB2C1 + 13: 7BB3A0592E02B391 + 14: 5B575C77A470946B + 15: 686DAD633B5A8CC3 + 16: BDFE0C7F0254BAD5 + +PMAC-xtea (16 byte key) + 0: A7EF6BB667216DDA + 1: B039E53812C4ABDC + 2: 87D2F8EA5FB6864D + 3: F85E3F4C1D9F5EFC + 4: 4EB749D982FB5FE2 + 5: 0BFA0F172027441A + 6: FF82D01F36A6EC91 + 7: 3BC2AA2028EBBD7A + 8: 15AA03A97A971E2A + 9: C974691F5D66B835 + 10: 4FC7AA8F399A79ED + 11: 2633DA9E94673BAE + 12: 82A9FD48C5B60902 + 13: 31BF6DA9EE0CE7E4 + 14: 26B2538601B7620E + 15: D103F3C0B4579BE5 + 16: 031346BA20CD87BC + +PMAC-rc5 (8 byte key) + 0: C6B48F8DEC631F7C + 1: F7AA62C39972C358 + 2: 0E26EC105D99F417 + 3: 7D3C942798F20B8C + 4: 415CDA53E1DE3888 + 5: A314BA5BCA9A67AC + 6: 02A5D00A3E371326 + 7: E210F0A597A639E5 + 8: D4A15EED872B78A2 + 9: AC5F99886123F7DC + 10: 69AEB2478B58FFDF + 11: 8AB167DFC9EF7854 + 12: 945786A136B98E07 + 13: F3822AB46627CAB5 + 14: 23833793C3A83DA9 + 15: 70E6AB9E6734E5A6 + 16: 0705C312A4BB6EDE + +PMAC-rc6 (16 byte key) + 0: C7715A17012401DE248DC944DEEBD551 + 1: 5B804C6CCDF97BB28811C9ED24FE6157 + 2: 7528378C052F4346253CB0DFA3D251C7 + 3: 6DA86EE0B28606861B1A954D7429A93C + 4: B4DFF84C25937FB50EE79D4037323160 + 5: A60FD9BE5E1FF67EC9734776C8781096 + 6: 81D3F8EDC0A197DD3739EAE648F38580 + 7: 8BAF47F02120E898916D678DBD0C1641 + 8: 7A9EEC96F10B7CF557B61EF35BB55B08 + 9: B88C11221014F8AE048E56C427DF4A46 + 10: 4BBA8EED89F357861A265006816D9B04 + 11: 8497C1D55010A65ED8C3688B75A7CABF + 12: 95E1720C06A373CAD1A22F432F26BCCA + 13: A175FB732692831E96AFB587BC49E18C + 14: 54EBC04FCFD90302907BF77C4D8AC77C + 15: EA9F13EE5548CDF771C354527CDDA09B + 16: 4EDBCFD0E2E6B321530EB31B3E8C2FE4 + 17: F412304C1A5B9005CC3B7900A597DFB5 + 18: 3B9247C12BB25DF048BF5541E91E1A78 + 19: 39626488635D0A6224CD23C13B25AE8E + 20: 40305F5C2FCEF34E764E33EF635A3DC5 + 21: F84499804086033E85633A1EF9908617 + 22: C4D263CDC7E0969B8AC6FA9AD9D65CB8 + 23: 6137DC840E61EA6A288D017EFB9646FC + 24: 8619960428EB29B1D5390F40173C152F + 25: F0464509D0FBDBECEC9DFC57A820016D + 26: 630EED23E87059051E564194831BAEF6 + 27: 4B792B412458DC9411F281D5DD3A8DF6 + 28: F2349FA4418BC89853706B35A9F887BA + 29: FEAC41D48AEAB0955745DC2BE1E024D5 + 30: A67A135B4E6043CB7C9CAFBFA25D1828 + 31: EC12C9574BDE5B0001EE3895B53716E2 + 32: 44903C5737EE6B08FD7D7A3937CC840D + +PMAC-safer+ (16 byte key) + 0: E8603C78F9324E9D294DA13C1C6E6E9B + 1: 3F1178DFC2A10567D4BCC817D35D1E16 + 2: 27FE01F90E09237B4B888746199908EE + 3: 4F5172E3D8A58CD775CD480D85E70835 + 4: 74BED75EFAAB3E8AA0027D6730318521 + 5: 54B003AB0BE29B7C69F7C7494E4E9623 + 6: 8A2DAD967747AEA24670141B52494E2F + 7: 69EB054A24EE814E1FB7E78395339781 + 8: E59C2D16B76B700DC62093F0A7F716CC + 9: AB227D6303007FD2001D0B6A9E2BFEB7 + 10: AE107117D9457A1166C6DFD27A819B44 + 11: F84DE551B480CED350458851BAE20541 + 12: B0EB5103E7559B967D06A081665421E0 + 13: CDB14F3AD1170CE8C6091947BE89DE7B + 14: 24FA2F476407094152D528FCF124E438 + 15: 440144B31EC09BD8791BFE02E24EA170 + 16: 697D268A46E8B33CEC0BAB8CAF43F52D + 17: 587CBDE7608449BD162184020FBFCC8D + 18: 3EA999C2169CC65735737F50FCD7956B + 19: C6D692698CD8BEEBF2387C6A35A261B0 + 20: 46DAB3AD3C4E2EF712FAC38F846C63E1 + 21: 7261E68B530D10DDC9AD4C9AB5D95693 + 22: 4D0BA5773E988C2B7B2302BBA0A9D368 + 23: 8617154626362736698613151D1FD03A + 24: 23CF25F68B281E21777DC409FE3B774A + 25: CA626956C97DC4207D968A8CC85940B8 + 26: 24C39BE160BDBB753513F949C238014E + 27: 83CD65C010FB69A77EEDEA022A650530 + 28: 1A72DC8438B927464125C0DFEACDE75D + 29: 546054936A2CB5BFBB5E25FFD07C9B51 + 30: 0EB81A268F1BB91997CB9809D7F9F2AD + 31: 7D08B4DE960CADC483D55745BB4B2C17 + 32: FD45061D378A31D0186598B088F6261B + +PMAC-twofish (16 byte key) + 0: D2D40F078CEDC1A330279CB71B0FF12B + 1: D1C1E80FD5F38212C3527DA3797DA71D + 2: 071118A5A87F637D627E27CB581AD58C + 3: C8CFA166A9B300F720590382CE503B94 + 4: 3965342C5A6AC5F7B0A40DC3B89ED4EB + 5: 6830AB8969796682C3705E368B2BDF74 + 6: FF4DCC4D16B71AFEEA405D0097AD6B89 + 7: ADB77760B079C010889F79AA02190D70 + 8: 5F2FCD6AA2A22CEECAA4671EE0403B88 + 9: 70DD6D396330904A0A03E19046F4C0BF + 10: 8A2C9D88FA0303123275C704445A7F47 + 11: BA0B2F6D029DCD72566821AB884A8427 + 12: C8DF45FF13D7A2E4CFE1546279172300 + 13: 512659AD40DC2B9D31D299A1B00B3DAD + 14: A8A0E99D2E231180949FC4DFB4B79ED4 + 15: CA161AFB2BC7D891AAE268D167897EF2 + 16: D6C19BBDFFC5822663B604B1F836D8BD + 17: 4BF115F409A41A26E89C8D758BBF5F68 + 18: 02E3196D888D5A8DE818DBCBAD6E6DC7 + 19: 995C9DD698EC711A73BD41CAAE8EB633 + 20: A031857FADC8C8AFEABF14EF663A712D + 21: 124695C9A8132618B10E9800A4EFACC5 + 22: 997E5E41798648B8CE0C398EF9135A2C + 23: 42C92154B71FB4E133F8F5B2A2007AB2 + 24: 945DC568188D036AC91051A11AC92BBF + 25: D5A860CC4C3087E9F4988B25D1F7FAAE + 26: 6CD6ABF8EDF3102659AFFBE476E2CBE8 + 27: 45ECD0C37091414E28153AA5AFA3E0B2 + 28: CBA6FE296DDE36FE689C65667F67A038 + 29: C4022281633F2FC438625540B2EE4EB8 + 30: 864E27045F9CC79B5377FDF80A6199CF + 31: 0D06F2FAEC5AA404A4087AAEBC4DBB36 + 32: 0F396FE9E3D9D74D17EB7A0BF603AB51 + +PMAC-rc2 (8 byte key) + 0: E5AF80FAC4580444 + 1: 6A15D6211EB4FF99 + 2: DDB95E9486C4B034 + 3: 9764761DC2AAD5C0 + 4: 1B1CD2E799D44B4F + 5: 4F80FE32256CF2EC + 6: 7B70CF31C81CD384 + 7: 9BC10DD9332CF3BB + 8: 628189801879FDD8 + 9: 5FC17C555E2AE28B + 10: E20E68327ABEAC32 + 11: 5D375CA59E7E2A7C + 12: A9F4CFC684113161 + 13: 3A0E069940DDD13C + 14: EAC25B6351941674 + 15: CB8B5CF885D838CF + 16: DCBCDDFC06D3DB9A + +PMAC-des (8 byte key) + 0: 086A2A7CFC08E28E + 1: F66A1FB75AF18EC9 + 2: B58561DE2BEB96DF + 3: 9C50856F571B3167 + 4: 6CC645BF3FB00754 + 5: 0E4BEE62B2972C5A + 6: D2215E451649F11F + 7: E83DDC61D12F3995 + 8: 155B20BDA899D2CF + 9: 2567071973052B1D + 10: DB9C20237A2D8575 + 11: DAF4041E5674A48C + 12: 552DB7A627E8ECC4 + 13: 1E8B7F823488DEC0 + 14: 84AA15713793B25D + 15: FCE22E6CAD528B49 + 16: 993884FB9B3FB620 + +PMAC-3des (24 byte key) + 0: E42CCBC9C9457DF6 + 1: FE766F7930557708 + 2: B9011E8AF7CD1E16 + 3: 5AE38B037BEA850B + 4: A6B2C586E1875116 + 5: BF8BA4F1D53A4473 + 6: 3EB4A079E4E39AD5 + 7: 80293018AC36EDBF + 8: CC3F5F62C2CEE93C + 9: EE6AA24CE39BE821 + 10: 487A6EAF915966EA + 11: D94AD6393DF44F00 + 12: F4BFCCC818B4E20D + 13: 2BE9BC57412591AA + 14: 7F7CC8D87F2CDAB7 + 15: B13BFD07E7A202CB + 16: 58A6931335B4B2C2 + +PMAC-cast5 (8 byte key) + 0: 0654F2F4BC1F7470 + 1: 3F725B162A1C8E6B + 2: BCFBDC680A20F379 + 3: 027922705BCACDEE + 4: 44E2F4BE59774BA4 + 5: 3ABD1AFC8EE291F7 + 6: D96347E717921E96 + 7: 96257299FCE55BC6 + 8: C2C1DA176EE98170 + 9: FD415C122E604589 + 10: DCBCA228D45AEDA4 + 11: 7801FBCFAAB9DF75 + 12: D38CB38574474B7F + 13: F5C5A23FF3E80F37 + 14: 83FA4DAD55D092F5 + 15: BDC0A27EE0CB1657 + 16: 87D907CACA80A138 + +PMAC-noekeon (16 byte key) + 0: A1E4C84B5958726557DF0855B37AA551 + 1: 5DE20299CA919D3365B493D3D4895F92 + 2: AF7E70C336571A857F62A18649EDB197 + 3: C5F55CFE1AA119C352B64252AD246CBD + 4: FEF68A0CE08E8BA315B73B62F861824F + 5: 8321C2958DE4903DC12C42A8845ECC20 + 6: 370466D1324AECF1F5B42E0E01381613 + 7: 5CB900190F5CACBACFE5EAB0CC289D87 + 8: A13C043E6CAAA1E34601A93C497446A4 + 9: 865E11622A4CC8A9E1408E00F56C4543 + 10: 9DC42C26868374649BD17D69D025CA1B + 11: 37D33C11B433C91DA09925CA9E86757A + 12: 1373D769C270E7137C953AC0F8F37941 + 13: 7E81DEC583348B1E2F6267ECF82CB994 + 14: 505B6329338556518FF364CAA730F5E8 + 15: 0C085AEEB315968B0BDE904E8BBC6FD0 + 16: 5FED63259364BE7E5133FF0507DD2D4C + 17: F7EE5C80A99AAEADB49E7CC69BFFF679 + 18: 4388FA5E763A641130940EB705BEFD08 + 19: 1BC31CA79EBE1674CEBE01BC9988267B + 20: BE88961637EFFE2D6905D104FEDD51A4 + 21: 9C341004FB22AFCC496094E3207CA761 + 22: B9DAA3620E38FFC7C5D5E7D2D8FE3DE4 + 23: A38D2E571F037061B4400F1131FDBDEA + 24: 61DB71AE77A6EB47F2E9E14E8CBF2F4B + 25: 9903A072274CC048EF2C51493266D9ED + 26: 1EBEA421DD08859C17DDF39B20A82102 + 27: F425858618E1A86F4912E4714EFB9E75 + 28: 3B3D4EA07F7FE6DDFDD02D624ACDFC9F + 29: CEEE256591D701514EB17DF73B08A970 + 30: 5CC56D5D46120C530A23B6C511C685FC + 31: 68E484CE18BE28EADD0BBF23291B8237 + 32: ABD58A9CDF8AA68168A1A402074CF520 + +PMAC-skipjack (10 byte key) + 0: 9CD94B75BC43B647 + 1: B069ACB82B12BC7B + 2: 6DD40E71EB03E311 + 3: 74CBED61D77DBA7D + 4: DD1B7E0D181537FE + 5: ACB5B96FA0AD1786 + 6: B34E01EB2567D381 + 7: 9623DAADE57B9549 + 8: 8BA384BABB798344 + 9: B147AA9D5C5C67CF + 10: 0033C520F4C67523 + 11: 42DAC184BEABC3E5 + 12: 428029311004AEBB + 13: AC2BB1C0F0ED649B + 14: F7CAA9A3BF749C1A + 15: 2C5BD475AAC44C77 + 16: FEB892DA66D31A84 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/tech0001.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,73 @@ +Tech Note 0001 +How to Gather Entropy on Embedded Systems +Tom St Denis + +Introduction +------------ + +This tech note explains a relatively simple way to gather entropy for a PRNG (Yarrow in this case) in embedded systems +where there are few sources of entropy or physical sources. + +When trying to setup a secure random number generator a fresh source of random data (entropy) is required to ensure the +deterministic state of the PRNG is not known or predetermined with respect to an attacker. + +At the very least the system requires one timer and one source of un-timed interrupts. by "un-timed" I mean interrupts +that do not occur at regular intervals [e.g. joypad/keypad input, network packets, etc...]. + +First we shall begin by taking an overview of how the Yarrow PRNG works within libtomcrypt. At the heart of all +PRNGs is the "prng_state" data type. This is a union of structures that hold the PRNG state for the various prngs. The +first thing we require is a state... + + prng_state myPrng; + +Next we must initialize the state once to get the ball rolling + + if (yarrow_start(&myPrng) != CRYPT_OK) { + // error should never happen! + } + +At this point the PRNG is ready to accept fresh entropy which is added with + + int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) + +This function is **NOT** thread safe which will come under consideration later. To add entropy to our PRNG we must +call this function with fresh data as its sampled. Lets say we have a timer counter called "uTimer" which is a 32-bit +long and say a 32-bit joyPad state called "uPad". An example interrupt handler would look like + + void joypad_interrupt(...) { + unsigned char buf[8]; + + STORE32L(uTimer, buf); + STORE32L(uPad, buf+4) + if (yarrow_add_entropy(buf, 8, &myPrng) != CRYPT_OK) { + // this should never occur either unless you didn't call yarrow_start + } + + // handle interrupt + } + +In this snippet the timer count and state of the joypad are added together into the entropy pool. The timer is important +because with respect to the joypad it is a good source of entropy (on its own its not). For example, the probability of +the user pushing the up arrow is fairly high, but at a specific time is not. + +This method doesn't gather alot of entropy and has to be used to for quite a while. One way to speed it up is to tap +multiple sources. If you have a network adapter and other sources of events (keyboard, mouse, etc...) trapping their +data is ideal as well. Its important to gather the timer along with the event data. + +As mentioned the "yarrow_add_entropy()" function is not thread safe. If your system allows interrupt handlers to be +interrupted themselves then you could have trouble. One simple way is to detect when an interrupt is in progress and +simply not add entropy during the call (jump over the yarrow_add_entropy() call) + +Once you feel that there has been enough entropy added to the pool then within a single thread you can call + + int yarrow_ready(prng_state *prng) + +Now the PRNG is ready to read via the + + unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) + +It is a very good idea that once you call the yarrow_ready() function that you stop harvesting entropy in your interrupt +functions. This will free up alot of CPU time. Also one more final note. The yarrow_read() function is not thread +safe either. This means if you have multiple threads or processes that read from it you will have to add your own semaphores +around calls to it. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/tech0002.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,52 @@ +Tech Note 0002 +How to avoid non-intrusive timing attacks with online computations +Tom St Denis + +Introduction +------------ + +A timing attack is when an attacker can observe a side channel of the device (in this case time). In this tech note +we consider only non-intrusive timing attacks with respect to online computations. That is an attacker can +determine when a computation (such as a public key encryption) begins and ends but cannot observe the device +directly. This is specifically important for applications which transmit data via a public network. + +Consider a Diffie-Hellman encryption which requires the sender to make up a public key "y = g^x mod p". Libtomcrypt +uses the MPI bignum library to perform the operation. The time it takes to compute y is controlled by the number +of 1 bits in the exponent 'x'. To a large extent there will be the same number of squaring operations. "1" bits in +the exponent require the sender to perform a multiplication. This means to a certain extent an attacker can +determine not only the magnitude of 'x' but the number of one bits. With this information the attacker cannot directly +learn the key used. However, good cryptography mandates the close scrutiny of any practical side channel. + +Similar logic applies to the other various routines. Fortunately for this case there is a simple solution. First, +determine the maximum time the particular operation can require. For instance, on an Athlon 1.53Ghz XP processor a +DH-768 encryption requires roughly 50 milliseconds. Take that time and round it up. Now place a delay after the call. + +For example, + +void demo(void) { + clock_t t1; + + // get initial clock + t1 = clock(); + + // some PK function + + // now delay + while (clock() < (t1 + 100)); + + // transmit data... + +} + +This code has the effect of taking at least 100 ms always. In effect someone analyzing the traffic will see that the +operations always take a fixed amount of time. Since no two platforms are the same this type of fix has not been +incorporated into libtomcrypt (nor is it desired for many platforms). This requires on the developers part to profile +the code to determine the delays required. + +Note that this "quick" fix has no effect against an intrusive attacker. For example, power consumption will drop +significantly in the loop after the operation. However, this type of fix is more important to secure the user of the +application/device. For example, a user placing an order online won't try to cheat themselves by cracking open their +device and performing side-channel cryptanalysis. An attacker over a network might try to use the timing information +against the user. + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/notes/tech0003.txt Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,52 @@ +Tech Note 0003 +Minimizing Memory Usage +Tom St Denis + +Introduction +------------ + +For the most part the library can get by with around 20KB of stack and about 32KB of heap even if you use the +public key functions. If all you plan on using are the hashes and ciphers than only about 1KB of stack is required +and no heap. + +To save space all of the symmetric key scheduled keys are stored in a union called "symmetric_key". This means the +size of a symmetric_key is the size of the largest scheduled key. By removing the ciphers you don't use from +the build you can minimize the size of this structure. For instance, by removing both Twofish and Blowfish the +size reduces to 768 bytes from the 4,256 bytes it would have been (on a 32-bit platform). Or if you remove +Blowfish and use Twofish with TWOFISH_SMALL defined its still 768 bytes. Even at its largest the structure is only +4KB which is normally not a problem for any platform. + + +Cipher Name | Size of scheduled key (bytes) | +------------+-------------------------------| +Twofish | 4,256 | +Blowfish | 4,168 | +3DES | 768 | +SAFER+ | 532 | +Serpent | 528 | +Rijndael | 516 | +XTEA | 256 | +RC2 | 256 | +DES | 256 | +SAFER [#] | 217 | +RC5 | 204 | +Twofish [*] | 193 | +RC6 | 176 | +CAST5 | 132 | +Noekeon | 32 | +Skipjack | 10 | +------------+-------------------------------/ +Memory used per cipher on a 32-bit platform. + +[*] For Twofish with TWOFISH_SMALL defined +[#] For all 64-bit SAFER ciphers. + +Noekeon is a fairly fast cipher and uses very little memory. Ideally in low-ram platforms all other ciphers should be +left undefined and Noekeon should remain. While Noekeon is generally considered a secure block cipher (it is insecure +as a hash) CAST5 is perhaps a "runner-up" choice. CAST5 has been around longer (it is also known as CAST-128) and is +fairly fast as well. + +You can easily accomplish this via the "config.pl" script. Simply answer "n" to all of the ciphers except the one you want +and then rebuild the library. [or you can hand edit mycrypt_custom.h] + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,58 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) +{ + unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; + int err, x; + + _ARGCHK(ocb != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* Get Z[i] value */ + ocb_shift_xor(ocb, Z); + + /* xor ct in, encrypt, xor Z out */ + for (x = 0; x < ocb->block_len; x++) { + tmp[x] = ct[x] ^ Z[x]; + } + cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key); + for (x = 0; x < ocb->block_len; x++) { + pt[x] ^= Z[x]; + } + + /* compute checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= pt[x]; + } + + +#ifdef CLEAN_STACK + zeromem(Z, sizeof(Z)); + zeromem(tmp, sizeof(tmp)); +#endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_decrypt_verify_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *res) +{ + int err; + ocb_state ocb; + + + _ARGCHK(key != NULL); + _ARGCHK(nonce != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(res != NULL); + + if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { + return err; + } + + while (ctlen > (unsigned long)ocb.block_len) { + if ((err = ocb_decrypt(&ocb, ct, pt)) != CRYPT_OK) { + return err; + } + ctlen -= ocb.block_len; + pt += ocb.block_len; + ct += ocb.block_len; + } + + return ocb_done_decrypt(&ocb, ct, ctlen, pt, tag, taglen, res); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_done_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *res) +{ + int err; + unsigned char tagbuf[MAXBLOCKSIZE]; + unsigned long tagbuflen; + + _ARGCHK(ocb != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(res != NULL); + + *res = 0; + + tagbuflen = sizeof(tagbuf); + if ((err = __ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) { + return err; + } + + if (taglen <= tagbuflen && memcmp(tagbuf, tag, taglen) == 0) { + *res = 1; + } + +#ifdef CLEAN_STACK + zeromem(tagbuf, sizeof(tagbuf)); +#endif + + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_done_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen) +{ + _ARGCHK(ocb != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(taglen != NULL); + return __ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0); +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,56 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) +{ + unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; + int err, x; + + _ARGCHK(ocb != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* compute checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= pt[x]; + } + + /* Get Z[i] value */ + ocb_shift_xor(ocb, Z); + + /* xor pt in, encrypt, xor Z out */ + for (x = 0; x < ocb->block_len; x++) { + tmp[x] = pt[x] ^ Z[x]; + } + cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key); + for (x = 0; x < ocb->block_len; x++) { + ct[x] ^= Z[x]; + } + +#ifdef CLEAN_STACK + zeromem(Z, sizeof(Z)); + zeromem(tmp, sizeof(tmp)); +#endif + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_encrypt_authenticate_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen) +{ + int err; + ocb_state ocb; + + _ARGCHK(key != NULL); + _ARGCHK(nonce != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(taglen != NULL); + + if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { + return err; + } + + while (ptlen > (unsigned long)ocb.block_len) { + if ((err = ocb_encrypt(&ocb, pt, ct)) != CRYPT_OK) { + return err; + } + ptlen -= ocb.block_len; + pt += ocb.block_len; + ct += ocb.block_len; + } + + return ocb_done_encrypt(&ocb, pt, ptlen, ct, tag, taglen); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_init.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,117 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce) +{ + int poly, x, y, m, err; + + _ARGCHK(ocb != NULL); + _ARGCHK(key != NULL); + _ARGCHK(nonce != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* determine which polys to use */ + ocb->block_len = cipher_descriptor[cipher].block_length; + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { + if (polys[poly].len == ocb->block_len) { + break; + } + } + if (polys[poly].len != ocb->block_len) { + return CRYPT_INVALID_ARG; + } + + /* schedule the key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* find L = E[0] */ + zeromem(ocb->L, ocb->block_len); + cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key); + + /* find R = E[N xor L] */ + for (x = 0; x < ocb->block_len; x++) { + ocb->R[x] = ocb->L[x] ^ nonce[x]; + } + cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key); + + /* find Ls[i] = L << i for i == 0..31 */ + memcpy(ocb->Ls[0], ocb->L, ocb->block_len); + for (x = 1; x < 32; x++) { + m = ocb->Ls[x-1][0] >> 7; + for (y = 0; y < ocb->block_len-1; y++) { + ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; + } + ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; + + if (m == 1) { + for (y = 0; y < ocb->block_len; y++) { + ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; + } + } + } + + /* find Lr = L / x */ + m = ocb->L[ocb->block_len-1] & 1; + + /* shift right */ + for (x = ocb->block_len - 1; x > 0; x--) { + ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; + } + ocb->Lr[0] = ocb->L[0] >> 1; + + if (m == 1) { + for (x = 0; x < ocb->block_len; x++) { + ocb->Lr[x] ^= polys[poly].poly_div[x]; + } + } + + /* set Li, checksum */ + zeromem(ocb->Li, ocb->block_len); + zeromem(ocb->checksum, ocb->block_len); + + /* set other params */ + ocb->block_index = 1; + ocb->cipher = cipher; + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_ntz.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_shift_xor.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z) +{ + int x, y; + y = ocb_ntz(ocb->block_index++); + for (x = 0; x < ocb->block_len; x++) { + ocb->Li[x] ^= ocb->Ls[y][x]; + Z[x] = ocb->Li[x] ^ ocb->R[x]; + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ocb_test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,226 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +int ocb_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + int ptlen; + unsigned char key[16], nonce[16], pt[34], ct[34], tag[16]; + } tests[] = { + + /* OCB-AES-128-0B */ +{ + 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0 }, + /* ct */ + { 0 }, + /* tag */ + { 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6, + 0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee }, +}, + + + /* OCB-AES-128-3B */ +{ + 3, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02 }, + /* ct */ + { 0xfc, 0xd3, 0x7d }, + /* tag */ + { 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a, + 0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba }, +}, + + /* OCB-AES-128-16B */ +{ + 16, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* ct */ + { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3, + 0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 }, + /* tag */ + { 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71, + 0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf }, +}, + + /* OCB-AES-128-20B */ +{ + 20, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0x70, 0x03, 0xeb, 0x55}, + /* tag */ + { 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77, + 0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb }, +}, + + /* OCB-AES-128-32B */ +{ + 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8, + 0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa }, + + /* tag */ + { 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c, + 0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf }, +}, + + /* OCB-AES-128-34B */ +{ + 34, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* nonce */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + /* pt */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 }, + /* ct */ + { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, + 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, + 0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa, + 0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f, + 0xa9, 0x5d }, + + /* tag */ + { 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf, + 0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab }, +}, + +}; + + int err, x, idx, res; + unsigned long len; + unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16, + tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) { + return err; + } + + if (memcmp(outtag, tests[x].tag, len) || memcmp(outct, tests[x].ct, tests[x].ptlen)) { +#if 0 + unsigned long y; + printf("\n\nFailure: \nCT:\n"); + for (y = 0; y < (unsigned long)tests[x].ptlen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen, + outct, tests[x].tag, len, &res)) != CRYPT_OK) { + return err; + } + if ((res != 1) || memcmp(tests[x].pt, outct, tests[x].ptlen)) { +#if 0 + unsigned long y; + printf("\n\nFailure-decrypt: \nPT:\n"); + for (y = 0; y < (unsigned long)tests[x].ptlen; ) { + printf("0x%02x", outct[y]); + if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); + if (!(++y % 8)) printf("\n"); + } + printf("\nres = %d\n\n", res); +#endif + } + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* OCB_MODE */ + + +/* some comments + + -- it's hard to seek + -- hard to stream [you can't emit ciphertext until full block] + -- The setup is somewhat complicated... +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofb_decrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,26 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef OFB + +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb) +{ + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ofb != NULL); + return ofb_encrypt(ct, pt, len, ofb); +} + + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofb_encrypt.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef OFB + +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ofb != NULL); + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || + ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (ofb->padlen == ofb->blocklen) { + cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key); + ofb->padlen = 0; + } + *ct++ = *pt++ ^ ofb->IV[ofb->padlen++]; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofb_start.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef OFB + +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* copy details */ + ofb->cipher = cipher; + ofb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < ofb->blocklen; x++) { + ofb->IV[x] = IV[x]; + } + + /* init the cipher */ + ofb->padlen = ofb->blocklen; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_done.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,66 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen) +{ + int err, mode, x; + + _ARGCHK(state != NULL); + _ARGCHK(out != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->blklen > (int)sizeof(state->block)) || (state->buflen > state->blklen)) { + return CRYPT_INVALID_ARG; + } + + /* figure out mode */ + if (state->buflen != state->blklen) { + /* add the 0x80 byte */ + state->block[state->buflen++] = 0x80; + + /* pad with 0x00 */ + while (state->buflen < state->blklen) { + state->block[state->buflen++] = 0x00; + } + mode = 1; + } else { + mode = 0; + } + + /* now xor prev + Lu[mode] */ + for (x = 0; x < state->blklen; x++) { + state->block[x] ^= state->prev[x] ^ state->Lu[mode][x]; + } + + /* encrypt it */ + cipher_descriptor[state->cipher_idx].ecb_encrypt(state->block, state->block, &state->key); + + /* output it */ + for (x = 0; x < state->blklen && (unsigned long)x < *outlen; x++) { + out[x] = state->block[x]; + } + *outlen = x; + +#ifdef CLEAN_STACK + zeromem(state, sizeof(*state)); +#endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_file.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + int err, x; + omac_state omac; + FILE *in; + unsigned char buf[512]; + + _ARGCHK(key != NULL); + _ARGCHK(filename != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_init.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,76 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int err, x, y, mask, msb, len; + + _ARGCHK(omac != NULL); + _ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* now setup the system */ + switch (cipher_descriptor[cipher].block_length) { + case 8: mask = 0x1B; + len = 8; + break; + case 16: mask = 0x87; + len = 16; + break; + default: return CRYPT_INVALID_ARG; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { + return err; + } + + /* ok now we need Lu and Lu^2 [calc one from the other] */ + + /* first calc L which is Ek(0) */ + zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); + cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key); + + /* now do the mults, whoopy! */ + for (x = 0; x < 2; x++) { + /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ + msb = omac->Lu[x][0] >> 7; + + /* shift left */ + for (y = 0; y < (len - 1); y++) { + omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; + } + omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; + + /* copy up as require */ + if (x == 0) { + memcpy(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); + } + } + + /* setup state */ + omac->cipher_idx = cipher; + omac->buflen = 0; + omac->blklen = len; + zeromem(omac->prev, sizeof(omac->prev)); + zeromem(omac->block, sizeof(omac->block)); + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen) +{ + int err; + omac_state omac; + + _ARGCHK(key != NULL); + _ARGCHK(msg != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + if ((err = omac_process(&omac, msg, msglen)) != CRYPT_OK) { + return err; + } + if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { + return err; + } + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_process.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_process(omac_state *state, const unsigned char *buf, unsigned long len) +{ + int err, n, x; + + _ARGCHK(state != NULL); + _ARGCHK(buf != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->blklen > (int)sizeof(state->block)) || (state->buflen > state->blklen)) { + return CRYPT_INVALID_ARG; + } + + while (len != 0) { + /* ok if the block is full we xor in prev, encrypt and replace prev */ + if (state->buflen == state->blklen) { + for (x = 0; x < state->blklen; x++) { + state->block[x] ^= state->prev[x]; + } + cipher_descriptor[state->cipher_idx].ecb_encrypt(state->block, state->prev, &state->key); + state->buflen = 0; + } + + /* add bytes */ + n = MIN(len, (unsigned long)(state->blklen - state->buflen)); + memcpy(state->block + state->buflen, buf, n); + state->buflen += n; + len -= n; + buf += n; + } + + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omac_test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,95 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct { + int keylen, msglen; + unsigned char key[16], msg[64], tag[16]; + } tests[] = { + { 16, 0, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x00 }, + { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 } + }, + { 16, 16, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, + { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } + }, + { 16, 40, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, + { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, + 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } + }, + { 16, 64, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, + { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } + } + + }; + unsigned char out[16]; + int x, y, err, idx; + unsigned long len; + + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(out); + if ((err = omac_memory(idx, tests[x].key, tests[x].keylen, tests[x].msg, tests[x].msglen, out, &len)) != CRYPT_OK) { + return err; + } + + if (memcmp(out, tests[x].tag, 16) != 0) { + printf("\n\nTag: "); + for (y = 0; y < 16; y++) printf("%02x", out[y]); printf("\n\n"); + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packet_store_header.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef PACKET + +void packet_store_header(unsigned char *dst, int section, int subsection) +{ + _ARGCHK(dst != NULL); + + /* store version number */ + dst[0] = (unsigned char)(CRYPT&255); + dst[1] = (unsigned char)((CRYPT>>8)&255); + + /* store section and subsection */ + dst[2] = (unsigned char)(section & 255); + dst[3] = (unsigned char)(subsection & 255); + +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packet_valid_header.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,37 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef PACKET + +int packet_valid_header(unsigned char *src, int section, int subsection) +{ + unsigned long ver; + + _ARGCHK(src != NULL); + + /* check version */ + ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U); + if (CRYPT < ver) { + return CRYPT_INVALID_PACKET; + } + + /* check section and subsection */ + if (section != (int)src[2] || subsection != (int)src[3]) { + return CRYPT_INVALID_PACKET; + } + + return CRYPT_OK; +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_i2osp.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* Integer to Octet I2OSP -- Tom St Denis */ + +#ifdef PKCS_1 + +/* always stores the same # of bytes, pads with leading zero bytes + as required + */ +int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out) +{ + int err; + unsigned long size; + + size = mp_unsigned_bin_size(n); + + if (size > modulus_len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store it */ + zeromem(out, modulus_len); + if ((err = mp_to_unsigned_bin(n, out+(modulus_len-size))) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + return CRYPT_OK; +} + +#endif /* PKCS_1 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_mgf1.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,66 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* The Mask Generation Function (MGF1) for PKCS #1 -- Tom St Denis */ + +#ifdef PKCS_1 + +int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, + int hash_idx, + unsigned char *mask, unsigned long masklen) +{ + unsigned long hLen, counter, x; + int err; + hash_state md; + unsigned char buf[MAXBLOCKSIZE]; + + _ARGCHK(seed != NULL); + _ARGCHK(mask != NULL); + + /* ensure valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get hash output size */ + hLen = hash_descriptor[hash_idx].hashsize; + + /* start counter */ + counter = 0; + + while (masklen > 0) { + /* handle counter */ + STORE32H(counter, buf); + ++counter; + + /* get hash of seed || counter */ + hash_descriptor[hash_idx].init(&md); + if ((err = hash_descriptor[hash_idx].process(&md, seed, seedlen)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].process(&md, buf, 4)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].done(&md, buf)) != CRYPT_OK) { + return err; + } + + /* store it */ + for (x = 0; x < hLen && masklen > 0; x++, masklen--) { + *mask++ = buf[x]; + } + } + + return CRYPT_OK; +} + +#endif /* PKCS_1 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_oaep_decode.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,135 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* OAEP Padding for PKCS #1 -- Tom St Denis */ + +#ifdef PKCS_1 + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)]; + unsigned long hLen, x, y, modulus_len; + int err; + + _ARGCHK(msg != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if (modulus_len >= sizeof(DB) || msglen != modulus_len) { + return CRYPT_PK_INVALID_SIZE; + } + + /* ok so it's now in the form + + 0x00 || maskedseed || maskedDB + + 1 || hLen || modulus_len - hLen - 1 + + */ + + /* must have leading 0x00 byte */ + if (msg[0] != 0x00) { + return CRYPT_INVALID_PACKET; + } + + /* now read the masked seed */ + for (x = 1, y = 0; y < hLen; y++) { + seed[y] = msg[x++]; + } + + /* now read the masked DB */ + for (y = 0; y < modulus_len - hLen - 1; y++) { + DB[y] = msg[x++]; + } + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(DB, modulus_len - hLen - 1, hash_idx, mask, hLen)) != CRYPT_OK) { + return err; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(seed, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + return err; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + + /* compute lhash and store it in seed [reuse temps!] */ + x = sizeof(seed); + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + return err; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { + return err; + } + } + + /* compare the lhash'es */ + if (memcmp(seed, DB, hLen) != 0) { + return CRYPT_INVALID_PACKET; + } + + /* now zeroes before a 0x01 */ + for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { + /* step... */ + } + + /* error out if wasn't 0x01 */ + if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { + return CRYPT_INVALID_PACKET; + } + + /* rest is the message (and skip 0x01) */ + if (msglen - ++x > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* copy message */ + *outlen = (modulus_len - hLen - 1) - x; + for (y = 0; x != (modulus_len - hLen - 1); ) { + out[y++] = DB[x++]; + } + +#ifdef CLEAN_STACK + zeromem(DB, sizeof(DB)); + zeromem(seed, sizeof(seed)); + zeromem(mask, sizeof(mask)); +#endif + + return CRYPT_OK; +} + +#endif /* PKCS_1 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_oaep_encode.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,128 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* OAEP Padding for PKCS #1 -- Tom St Denis */ + +#ifdef PKCS_1 + +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned char *out, unsigned long *outlen) +{ + unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)]; + unsigned long hLen, x, y, modulus_len; + int err; + + _ARGCHK(msg != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* valid prng */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if (modulus_len >= sizeof(DB) || msglen > (modulus_len - 2*hLen - 2)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* get lhash */ +// DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes + x = sizeof(DB); + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) { + return err; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) { + return err; + } + } + + /* append PS then 0x01 (to lhash) */ + x = hLen; + y = modulus_len - msglen - 2*hLen - 2; + while (y--) { + DB[x++] = 0x00; + } + DB[x++] = 0x01; + + /* message */ + y = msglen; + while (y--) { + DB[x++] = *msg++; + } + + /* now choose a random seed */ + if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { + return CRYPT_ERROR_READPRNG; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(seed, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + return err; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(DB, modulus_len - hLen - 1, hash_idx, mask, hLen)) != CRYPT_OK) { + return err; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* create string of length modulus_len */ + if (*outlen < modulus_len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* start output which is 0x00 || maskedSeed || maskedDB */ + x = 0; + out[x++] = 0x00; + for (y = 0; y < hLen; y++) { + out[x++] = seed[y]; + } + for (y = 0; y < modulus_len - hLen - 1; y++) { + out[x++] = DB[y]; + } + *outlen = x; + +#ifdef CLEAN_STACK + zeromem(DB, sizeof(DB)); + zeromem(seed, sizeof(seed)); + zeromem(mask, sizeof(mask)); +#endif + + return CRYPT_OK; +} + +#endif /* PKCS_1 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_os2ip.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* Octet to Integer OS2IP -- Tom St Denis */ +#ifdef PKCS_1 + +int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen) +{ + int err; + /* read it */ + if ((err = mp_read_unsigned_bin(n, in, inlen)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + return CRYPT_OK; +} + +#endif /* PKCS_1 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_pss_decode.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,121 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* PKCS #1 PSS Signature Padding -- Tom St Denis */ + +#ifdef PKCS_1 + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + unsigned char DB[1024], mask[sizeof(DB)], salt[sizeof(DB)], hash[sizeof(DB)]; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + _ARGCHK(msghash != NULL); + _ARGCHK(res != NULL); + + /* default to invalid */ + *res = 0; + + /* ensure hash is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > sizeof(salt)) || (modulus_len > sizeof(DB)) || + (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { + return CRYPT_INVALID_ARG; + } + + /* ensure the 0xBC byte */ + if (sig[siglen-1] != 0xBC) { + return CRYPT_OK; + } + + /* copy out the DB */ + for (x = 0; x < modulus_len - hLen - 1; x++) { + DB[x] = sig[x]; + } + + /* copy out the hash */ + for (y = 0; y < hLen; y++) { + hash[y] = sig[x++]; + } + + /* check the MSB */ + if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) { + return CRYPT_OK; + } + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + return err; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + + /* check for zeroes and 0x01 */ + for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { + if (DB[x] != 0x00) { + return CRYPT_OK; + } + } + + if (DB[x++] != 0x01) { + return CRYPT_OK; + } + + /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ + hash_descriptor[hash_idx].init(&md); + zeromem(mask, 8); + if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + return err; + } + + /* mask == hash means valid signature */ + if (memcmp(mask, hash, hLen) == 0) { + *res = 1; + } + +#ifdef CLEAN_STACK + zeromem(DB, sizeof(DB)); + zeromem(mask, sizeof(mask)); + zeromem(salt, sizeof(salt)); + zeromem(hash, sizeof(hash)); +#endif + + return CRYPT_OK; +} + +#endif /* PKCS_1 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_1_pss_encode.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,122 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +/* PKCS #1 PSS Signature Padding -- Tom St Denis */ + +#ifdef PKCS_1 + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, int hash_idx, + int prng_idx, prng_state *prng, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned char DB[1024], mask[sizeof(DB)], salt[sizeof(DB)], hash[sizeof(DB)]; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + _ARGCHK(msghash != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* ensure hash and PRNG are valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > sizeof(salt)) || (modulus_len > sizeof(DB)) || (modulus_len < hLen + saltlen + 2)) { + return CRYPT_INVALID_ARG; + } + + /* generate random salt */ + if (saltlen > 0) { + if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + return CRYPT_ERROR_READPRNG; + } + } + + /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ + hash_descriptor[hash_idx].init(&md); + zeromem(DB, 8); + if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + return err; + } + if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + return err; + } + + /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + for (x = 0; x < (modulus_len - saltlen - hLen - 2); x++) { + DB[x] = 0x00; + } + DB[x++] = 0x01; + for (y = 0; y < saltlen; y++) { + DB[x++] = salt[y]; + } + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + return err; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* output is DB || hash || 0xBC */ + if (*outlen < modulus_len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* DB */ + for (y = x = 0; x < modulus_len - hLen - 1; x++) { + out[y++] = DB[x]; + } + /* hash */ + for (x = 0; x < hLen; x++) { + out[y++] = hash[x]; + } + /* 0xBC */ + out[y] = 0xBC; + + /* now clear the 8*modulus_len - modulus_bitlen most significant bits */ + out[0] &= 0xFF >> ((modulus_len<<3) - modulus_bitlen); + + /* store output size */ + *outlen = modulus_len; + +#ifdef CLEAN_STACK + zeromem(DB, sizeof(DB)); + zeromem(mask, sizeof(mask)); + zeromem(salt, sizeof(salt)); + zeromem(hash, sizeof(hash)); +#endif + + return CRYPT_OK; +} + +#endif /* PKCS_1 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_5_1.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,63 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include <mycrypt.h> + +/* PKCS #5, Algorithm #1 */ +#ifdef PKCS_5 + +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err; + unsigned long x; + hash_state md; + unsigned char buf[MAXBLOCKSIZE]; + + _ARGCHK(password != NULL); + _ARGCHK(salt != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* hash initial password + salt */ + hash_descriptor[hash_idx].init(&md); + hash_descriptor[hash_idx].process(&md, password, password_len); + hash_descriptor[hash_idx].process(&md, salt, 8); + hash_descriptor[hash_idx].done(&md, buf); + + while (--iteration_count) { + // code goes here. + x = sizeof(buf); + if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) { + return err; + } + } + + /* copy upto outlen bytes */ + for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) { + out[x] = buf[x]; + } + *outlen = x; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkcs_5_2.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,88 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include <mycrypt.h> + +/* PKCS #5, Algorithm #2 */ +#ifdef PKCS_5 + +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err, itts; + unsigned long stored, left, x, y, blkno; + unsigned char buf[2][MAXBLOCKSIZE]; + hmac_state hmac; + + _ARGCHK(password != NULL); + _ARGCHK(salt != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + left = *outlen; + blkno = 1; + stored = 0; + while (left != 0) { + /* process block number blkno */ + zeromem(buf, sizeof(buf)); + + /* store current block number and increment for next pass */ + STORE32H(blkno, buf[1]); + ++blkno; + + /* get PRF(P, S||int(blkno)) */ + if ((err = hmac_init(&hmac, hash_idx, password, password_len)) != CRYPT_OK) { + return err; + } + if ((err = hmac_process(&hmac, salt, salt_len)) != CRYPT_OK) { + return err; + } + if ((err = hmac_process(&hmac, buf[1], 4)) != CRYPT_OK) { + return err; + } + x = sizeof(buf[0]); + if ((err = hmac_done(&hmac, buf[0], &x)) != CRYPT_OK) { + return err; + } + + /* now compute repeated and XOR it in buf[1] */ + memcpy(buf[1], buf[0], x); + for (itts = 2; itts < iteration_count; ++itts) { + if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) { + return err; + } + for (y = 0; y < x; y++) { + buf[1][y] ^= buf[0][y]; + } + } + + /* now emit upto x bytes of buf[1] to output */ + for (y = 0; y < x && left != 0; ++y) { + out[stored++] = buf[1][y]; + --left; + } + } + *outlen = stored; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_done.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,64 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) +{ + int err, x; + + _ARGCHK(state != NULL); + _ARGCHK(out != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { + return CRYPT_INVALID_ARG; + } + + + /* handle padding. If multiple xor in L/x */ + + if (state->buflen == state->block_len) { + /* xor Lr against the checksum */ + for (x = 0; x < state->block_len; x++) { + state->checksum[x] ^= state->block[x] ^ state->Lr[x]; + } + } else { + /* otherwise xor message bytes then the 0x80 byte */ + for (x = 0; x < state->buflen; x++) { + state->checksum[x] ^= state->block[x]; + } + state->checksum[x] ^= 0x80; + } + + /* encrypt it */ + cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key); + + /* store it */ + for (x = 0; x < state->block_len && x <= (int)*outlen; x++) { + out[x] = state->checksum[x]; + } + *outlen = x; + +#ifdef CLEAN_STACK + zeromem(state, sizeof(*state)); +#endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_file.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,67 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + int err, x; + pmac_state pmac; + FILE *in; + unsigned char buf[512]; + + + _ARGCHK(key != NULL); + _ARGCHK(filename != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + return CRYPT_OK; +#endif +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_init.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,114 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int poly, x, y, m, err; + unsigned char L[MAXBLOCKSIZE]; + + _ARGCHK(pmac != NULL); + _ARGCHK(key != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* determine which polys to use */ + pmac->block_len = cipher_descriptor[cipher].block_length; + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { + if (polys[poly].len == pmac->block_len) { + break; + } + } + if (polys[poly].len != pmac->block_len) { + return CRYPT_INVALID_ARG; + } + + /* schedule the key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { + return err; + } + + /* find L = E[0] */ + zeromem(L, pmac->block_len); + cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key); + + /* find Ls[i] = L << i for i == 0..31 */ + memcpy(pmac->Ls[0], L, pmac->block_len); + for (x = 1; x < 32; x++) { + m = pmac->Ls[x-1][0] >> 7; + for (y = 0; y < pmac->block_len-1; y++) { + pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255; + } + pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255; + + if (m == 1) { + for (y = 0; y < pmac->block_len; y++) { + pmac->Ls[x][y] ^= polys[poly].poly_mul[y]; + } + } + } + + /* find Lr = L / x */ + m = L[pmac->block_len-1] & 1; + + /* shift right */ + for (x = pmac->block_len - 1; x > 0; x--) { + pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; + } + pmac->Lr[0] = L[0] >> 1; + + if (m == 1) { + for (x = 0; x < pmac->block_len; x++) { + pmac->Lr[x] ^= polys[poly].poly_div[x]; + } + } + + /* zero buffer, counters, etc... */ + pmac->block_index = 1; + pmac->cipher_idx = cipher; + pmac->buflen = 0; + zeromem(pmac->block, sizeof(pmac->block)); + zeromem(pmac->Li, sizeof(pmac->Li)); + zeromem(pmac->checksum, sizeof(pmac->checksum)); + +#ifdef CLEAN_STACK + zeromem(L, sizeof(L)); +#endif + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_memory.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen) +{ + int err; + pmac_state pmac; + + _ARGCHK(key != NULL); + _ARGCHK(msg != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + + if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + if ((err = pmac_process(&pmac, msg, msglen)) != CRYPT_OK) { + return err; + } + if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) { + return err; + } + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_ntz.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,29 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_process.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,62 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_process(pmac_state *state, const unsigned char *buf, unsigned long len) +{ + int err, n, x; + unsigned char Z[MAXBLOCKSIZE]; + + _ARGCHK(state != NULL); + _ARGCHK(buf != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { + return CRYPT_INVALID_ARG; + } + + while (len != 0) { + /* ok if the block is full we xor in prev, encrypt and replace prev */ + if (state->buflen == state->block_len) { + pmac_shift_xor(state); + for (x = 0; x < state->block_len; x++) { + Z[x] = state->Li[x] ^ state->block[x]; + } + cipher_descriptor[state->cipher_idx].ecb_encrypt(Z, Z, &state->key); + for (x = 0; x < state->block_len; x++) { + state->checksum[x] ^= Z[x]; + } + state->buflen = 0; + } + + /* add bytes */ + n = MIN(len, (unsigned long)(state->block_len - state->buflen)); + memcpy(state->block + state->buflen, buf, n); + state->buflen += n; + len -= n; + buf += n; + } + +#ifdef CLEAN_STACK + zeromem(Z, sizeof(Z)); +#endif + + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_shift_xor.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,26 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +void pmac_shift_xor(pmac_state *pmac) +{ + int x, y; + y = pmac_ntz(pmac->block_index++); + for (x = 0; x < pmac->block_len; x++) { + pmac->Li[x] ^= pmac->Ls[y][x]; + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pmac_test.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,153 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* PMAC implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef PMAC + +int pmac_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct { + int msglen; + unsigned char key[16], msg[34], tag[16]; + } tests[] = { + + /* PMAC-AES-128-0B */ +{ + 0, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00 }, + /* tag */ + { 0x43, 0x99, 0x57, 0x2c, 0xd6, 0xea, 0x53, 0x41, + 0xb8, 0xd3, 0x58, 0x76, 0xa7, 0x09, 0x8a, 0xf7 } +}, + + /* PMAC-AES-128-3B */ +{ + 3, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02 }, + /* tag */ + { 0x25, 0x6b, 0xa5, 0x19, 0x3c, 0x1b, 0x99, 0x1b, + 0x4d, 0xf0, 0xc5, 0x1f, 0x38, 0x8a, 0x9e, 0x27 } +}, + + /* PMAC-AES-128-16B */ +{ + 16, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* tag */ + { 0xeb, 0xbd, 0x82, 0x2f, 0xa4, 0x58, 0xda, 0xf6, + 0xdf, 0xda, 0xd7, 0xc2, 0x7d, 0xa7, 0x63, 0x38 } +}, + + /* PMAC-AES-128-20B */ +{ + 20, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 }, + /* tag */ + { 0x04, 0x12, 0xca, 0x15, 0x0b, 0xbf, 0x79, 0x05, + 0x8d, 0x8c, 0x75, 0xa5, 0x8c, 0x99, 0x3f, 0x55 } +}, + + /* PMAC-AES-128-32B */ +{ + 32, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + /* tag */ + { 0xe9, 0x7a, 0xc0, 0x4e, 0x9e, 0x5e, 0x33, 0x99, + 0xce, 0x53, 0x55, 0xcd, 0x74, 0x07, 0xbc, 0x75 } +}, + + /* PMAC-AES-128-34B */ +{ + 34, + /* key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + /* msg */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 }, + /* tag */ + { 0x5c, 0xba, 0x7d, 0x5e, 0xb2, 0x4f, 0x7c, 0x86, + 0xcc, 0xc5, 0x46, 0x04, 0xe5, 0x3d, 0x55, 0x12 } +} + +}; + int err, x, idx; + unsigned long len; + unsigned char outtag[MAXBLOCKSIZE]; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + len = sizeof(outtag); + if ((err = pmac_memory(idx, tests[x].key, 16, tests[x].msg, tests[x].msglen, outtag, &len)) != CRYPT_OK) { + return err; + } + + if (memcmp(outtag, tests[x].tag, len)) { +#if 0 + unsigned long y; + printf("\nTAG:\n"); + for (y = 0; y < len; ) { + printf("0x%02x", outtag[y]); + if (y < len-1) printf(", "); + if (!(++y % 8)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif /* LTC_TEST */ +} + +#endif /* PMAC_MODE */ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rand_prime.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef MPI + +struct rng_data { + prng_state *prng; + int wprng; +}; + +static int rand_prime_helper(unsigned char *dst, int len, void *dat) +{ + return (int)prng_descriptor[((struct rng_data *)dat)->wprng].read(dst, len, ((struct rng_data *)dat)->prng); +} + +int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) +{ + struct rng_data rng; + int type, err; + + _ARGCHK(N != NULL); + + /* allow sizes between 2 and 256 bytes for a prime size */ + if (len < 16 || len > 4096) { + return CRYPT_INVALID_PRIME_SIZE; + } + + /* valid PRNG? Better be! */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* setup our callback data, then world domination! */ + rng.prng = prng; + rng.wprng = wprng; + + /* get type */ + if (len < 0) { + type = LTM_PRIME_BBS; + len = -len; + } else { + type = 0; + } + + /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! + -- Gir: Yeah, oh wait, er, no. + */ + if ((err = mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rc2.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,319 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/**********************************************************************\ +* To commemorate the 1996 RSA Data Security Conference, the following * +* code is released into the public domain by its author. Prost! * +* * +* This cipher uses 16-bit words and little-endian byte ordering. * +* I wonder which processor it was optimized for? * +* * +* Thanks to CodeView, SoftIce, and D86 for helping bring this code to * +* the public. * +\**********************************************************************/ + +#include <mycrypt.h> + +#ifdef RC2 + +const struct _cipher_descriptor rc2_desc = { + "rc2", + 12, 8, 128, 8, 16, + &rc2_setup, + &rc2_ecb_encrypt, + &rc2_ecb_decrypt, + &rc2_test, + &rc2_keysize +}; + + +/**********************************************************************\ +* Expand a variable-length user key (between 1 and 128 bytes) to a * +* 64-short working rc2 key, of at most "bits" effective key bits. * +* The effective key bits parameter looks like an export control hack. * +* For normal use, it should always be set to 1024. For convenience, * +* zero is accepted as an alias for 1024. * +\**********************************************************************/ + + /* 256-entry permutation table, probably derived somehow from pi */ + static const unsigned char permute[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 + }; + +int rc2_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey) +{ + unsigned *xkey = skey->rc2.xkey; + unsigned char tmp[128]; + unsigned T8, TM; + int i, bits; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + if (rounds != 0 && rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + for (i = 0; i < keylen; i++) { + tmp[i] = key[i] & 255; + } + + /* Phase 1: Expand input key to 128 bytes */ + if (keylen < 128) { + for (i = keylen; i < 128; i++) { + tmp[i] = permute[(int)((tmp[i - 1] + tmp[i - keylen]) & 255)]; + } + } + + /* Phase 2 - reduce effective key size to "bits" */ + bits = keylen*8; + T8 = (unsigned)(bits+7)>>3; + TM = (255 >> (unsigned)(7 & -bits)); + tmp[128 - T8] = permute[(int)(tmp[128 - T8] & TM)]; + for (i = 127 - T8; i >= 0; i--) { + tmp[i] = permute[(int)(tmp[i + 1] ^ tmp[i + T8])]; + } + + /* Phase 3 - copy to xkey in little-endian order */ + i = 63; + do { + xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); + } while (i-- > 0); + +#ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/**********************************************************************\ +* Encrypt an 8-byte block of plaintext using the given key. * +\**********************************************************************/ +#ifdef CLEAN_STACK +static void _rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +#else +void rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +#endif +{ + unsigned *xkey; + unsigned x76, x54, x32, x10, i; + + _ARGCHK(plain != NULL); + _ARGCHK(cipher != NULL); + _ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)plain[7] << 8) + (unsigned)plain[6]; + x54 = ((unsigned)plain[5] << 8) + (unsigned)plain[4]; + x32 = ((unsigned)plain[3] << 8) + (unsigned)plain[2]; + x10 = ((unsigned)plain[1] << 8) + (unsigned)plain[0]; + + for (i = 0; i < 16; i++) { + x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; + x10 = ((x10 << 1) | (x10 >> 15)) & 0xFFFF; + + x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; + x32 = ((x32 << 2) | (x32 >> 14)) & 0xFFFF; + + x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; + x54 = ((x54 << 3) | (x54 >> 13)) & 0xFFFF; + + x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; + x76 = ((x76 << 5) | (x76 >> 11)) & 0xFFFF; + + if (i == 4 || i == 10) { + x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; + x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; + x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; + x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; + } + } + + cipher[0] = (unsigned char)x10; + cipher[1] = (unsigned char)(x10 >> 8); + cipher[2] = (unsigned char)x32; + cipher[3] = (unsigned char)(x32 >> 8); + cipher[4] = (unsigned char)x54; + cipher[5] = (unsigned char)(x54 >> 8); + cipher[6] = (unsigned char)x76; + cipher[7] = (unsigned char)(x76 >> 8); +} + +#ifdef CLEAN_STACK +void rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +{ + _rc2_ecb_encrypt(plain, cipher, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); +} +#endif + +/**********************************************************************\ +* Decrypt an 8-byte block of ciphertext using the given key. * +\**********************************************************************/ + +#ifdef CLEAN_STACK +static void _rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +#else +void rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +#endif +{ + unsigned x76, x54, x32, x10; + unsigned *xkey; + int i; + + _ARGCHK(plain != NULL); + _ARGCHK(cipher != NULL); + _ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)cipher[7] << 8) + (unsigned)cipher[6]; + x54 = ((unsigned)cipher[5] << 8) + (unsigned)cipher[4]; + x32 = ((unsigned)cipher[3] << 8) + (unsigned)cipher[2]; + x10 = ((unsigned)cipher[1] << 8) + (unsigned)cipher[0]; + + for (i = 15; i >= 0; i--) { + if (i == 4 || i == 10) { + x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; + x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; + x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; + x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; + } + + x76 = ((x76 << 11) | (x76 >> 5)) & 0xFFFF; + x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; + + x54 = ((x54 << 13) | (x54 >> 3)) & 0xFFFF; + x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; + + x32 = ((x32 << 14) | (x32 >> 2)) & 0xFFFF; + x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; + + x10 = ((x10 << 15) | (x10 >> 1)) & 0xFFFF; + x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; + } + + plain[0] = (unsigned char)x10; + plain[1] = (unsigned char)(x10 >> 8); + plain[2] = (unsigned char)x32; + plain[3] = (unsigned char)(x32 >> 8); + plain[4] = (unsigned char)x54; + plain[5] = (unsigned char)(x54 >> 8); + plain[6] = (unsigned char)x76; + plain[7] = (unsigned char)(x76 >> 8); +} + +#ifdef CLEAN_STACK +void rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +{ + _rc2_ecb_decrypt(cipher, plain, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); +} +#endif + +int rc2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + + { 8, + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } + + }, + { 16, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } + } + }; + int x, y, err; + symmetric_key skey; + unsigned char tmp[2][8]; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + zeromem(tmp, sizeof(tmp)); + if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + + rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); + rc2_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (memcmp(tmp[0], tests[x].ct, 8) != 0 || memcmp(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc2_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rc4.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +#ifdef RC4 + +const struct _prng_descriptor rc4_desc = +{ + "rc4", + &rc4_start, + &rc4_add_entropy, + &rc4_ready, + &rc4_read +}; + +int rc4_start(prng_state *prng) +{ + _ARGCHK(prng != NULL); + + /* set keysize to zero */ + prng->rc4.x = 0; + + return CRYPT_OK; +} + +int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + if (prng->rc4.x + len > 256) { + return CRYPT_INVALID_KEYSIZE; + } + + while (len--) { + prng->rc4.buf[prng->rc4.x++] = *buf++; + } + + return CRYPT_OK; + +} + +int rc4_ready(prng_state *prng) +{ + unsigned char key[256], tmp; + int keylen, x, y; + + _ARGCHK(prng != NULL); + + /* extract the key */ + memcpy(key, prng->rc4.buf, 256); + keylen = prng->rc4.x; + + /* make RC4 perm and shuffle */ + for (x = 0; x < 256; x++) { + prng->rc4.buf[x] = x; + } + + for (x = y = 0; x < 256; x++) { + y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255; + tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp; + } + prng->rc4.x = x; + prng->rc4.y = y; + +#ifdef CLEAN_STACK + zeromem(key, sizeof(key)); +#endif + + return CRYPT_OK; +} + +unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + int x, y; + unsigned char *s, tmp; + unsigned long n; + + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + n = len; + x = prng->rc4.x; + y = prng->rc4.y; + s = prng->rc4.buf; + while (len--) { + x = (x + 1) & 255; + y = (y + s[x]) & 255; + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + tmp = (s[x] + s[y]) & 255; + *buf++ ^= s[tmp]; + } + prng->rc4.x = x; + prng->rc4.y = y; + return n; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rc5.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,269 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RC5 code by Tom St Denis */ + +#include "mycrypt.h" + +#ifdef RC5 + +const struct _cipher_descriptor rc5_desc = +{ + "rc5", + 2, + 8, 128, 8, 12, + &rc5_setup, + &rc5_ecb_encrypt, + &rc5_ecb_decrypt, + &rc5_test, + &rc5_keysize +}; + +static const ulong32 stab[50] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL, +0x62482413UL, 0x007f9dccUL +}; + +#ifdef CLEAN_STACK +static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], *S, A, B, i, j, v, s, t, l; + + _ARGCHK(skey != NULL); + _ARGCHK(key != NULL); + + /* test parameters */ + if (num_rounds == 0) { + num_rounds = rc5_desc.default_rounds; + } + + if (num_rounds < 12 || num_rounds > 24) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + skey->rc5.rounds = num_rounds; + S = skey->rc5.K; + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if ((i & 3) == 0) { + L[j++] = BSWAP(A); + A = 0; + } + } + + if ((keylen & 3) != 0) { + A <<= (ulong32)((8 * (4 - (keylen&3)))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + t = (ulong32)(2 * (num_rounds + 1)); + memcpy(S, stab, t * sizeof(*S)); + + /* mix buffer */ + s = 3 * MAX(t, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROL(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == t) { i = 0; } + if (++j == l) { j = 0; } + } + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122 + sizeof(int)); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 A, B, *K; + int r; + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(A, &pt[0]); + LOAD32L(B, &pt[4]); + A += key->rc5.K[0]; + B += key->rc5.K[1]; + K = key->rc5.K + 2; + + if ((key->rc5.rounds & 1) == 0) { + for (r = 0; r < key->rc5.rounds; r += 2) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + A = ROL(A ^ B, B) + K[2]; + B = ROL(B ^ A, A) + K[3]; + K += 4; + } + } else { + for (r = 0; r < key->rc5.rounds; r++) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + K += 2; + } + } + STORE32L(A, &ct[0]); + STORE32L(B, &ct[4]); +} + +#ifdef CLEAN_STACK +void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _rc5_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 A, B, *K; + int r; + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(A, &ct[0]); + LOAD32L(B, &ct[4]); + K = key->rc5.K + (key->rc5.rounds << 1); + + if ((key->rc5.rounds & 1) == 0) { + K -= 2; + for (r = key->rc5.rounds - 1; r >= 0; r -= 2) { + B = ROR(B - K[3], A) ^ A; + A = ROR(A - K[2], B) ^ B; + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 4; + } + } else { + for (r = key->rc5.rounds - 1; r >= 0; r--) { + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 2; + } + } + A -= key->rc5.K[0]; + B -= key->rc5.K[1]; + STORE32L(A, &pt[0]); + STORE32L(B, &pt[4]); +} + +#ifdef CLEAN_STACK +void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _rc5_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +int rc5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + { + { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, + 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 }, + { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d }, + { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 } + }, + { + { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, + 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 }, + { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 } + }, + { + { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, + 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }, + { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc } + } + }; + unsigned char tmp[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc5_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc5_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (memcmp(tmp[0], tests[x].ct, 8) != 0 || memcmp(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc5_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 128) { + *desired_keysize = 128; + } + return CRYPT_OK; +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rc6.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,298 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RC6 code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef RC6 + +const struct _cipher_descriptor rc6_desc = +{ + "rc6", + 3, + 8, 128, 16, 20, + &rc6_setup, + &rc6_ecb_encrypt, + &rc6_ecb_decrypt, + &rc6_test, + &rc6_keysize +}; + +static const ulong32 stab[44] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL }; + +#ifdef CLEAN_STACK +static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], S[50], A, B, i, j, v, s, l; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* test parameters */ + if (num_rounds != 0 && num_rounds != 20) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if (!(i & 3)) { + L[j++] = BSWAP(A); + A = 0; + } + } + + /* handle odd sized keys */ + if (keylen & 3) { + A <<= (8 * (4 - (keylen&3))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + memcpy(S, stab, 44 * sizeof(stab[0])); + + /* mix buffer */ + s = 3 * MAX(44, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROL(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == 44) { i = 0; } + if (++j == l) { j = 0; } + } + + /* copy to key */ + for (i = 0; i < 44; i++) { + skey->rc6.K[i] = S[i]; + } + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc6_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); + + b += key->rc6.K[0]; + d += key->rc6.K[1]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROL(t, 5); \ + u = (d * (d + d + 1)); u = ROL(u, 5); \ + a = ROL(a^t,u) + K[0]; \ + c = ROL(c^u,t) + K[1]; K += 2; + + K = key->rc6.K + 2; + for (r = 0; r < 20; r += 4) { + RND(a,b,c,d); + RND(b,c,d,a); + RND(c,d,a,b); + RND(d,a,b,c); + } + +#undef RND + + a += key->rc6.K[42]; + c += key->rc6.K[43]; + STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); +} + +#ifdef CLEAN_STACK +void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _rc6_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); + a -= key->rc6.K[42]; + c -= key->rc6.K[43]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROL(t, 5); \ + u = (d * (d + d + 1)); u = ROL(u, 5); \ + c = ROR(c - K[1], t) ^ u; \ + a = ROR(a - K[0], u) ^ t; K -= 2; + + K = key->rc6.K + 40; + + for (r = 0; r < 20; r += 4) { + RND(d,a,b,c); + RND(c,d,a,b); + RND(b,c,d,a); + RND(a,b,c,d); + } + +#undef RND + + b -= key->rc6.K[0]; + d -= key->rc6.K[1]; + STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); +} + +#ifdef CLEAN_STACK +void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _rc6_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); +} +#endif + +int rc6_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, + 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 } + }, + { + 24, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04, + 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 } + }, + { + 32, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89, + 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 } + } + }; + unsigned char tmp[2][16]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc6_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (memcmp(tmp[0], tests[x].ct, 16) || memcmp(tmp[1], tests[x].pt, 16)) { +#if 0 + printf("\n\nFailed test %d\n", x); + if (memcmp(tmp[0], tests[x].ct, 16)) { + printf("Ciphertext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]); + printf("\n"); + } + if (memcmp(tmp[1], tests[x].pt, 16)) { + printf("Plaintext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]); + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc6_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 128) { + *desired_keysize = 128; + } + return CRYPT_OK; +} + +#endif /*RC6*/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rmd128.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,368 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ +#include "mycrypt.h" + +#ifdef RIPEMD128 + +const struct _hash_descriptor rmd128_desc = +{ + "rmd128", + 8, + 16, + 64, + &rmd128_init, + &rmd128_process, + &rmd128_done, + &rmd128_test +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)); + +#ifdef CLEAN_STACK +static void _rmd128_compress(hash_state *md, unsigned char *buf) +#else +static void rmd128_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd128.state[0]; + bb = bbb = md->rmd128.state[1]; + cc = ccc = md->rmd128.state[2]; + dd = ddd = md->rmd128.state[3]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + /* combine results */ + ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ + md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; + md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; + md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; + md->rmd128.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd128_compress(hash_state *md, unsigned char *buf) +{ + _rmd128_compress(md, buf); + burn_stack(sizeof(ulong32) * 24 + sizeof(int)); +} +#endif + +void rmd128_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd128.state[0] = 0x67452301UL; + md->rmd128.state[1] = 0xefcdab89UL; + md->rmd128.state[2] = 0x98badcfeUL; + md->rmd128.state[3] = 0x10325476UL; + md->rmd128.curlen = 0; + md->rmd128.length = 0; +} + +HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) + +int rmd128_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd128.length += md->rmd128.curlen * 8; + + /* append the '1' bit */ + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd128.curlen > 56) { + while (md->rmd128.curlen < 64) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + rmd128_compress(md, md->rmd128.buf); + md->rmd128.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd128.curlen < 56) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd128.length, md->rmd128.buf+56); + rmd128_compress(md, md->rmd128.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->rmd128.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int rmd128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, + 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } + }, + { "a", + { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, + 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } + }, + { "abc", + { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, + 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } + }, + { "message digest", + { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, + 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, + 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, + 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } + } + }; + int x; + unsigned char buf[16]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd128_init(&md); + rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd128_done(&md, buf); + if (memcmp(buf, tests[x].md, 16) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rmd160.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,427 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Implementation of RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ +#include "mycrypt.h" + +#ifdef RIPEMD160 + +const struct _hash_descriptor rmd160_desc = +{ + "rmd160", + 9, + 20, + 64, + &rmd160_init, + &rmd160_process, + &rmd160_done, + &rmd160_test +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + + +#ifdef CLEAN_STACK +static void _rmd160_compress(hash_state *md, unsigned char *buf) +#else +static void rmd160_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd160.state[0]; + bb = bbb = md->rmd160.state[1]; + cc = ccc = md->rmd160.state[2]; + dd = ddd = md->rmd160.state[3]; + ee = eee = md->rmd160.state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ + md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; + md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; + md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; + md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; + md->rmd160.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd160_compress(hash_state *md, unsigned char *buf) +{ + _rmd160_compress(md, buf); + burn_stack(sizeof(ulong32) * 26 + sizeof(int)); +} +#endif + +void rmd160_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd160.state[0] = 0x67452301UL; + md->rmd160.state[1] = 0xefcdab89UL; + md->rmd160.state[2] = 0x98badcfeUL; + md->rmd160.state[3] = 0x10325476UL; + md->rmd160.state[4] = 0xc3d2e1f0UL; + md->rmd160.curlen = 0; + md->rmd160.length = 0; +} + +HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) + +int rmd160_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd160.length += md->rmd160.curlen * 8; + + /* append the '1' bit */ + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd160.curlen > 56) { + while (md->rmd160.curlen < 64) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + rmd160_compress(md, md->rmd160.buf); + md->rmd160.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd160.curlen < 56) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd160.length, md->rmd160.buf+56); + rmd160_compress(md, md->rmd160.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->rmd160.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int rmd160_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[20]; + } tests[] = { + { "", + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } + }, + { "a", + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } + }, + { "abc", + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } + }, + { "message digest", + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } + } + }; + int x; + unsigned char buf[20]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd160_init(&md); + rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd160_done(&md, buf); + if (memcmp(buf, tests[x].md, 20) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rng_get_bytes.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,129 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* portable way to get secure random bits to feed a PRNG */ +#include "mycrypt.h" + +#ifdef DEVRANDOM +/* on *NIX read /dev/random */ +static unsigned long rng_nix(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ +#ifdef NO_FILE + return 0; +#else + FILE *f; + unsigned long x; +#ifdef TRY_URANDOM_FIRST + f = fopen("/dev/urandom", "rb"); + if (f == NULL) +#endif /* TRY_URANDOM_FIRST */ + f = fopen("/dev/random", "rb"); + + if (f == NULL) { + return 0; + } + + /* disable buffering */ + if (setvbuf(f, NULL, _IONBF, 0) != 0) { + fclose(f); + return 0; + } + + x = (unsigned long)fread(buf, 1, (size_t)len, f); + fclose(f); + return x; +#endif /* NO_FILE */ +} + +#endif /* DEVRANDOM */ + +/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */ +#if defined(CLOCKS_PER_SEC) + +#define ANSI_RNG + +static unsigned long rng_ansic(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + clock_t t1; + int l, acc, bits, a, b; + + if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) { + return 0; + } + + l = len; + bits = 8; + acc = a = b = 0; + while (len--) { + if (callback != NULL) callback(); + while (bits--) { + do { + t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; + t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; + } while (a == b); + acc = (acc << 1) | a; + } + *buf++ = acc; + acc = 0; + bits = 8; + } + acc = bits = a = b = 0; + return l; +} + +#endif + +/* Try the Microsoft CSP */ +#ifdef WIN32 +#define _WIN32_WINNT 0x0400 +#include <windows.h> +#include <wincrypt.h> + +static unsigned long rng_win32(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + HCRYPTPROV hProv = 0; + if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + return 0; + + if (CryptGenRandom(hProv, len, buf) == TRUE) { + CryptReleaseContext(hProv, 0); + return len; + } else { + CryptReleaseContext(hProv, 0); + return 0; + } +} + +#endif /* WIN32 */ + +unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + unsigned long x; + + _ARGCHK(buf != NULL); + +#if defined(DEVRANDOM) + x = rng_nix(buf, len, callback); if (x != 0) { return x; } +#endif +#ifdef WIN32 + x = rng_win32(buf, len, callback); if (x != 0) { return x; } +#endif +#ifdef ANSI_RNG + x = rng_ansic(buf, len, callback); if (x != 0) { return x; } +#endif + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rng_make_prng.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +/* portable way to get secure random bits to feed a PRNG */ +#include "mycrypt.h" + +int rng_make_prng(int bits, int wprng, prng_state *prng, + void (*callback)(void)) +{ + unsigned char buf[256]; + int err; + + _ARGCHK(prng != NULL); + + /* check parameter */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (bits < 64 || bits > 1024) { + return CRYPT_INVALID_PRNGSIZE; + } + + if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { + return err; + } + + bits = ((bits/8)+((bits&7)!=0?1:0)) * 2; + if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { + return CRYPT_ERROR_READPRNG; + } + + if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { + return err; + } + + if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { + return err; + } + + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsa.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,273 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RSA Code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MRSA + +int rsa_signpad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < (3 * inlen)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* check inlen */ + if (inlen > MAX_RSA_SIZE/8) { + return CRYPT_PK_INVALID_SIZE; + } + + for (y = x = 0; x < inlen; x++) + out[y++] = (unsigned char)0xFF; + for (x = 0; x < inlen; x++) + out[y++] = in[x]; + for (x = 0; x < inlen; x++) + out[y++] = (unsigned char)0xFF; + *outlen = 3 * inlen; + return CRYPT_OK; +} + +int rsa_pad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int wprng, prng_state *prng) +{ + unsigned char buf[3*(MAX_RSA_SIZE/8)]; + unsigned long x; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* is output big enough? */ + if (*outlen < (3 * inlen)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* get random padding required */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* check inlen */ + if (inlen > (MAX_RSA_SIZE/8)) { + return CRYPT_PK_INVALID_SIZE; + } + + if (prng_descriptor[wprng].read(buf, inlen*2-2, prng) != (inlen*2 - 2)) { + return CRYPT_ERROR_READPRNG; + } + + /* pad it like a sandwhich + * + * Looks like 0xFF R1 M R2 0xFF + * + * Where R1/R2 are random and exactly equal to the length of M minus one byte. + */ + for (x = 0; x < inlen-1; x++) { + out[x+1] = buf[x]; + } + + for (x = 0; x < inlen; x++) { + out[x+inlen] = in[x]; + } + + for (x = 0; x < inlen-1; x++) { + out[x+inlen+inlen] = buf[x+inlen-1]; + } + + /* last and first bytes are 0xFF */ + out[0] = out[inlen+inlen+inlen-1] = (unsigned char)0xFF; + + /* clear up and return */ +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + *outlen = inlen*3; + return CRYPT_OK; +} + +int rsa_signdepad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < inlen/3) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* check padding bytes */ + for (x = 0; x < inlen/3; x++) { + if (in[x] != (unsigned char)0xFF || in[x+(inlen/3)+(inlen/3)] != (unsigned char)0xFF) { + return CRYPT_INVALID_PACKET; + } + } + for (x = 0; x < inlen/3; x++) { + out[x] = in[x+(inlen/3)]; + } + *outlen = inlen/3; + return CRYPT_OK; +} + +int rsa_depad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < inlen/3) { + return CRYPT_BUFFER_OVERFLOW; + } + for (x = 0; x < inlen/3; x++) { + out[x] = in[x+(inlen/3)]; + } + *outlen = inlen/3; + return CRYPT_OK; +} + +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) +{ + unsigned long y, z; + int err; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 1)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* type valid? */ + if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) && + (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) { + return CRYPT_PK_INVALID_TYPE; + } + + /* start at offset y=PACKET_SIZE */ + y = PACKET_SIZE; + + /* output key type */ + out[y++] = type; + + /* output modulus */ + OUTPUT_BIGNUM(&key->N, out, y, z); + + /* output public key */ + OUTPUT_BIGNUM(&key->e, out, y, z); + + if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) { + OUTPUT_BIGNUM(&key->d, out, y, z); + } + + if (type == PK_PRIVATE_OPTIMIZED) { + OUTPUT_BIGNUM(&key->dQ, out, y, z); + OUTPUT_BIGNUM(&key->dP, out, y, z); + OUTPUT_BIGNUM(&key->pQ, out, y, z); + OUTPUT_BIGNUM(&key->qP, out, y, z); + OUTPUT_BIGNUM(&key->p, out, y, z); + OUTPUT_BIGNUM(&key->q, out, y, z); + } + + /* store packet header */ + packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY); + + /* copy to the user buffer */ + *outlen = y; + + /* clear stack and return */ + return CRYPT_OK; +} + +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + unsigned long x, y; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if (inlen < (1+PACKET_SIZE)) { + return CRYPT_INVALID_PACKET; + } + + /* test packet header */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, + &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* get key type */ + y = PACKET_SIZE; + key->type = (int)in[y++]; + + /* load the modulus */ + INPUT_BIGNUM(&key->N, in, x, y, inlen); + + /* load public exponent */ + INPUT_BIGNUM(&key->e, in, x, y, inlen); + + /* get private exponent */ + if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) { + INPUT_BIGNUM(&key->d, in, x, y, inlen); + } + + /* get CRT private data if required */ + if (key->type == PK_PRIVATE_OPTIMIZED) { + INPUT_BIGNUM(&key->dQ, in, x, y, inlen); + INPUT_BIGNUM(&key->dP, in, x, y, inlen); + INPUT_BIGNUM(&key->pQ, in, x, y, inlen); + INPUT_BIGNUM(&key->qP, in, x, y, inlen); + INPUT_BIGNUM(&key->p, in, x, y, inlen); + INPUT_BIGNUM(&key->q, in, x, y, inlen); + } + + /* free up ram not required */ + if (key->type != PK_PRIVATE_OPTIMIZED) { + mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL); + } + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + mp_clear(&key->d); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, + &key->pQ, &key->qP, &key->p, &key->q, NULL); + return err; +} + +#include "rsa_sys.c" + +#endif /* RSA */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsa_exptmod.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RSA Code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MRSA + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key) +{ + mp_int tmp, tmpa, tmpb; + unsigned long x; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != MP_OKAY) { goto error; } + if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } + + /* sanity check on the input */ + if (mp_cmp(&key->N, &tmp) == MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto done; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY) { goto error; } + + /* tmp = tmpa*qP + tmpb*pQ mod N */ + if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&tmpb, &key->pQ, &tmpb)) != MP_OKAY) { goto error; } + if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY) { goto error; } + } else { + /* exptmod it */ + if ((err = mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp)) != MP_OKAY) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(&tmp); + if (x > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + *outlen = x; + + /* convert it */ + if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { goto error; } + + /* clean up and return */ + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp, &tmpa, &tmpb, NULL); + return err; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsa_free.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,24 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RSA Code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MRSA + +void rsa_free(rsa_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsa_make_key.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,113 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* RSA Code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MRSA + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) +{ + mp_int p, q, tmp1, tmp2, tmp3; + int err; + + _ARGCHK(key != NULL); + + if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if ((err = mp_set_int(&tmp3, e)) != MP_OKAY) { goto error; } /* tmp3 = e */ + + /* make prime "p" */ + do { + if ((err = rand_prime(&p, size*4, prng, wprng)) != CRYPT_OK) { goto done; } + if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY) { goto error; } /* tmp1 = p-1 */ + if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if ((err = rand_prime(&q, size*4, prng, wprng)) != CRYPT_OK) { goto done; } + if ((err = mp_sub_d(&q, 1, &tmp1)) != MP_OKAY) { goto error; } /* tmp1 = q-1 */ + if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if ((err = mp_sub_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if ((err = mp_lcm(&tmp1, &tmp2, &tmp1)) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */ + + /* make key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) { + goto error; + } + + if ((err = mp_set_int(&key->e, e)) != MP_OKAY) { goto error2; } /* key->e = e */ + if ((err = mp_invmod(&key->e, &tmp1, &key->d)) != MP_OKAY) { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */ + if ((err = mp_mul(&p, &q, &key->N)) != MP_OKAY) { goto error2; } /* key->N = pq */ + +/* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY) { goto error2; } /* tmp1 = q-1 */ + if ((err = mp_sub_d(&q, 1, &tmp2)) != MP_OKAY) { goto error2; } /* tmp2 = p-1 */ + + if ((err = mp_mod(&key->d, &tmp1, &key->dP)) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */ + if ((err = mp_mod(&key->d, &tmp2, &key->dQ)) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */ + + if ((err = mp_invmod(&q, &p, &key->qP)) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */ + if ((err = mp_mulmod(&key->qP, &q, &key->N, &key->qP)) != MP_OKAY) { goto error2; } /* qP = q * (1/q mod p) mod N */ + + if ((err = mp_invmod(&p, &q, &key->pQ)) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */ + if ((err = mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) != MP_OKAY) { goto error2; } /* pQ = p * (1/p mod q) mod N */ + + if ((err = mp_copy(&p, &key->p)) != MP_OKAY) { goto error2; } + if ((err = mp_copy(&q, &key->q)) != MP_OKAY) { goto error2; } + + /* shrink ram required */ + if ((err = mp_shrink(&key->e)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->d)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->N)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->dQ)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->dP)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->qP)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->pQ)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error2; } + if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error2; } + + err = CRYPT_OK; + key->type = PK_PRIVATE_OPTIMIZED; + goto done; +error2: + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL); +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL); + return err; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsa_sys.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,274 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* these are smaller routines written by Clay Culver. They do the same function as the rsa_encrypt/decrypt + * except that they are used to RSA encrypt/decrypt a single value and not a packet. + */ +int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, + unsigned char *outkey, unsigned long *outlen, + prng_state *prng, int wprng, rsa_key *key) +{ + unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK]; + unsigned long x, y, rsa_size; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* only allow keys from 64 to 256 bits */ + if (inlen < 8 || inlen > 32) { + return CRYPT_INVALID_ARG; + } + + /* are the parameters valid? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* rsa_pad the symmetric key */ + y = (unsigned long)sizeof(rsa_in); + if ((err = rsa_pad(inkey, inlen, rsa_in, &y, wprng, prng)) != CRYPT_OK) { + return CRYPT_ERROR; + } + + /* rsa encrypt it */ + rsa_size = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(rsa_in, y, rsa_out, &rsa_size, PK_PUBLIC, key)) != CRYPT_OK) { + return CRYPT_ERROR; + } + + /* check size */ + if (*outlen < (PACKET_SIZE+4+rsa_size)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY); + + /* now lets make the header */ + y = PACKET_SIZE; + + /* store the size of the RSA value */ + STORE32L(rsa_size, (outkey+y)); + y += 4; + + /* store the rsa value */ + for (x = 0; x < rsa_size; x++, y++) { + outkey[y] = rsa_out[x]; + } + + *outlen = y; +#ifdef CLEAN_STACK + /* clean up */ + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + + return CRYPT_OK; +} + +int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + rsa_key *key) +{ + unsigned char sym_key[MAXBLOCKSIZE], rsa_out[RSA_STACK]; + unsigned long x, y, z, i, rsa_size; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (inlen < PACKET_SIZE+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+4; + } + + /* check the header */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* grab length of the rsa key */ + y = PACKET_SIZE; + LOAD32L(rsa_size, (in+y)); + if (inlen < rsa_size) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= rsa_size; + } + y += 4; + + /* decrypt it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(in+y, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) { + return err; + } + y += rsa_size; + + /* depad it */ + z = (unsigned long)sizeof(sym_key); + if ((err = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (*keylen < z) { + return CRYPT_BUFFER_OVERFLOW; + } + + for (i = 0; i < z; i++) { + outkey[i] = sym_key[i]; + } + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(sym_key, sizeof(sym_key)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + *keylen = z; + return CRYPT_OK; +} + +int rsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + rsa_key *key) +{ + unsigned long rsa_size, x, y; + unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK]; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* reject nonsense sizes */ + if (inlen > (512/3) || inlen < 16) { + return CRYPT_INVALID_ARG; + } + + /* type of key? */ + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* pad it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_signpad(in, inlen, rsa_out, &x)) != CRYPT_OK) { + return err; + } + + /* sign it */ + rsa_size = (unsigned long)sizeof(rsa_in); + if ((err = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (*outlen < (PACKET_SIZE+4+rsa_size)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* now lets output the message */ + y = PACKET_SIZE; + + /* output the len */ + STORE32L(rsa_size, (out+y)); + y += 4; + + /* store the signature */ + for (x = 0; x < rsa_size; x++, y++) { + out[y] = rsa_in[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED); + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + *outlen = y; + return CRYPT_OK; +} + +int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *md, int *stat, rsa_key *key) +{ + unsigned long rsa_size, x, y, z; + unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK]; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(md != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* always be incorrect by default */ + *stat = 0; + + if (siglen < PACKET_SIZE+4) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= PACKET_SIZE+4; + } + + /* verify header */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get the len */ + y = PACKET_SIZE; + LOAD32L(rsa_size, (sig+y)); + if (siglen < rsa_size) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= rsa_size; + } + y += 4; + + /* exptmod it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(sig+y, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) { + return err; + } + y += rsa_size; + + /* depad it */ + z = (unsigned long)sizeof(rsa_in); + if ((err = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) { + return err; + } + + /* check? */ + if (memcmp(rsa_in, md, (size_t)z) == 0) { + *stat = 1; + } + +#ifdef CLEAN_STACK + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + return CRYPT_OK; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/s_ocb_done.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,102 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* OCB Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef OCB_MODE + +/* Since the last block is encrypted in CTR mode the same code can + * be used to finish a decrypt or encrypt stream. The only difference + * is we XOR the final ciphertext into the checksum so we have to xor it + * before we CTR [decrypt] or after [encrypt] + * + * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... + */ +int __ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode) + +{ + unsigned char Z[MAXBLOCKSIZE], Y[MAXBLOCKSIZE], X[MAXBLOCKSIZE]; + int err, x; + + _ARGCHK(ocb != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(tag != NULL); + _ARGCHK(taglen != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length || + (int)ptlen > ocb->block_len || (int)ptlen < 0) { + return CRYPT_INVALID_ARG; + } + + /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */ + ocb_shift_xor(ocb, X); + memcpy(Z, X, ocb->block_len); + + X[ocb->block_len-1] ^= (ptlen*8)&255; + X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255; + for (x = 0; x < ocb->block_len; x++) { + X[x] ^= ocb->Lr[x]; + } + + /* Y[m] = E(X[m])) */ + cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key); + + if (mode == 1) { + /* decrypt mode, so let's xor it first */ + /* xor C[m] into checksum */ + for (x = 0; x < (int)ptlen; x++) { + ocb->checksum[x] ^= ct[x]; + } + } + + /* C[m] = P[m] xor Y[m] */ + for (x = 0; x < (int)ptlen; x++) { + ct[x] = pt[x] ^ Y[x]; + } + + if (mode == 0) { + /* encrypt mode */ + /* xor C[m] into checksum */ + for (x = 0; x < (int)ptlen; x++) { + ocb->checksum[x] ^= ct[x]; + } + } + + /* xor Y[m] and Z[m] into checksum */ + for (x = 0; x < ocb->block_len; x++) { + ocb->checksum[x] ^= Y[x] ^ Z[x]; + } + + /* encrypt checksum, er... tag!! */ + cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key); + + /* now store it */ + for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { + tag[x] = X[x]; + } + *taglen = x; + +#ifdef CLEAN_STACK + zeromem(X, sizeof(X)); + zeromem(Y, sizeof(Y)); + zeromem(Z, sizeof(Z)); + zeromem(ocb, sizeof(*ocb)); +#endif + return CRYPT_OK; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/safer.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,468 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/******************************************************************************* +* +* FILE: safer.c +* +* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption +* Routine) in its four versions: SAFER K-64, SAFER K-128, +* SAFER SK-64 and SAFER SK-128. +* +* AUTHOR: Richard De Moliner ([email protected]) +* Signal and Information Processing Laboratory +* Swiss Federal Institute of Technology +* CH-8092 Zuerich, Switzerland +* +* DATE: September 9, 1995 +* +* CHANGE HISTORY: +* +*******************************************************************************/ + +#include <mycrypt.h> + +#ifdef SAFER + +const struct _cipher_descriptor + safer_k64_desc = { + "safer-k64", + 8, 8, 8, 8, SAFER_K64_DEFAULT_NOF_ROUNDS, + &safer_k64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_k64_test, + &safer_64_keysize + }, + + safer_sk64_desc = { + "safer-sk64", + 9, 8, 8, 8, SAFER_SK64_DEFAULT_NOF_ROUNDS, + &safer_sk64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk64_test, + &safer_64_keysize + }, + + safer_k128_desc = { + "safer-k128", + 10, 16, 16, 8, SAFER_K128_DEFAULT_NOF_ROUNDS, + &safer_k128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_128_keysize + }, + + safer_sk128_desc = { + "safer-sk128", + 11, 16, 16, 8, SAFER_SK128_DEFAULT_NOF_ROUNDS, + &safer_sk128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_128_keysize + }; + +/******************* Constants ************************************************/ +// #define TAB_LEN 256 + +/******************* Assertions ***********************************************/ + +/******************* Macros ***************************************************/ +#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ + |(unsigned int)((x) & 0xFF) >> (8 - (n)))) +#define EXP(x) safer_ebox[(x) & 0xFF] +#define LOG(x) safer_lbox[(x) & 0xFF] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +/******************* Types ****************************************************/ +extern const unsigned char safer_ebox[], safer_lbox[]; + +#ifdef CLEAN_STACK +static void _Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#else +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#endif +{ unsigned int i, j, k; + unsigned char ka[SAFER_BLOCK_LEN + 1]; + unsigned char kb[SAFER_BLOCK_LEN + 1]; + + if (SAFER_MAX_NOF_ROUNDS < nof_rounds) + nof_rounds = SAFER_MAX_NOF_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[SAFER_BLOCK_LEN] = (unsigned char)0; + kb[SAFER_BLOCK_LEN] = (unsigned char)0; + k = 0; + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + ka[j] = ROL8(userkey_1[j], 5); + ka[SAFER_BLOCK_LEN] ^= ka[j]; + kb[j] = *key++ = userkey_2[j]; + kb[SAFER_BLOCK_LEN] ^= kb[j]; + } + for (i = 1; i <= nof_rounds; i++) { + for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) { + ka[j] = ROL8(ka[j], 6); + kb[j] = ROL8(kb[j], 6); + } + if (strengthened) { + k = 2 * i - 1; + while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (ka[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + } + } + if (strengthened) { + k = 2 * i; + while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (kb[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + } + } + } + +#ifdef CLEAN_STACK + zeromem(ka, sizeof(ka)); + zeromem(kb, sizeof(kb)); +#endif +} + +#ifdef CLEAN_STACK +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +{ + _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); + burn_stack(sizeof(unsigned char) * (2 * (SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); +} +#endif + +int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +void safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + _ARGCHK(block_in != NULL); + _ARGCHK(block_out != NULL); + _ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; + while(round-- > 0) + { + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + a = EXP(a) + *++key; b = LOG(b) ^ *++key; + c = LOG(c) ^ *++key; d = EXP(d) + *++key; + e = EXP(e) + *++key; f = LOG(f) ^ *++key; + g = LOG(g) ^ *++key; h = EXP(h) + *++key; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; +} + +#ifdef CLEAN_STACK +void safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + _safer_ecb_encrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); +} +#endif + +#ifdef CLEAN_STACK +static void _safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +void safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + _ARGCHK(block_in != NULL); + _ARGCHK(block_out != NULL); + _ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; + key += SAFER_BLOCK_LEN * (1 + 2 * round); + h ^= *key; g -= *--key; f -= *--key; e ^= *--key; + d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; + while (round--) + { + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; + d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; + h = LOG(h) ^ *--key; g = EXP(g) - *--key; + f = EXP(f) - *--key; e = LOG(e) ^ *--key; + d = LOG(d) ^ *--key; c = EXP(c) - *--key; + b = EXP(b) - *--key; a = LOG(a) ^ *--key; + } + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; +} + +#ifdef CLEAN_STACK +void safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + _safer_ecb_decrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); +} +#endif + +int safer_64_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 8; + return CRYPT_OK; + } +} + +int safer_128_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +int safer_k64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, + k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err; + + /* test K64 */ + if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(k64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], k64_ct, 8) != 0 || memcmp(buf[1], k64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + + +int safer_sk64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK64 */ + if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + + safer_ecb_encrypt(sk64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], sk64_ct, 8) != 0 || memcmp(buf[1], sk64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +int safer_sk128_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0 }, + sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK128 */ + if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(sk128_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], sk128_ct, 8) != 0 || memcmp(buf[1], sk128_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + return CRYPT_OK; + #endif +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/safer_tab.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,59 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +#include "mycrypt.h" + +#if defined(SAFERP) || defined(SAFER) + +/* This is the box defined by ebox[x] = 45^x mod 257. + * Its assumed that the value "256" corresponds to zero. */ +const unsigned char safer_ebox[256] = { + 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, +255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, +241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, +129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, +249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, +193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, +128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, +253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, +225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 +}; + +/* This is the inverse of ebox or the base 45 logarithm */ +const unsigned char safer_lbox[256] = { +128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, +192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, +112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, +201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, +175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, +121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, +189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, +208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, +210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, +164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, +122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, +109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, +184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 +}; + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/saferp.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,510 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* SAFER+ Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef SAFERP + +const struct _cipher_descriptor saferp_desc = +{ + "safer+", + 4, + 16, 32, 16, 8, + &saferp_setup, + &saferp_ecb_encrypt, + &saferp_ecb_decrypt, + &saferp_test, + &saferp_keysize +}; + +/* ROUND(b,i) + * + * This is one forward key application. Note the basic form is + * key addition, substitution, key addition. The safer_ebox and safer_lbox + * are the exponentiation box and logarithm boxes respectively. + * The value of 'i' is the current round number which allows this + * function to be unrolled massively. Most of SAFER+'s speed + * comes from not having to compute indirect accesses into the + * array of 16 bytes b[0..15] which is the block of data +*/ + +extern const unsigned char safer_ebox[], safer_lbox[]; + +#define ROUND(b, i) \ + b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ + b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ + b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ + b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ + b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ + b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ + b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ + b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ + b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ + b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ + b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ + b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ + b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ + b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ + b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ + b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; + +/* This is one inverse key application */ +#define iROUND(b, i) \ + b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ + b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ + b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ + b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ + b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ + b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ + b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ + b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ + b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ + b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ + b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ + b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ + b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ + b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ + b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ + b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; + +/* This is a forward single layer PHT transform. */ +#define PHT(b) \ + b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ + b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ + b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ + b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ + b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ + b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ + b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ + b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; + +/* This is an inverse single layer PHT transform */ +#define iPHT(b) \ + b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ + b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ + b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ + b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ + b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ + b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ + b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ + b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \ + +/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ +#define SHUF(b, b2) \ + b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ + b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ + b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ + b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; + +/* This is the inverse shuffle. It takes from b and gives to b2 */ +#define iSHUF(b, b2) \ + b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ + b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ + b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ + b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; + +/* The complete forward Linear Transform layer. + * Note that alternating usage of b and b2. + * Each round of LT starts in 'b' and ends in 'b2'. + */ +#define LT(b, b2) \ + PHT(b); SHUF(b, b2); \ + PHT(b2); SHUF(b2, b); \ + PHT(b); SHUF(b, b2); \ + PHT(b2); + +/* This is the inverse linear transform layer. */ +#define iLT(b, b2) \ + iPHT(b); \ + iSHUF(b, b2); iPHT(b2); \ + iSHUF(b2, b); iPHT(b); \ + iSHUF(b, b2); iPHT(b2); + +#ifdef SMALL_CODE + +static void _round(unsigned char *b, int i, symmetric_key *skey) +{ + ROUND(b, i); +} + +static void _iround(unsigned char *b, int i, symmetric_key *skey) +{ + iROUND(b, i); +} + +static void _lt(unsigned char *b, unsigned char *b2) +{ + LT(b, b2); +} + +static void _ilt(unsigned char *b, unsigned char *b2) +{ + iLT(b, b2); +} + +#undef ROUND +#define ROUND(b, i) _round(b, i, skey) + +#undef iROUND +#define iROUND(b, i) _iround(b, i, skey) + +#undef LT +#define LT(b, b2) _lt(b, b2) + +#undef iLT +#define iLT(b, b2) _ilt(b, b2) + +#endif + +/* These are the 33, 128-bit bias words for the key schedule */ +static const unsigned char safer_bias[33][16] = { +{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100}, +{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61}, +{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160}, +{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148}, +{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143}, +{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202}, +{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44}, +{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51}, +{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56}, +{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215}, +{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210}, +{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53}, +{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244}, +{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131}, +{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241}, +{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172}, +{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239}, +{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202}, +{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246}, +{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152}, +{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236}, +{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150}, +{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30}, +{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6}, +{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104}, +{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175}, +{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35}, +{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7}, +{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207}, +{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247}, +{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255}, +{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; + +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned x, y, z; + unsigned char t[33]; + static const int rounds[3] = { 8, 12, 16 }; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* Is the number of rounds valid? Either use zero for default or + * 8,12,16 rounds for 16,24,32 byte keys + */ + if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { + return CRYPT_INVALID_ROUNDS; + } + + /* 128 bit key version */ + if (keylen == 16) { + /* copy key into t */ + for (x = y = 0; x < 16; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[16] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + /* make the 16 other keys as a transformation of the first key */ + for (x = 1; x < 17; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 17; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 17) { z = 0; } + } + } + skey->saferp.rounds = 8; + } else if (keylen == 24) { + /* copy key into t */ + for (x = y = 0; x < 24; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[24] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 25; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 25; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 25) { z = 0; } + } + } + skey->saferp.rounds = 12; + } else { + /* copy key into t */ + for (x = y = 0; x < 32; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[32] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 33; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 33; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 33) { z = 0; } + } + } + skey->saferp.rounds = 16; + } +#ifdef CLEAN_STACK + zeromem(t, sizeof(t)); +#endif + return CRYPT_OK; +} + +void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + /* do eight rounds */ + for (x = 0; x < 16; x++) { + b[x] = pt[x]; + } + ROUND(b, 0); LT(b, ct); + ROUND(ct, 2); LT(ct, b); + ROUND(b, 4); LT(b, ct); + ROUND(ct, 6); LT(ct, b); + ROUND(b, 8); LT(b, ct); + ROUND(ct, 10); LT(ct, b); + ROUND(b, 12); LT(b, ct); + ROUND(ct, 14); LT(ct, b); + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + ROUND(b, 16); LT(b, ct); + ROUND(ct, 18); LT(ct, b); + ROUND(b, 20); LT(b, ct); + ROUND(ct, 22); LT(ct, b); + } + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + ROUND(b, 24); LT(b, ct); + ROUND(ct, 26); LT(ct, b); + ROUND(b, 28); LT(b, ct); + ROUND(ct, 30); LT(ct, b); + } + ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; +#ifdef CLEAN_STACK + zeromem(b, sizeof(b)); +#endif +} + +void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + /* do eight rounds */ + b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + iLT(b, pt); iROUND(pt, 30); + iLT(pt, b); iROUND(b, 28); + iLT(b, pt); iROUND(pt, 26); + iLT(pt, b); iROUND(b, 24); + } + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + iLT(b, pt); iROUND(pt, 22); + iLT(pt, b); iROUND(b, 20); + iLT(b, pt); iROUND(pt, 18); + iLT(pt, b); iROUND(b, 16); + } + iLT(b, pt); iROUND(pt, 14); + iLT(pt, b); iROUND(b, 12); + iLT(b, pt); iROUND(pt,10); + iLT(pt, b); iROUND(b, 8); + iLT(b, pt); iROUND(pt,6); + iLT(pt, b); iROUND(b, 4); + iLT(b, pt); iROUND(pt,2); + iLT(pt, b); iROUND(b, 0); + for (x = 0; x < 16; x++) { + pt[x] = b[x]; + } +#ifdef CLEAN_STACK + zeromem(b, sizeof(b)); +#endif +} + +int saferp_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 41, 35, 190, 132, 225, 108, 214, 174, + 82, 144, 73, 241, 241, 187, 233, 235 }, + { 179, 166, 219, 60, 135, 12, 62, 153, + 36, 94, 13, 28, 6, 183, 71, 222 }, + { 224, 31, 182, 10, 12, 255, 84, 70, + 127, 13, 89, 249, 9, 57, 165, 220 } + }, { + 24, + { 72, 211, 143, 117, 230, 217, 29, 42, + 229, 192, 247, 43, 120, 129, 135, 68, + 14, 95, 80, 0, 212, 97, 141, 190 }, + { 123, 5, 21, 7, 59, 51, 130, 31, + 24, 112, 146, 218, 100, 84, 206, 177 }, + { 92, 136, 4, 63, 57, 95, 100, 0, + 150, 130, 130, 16, 193, 111, 219, 133 } + }, { + 32, + { 243, 168, 141, 254, 190, 242, 235, 113, + 255, 160, 208, 59, 117, 6, 140, 126, + 135, 120, 115, 77, 208, 190, 130, 190, + 219, 194, 70, 65, 43, 140, 250, 48 }, + { 127, 112, 240, 167, 84, 134, 50, 149, + 170, 91, 104, 19, 11, 230, 252, 245 }, + { 88, 11, 25, 36, 172, 229, 202, 213, + 170, 65, 105, 153, 220, 104, 153, 138 } + } + }; + + unsigned char tmp[2][16]; + symmetric_key skey; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey); + saferp_ecb_decrypt(tmp[0], tmp[1], &skey); + + /* compare */ + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int saferp_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + } else { + *desired_keysize = 32; + } + return CRYPT_OK; +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serpent.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,698 @@ +#include "mycrypt.h" + +#ifdef SERPENT + +const struct _cipher_descriptor serpent_desc = +{ + "serpent", + 5, + 16, 32, 16, 32, + &serpent_setup, + &serpent_ecb_encrypt, + &serpent_ecb_decrypt, + &serpent_test, + &serpent_keysize +}; + +/* These defines are derived from Brian Gladman's work. Contact him at [email protected] + * + * Available on the web at http://fp.gladman.plus.com/cryptography_technology/aes/index.htm + */ +#define sb0(a,b,c,d,e,f,g,h) \ + t1 = a ^ d; \ + t2 = a & d; \ + t3 = c ^ t1; \ + t6 = b & t1; \ + t4 = b ^ t3; \ + t10 = ~t3; \ + h = t2 ^ t4; \ + t7 = a ^ t6; \ + t14 = ~t7; \ + t8 = c | t7; \ + t11 = t3 ^ t7; \ + g = t4 ^ t8; \ + t12 = h & t11; \ + f = t10 ^ t12; \ + e = t12 ^ t14 + +/* 15 terms */ + +#define ib0(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = t1 | t2; \ + t4 = d ^ t3; \ + t7 = d & t2; \ + t5 = c ^ t4; \ + t8 = t1 ^ t7; \ + g = t2 ^ t5; \ + t11 = a & t4; \ + t9 = g & t8; \ + t14 = t5 ^ t8; \ + f = t4 ^ t9; \ + t12 = t5 | f; \ + h = t11 ^ t12; \ + e = h ^ t14 + +/* 14 terms! */ + +#define sb1(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = b ^ t1; \ + t3 = a | t2; \ + t4 = d | t2; \ + t5 = c ^ t3; \ + g = d ^ t5; \ + t7 = b ^ t4; \ + t8 = t2 ^ g; \ + t9 = t5 & t7; \ + h = t8 ^ t9; \ + t11 = t5 ^ t7; \ + f = h ^ t11; \ + t13 = t8 & t11; \ + e = t5 ^ t13 + +/* 17 terms */ + +#define ib1(a,b,c,d,e,f,g,h) \ + t1 = a ^ d; \ + t2 = a & b; \ + t3 = b ^ c; \ + t4 = a ^ t3; \ + t5 = b | d; \ + t7 = c | t1; \ + h = t4 ^ t5; \ + t8 = b ^ t7; \ + t11 = ~t2; \ + t9 = t4 & t8; \ + f = t1 ^ t9; \ + t13 = t9 ^ t11; \ + t12 = h & f; \ + g = t12 ^ t13; \ + t15 = a & d; \ + t16 = c ^ t13; \ + e = t15 ^ t16 + +/* 16 terms */ + +#define sb2(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = b ^ d; \ + t3 = c & t1; \ + t13 = d | t1; \ + e = t2 ^ t3; \ + t5 = c ^ t1; \ + t6 = c ^ e; \ + t7 = b & t6; \ + t10 = e | t5; \ + h = t5 ^ t7; \ + t9 = d | t7; \ + t11 = t9 & t10; \ + t14 = t2 ^ h; \ + g = a ^ t11; \ + t15 = g ^ t13; \ + f = t14 ^ t15 + +/* 16 terms */ + +#define ib2(a,b,c,d,e,f,g,h) \ + t1 = b ^ d; \ + t2 = ~t1; \ + t3 = a ^ c; \ + t4 = c ^ t1; \ + t7 = a | t2; \ + t5 = b & t4; \ + t8 = d ^ t7; \ + t11 = ~t4; \ + e = t3 ^ t5; \ + t9 = t3 | t8; \ + t14 = d & t11; \ + h = t1 ^ t9; \ + t12 = e | h; \ + f = t11 ^ t12; \ + t15 = t3 ^ t12; \ + g = t14 ^ t15 + +/* 17 terms */ + +#define sb3(a,b,c,d,e,f,g,h) \ + t1 = a ^ c; \ + t2 = d ^ t1; \ + t3 = a & t2; \ + t4 = d ^ t3; \ + t5 = b & t4; \ + g = t2 ^ t5; \ + t7 = a | g; \ + t8 = b | d; \ + t11 = a | d; \ + t9 = t4 & t7; \ + f = t8 ^ t9; \ + t12 = b ^ t11; \ + t13 = g ^ t9; \ + t15 = t3 ^ t8; \ + h = t12 ^ t13; \ + t16 = c & t15; \ + e = t12 ^ t16 + +/* 16 term solution that performs less well than 17 term one + in my environment (PPro/PII) + +#define sb3(a,b,c,d,e,f,g,h) \ + t1 = a ^ b; \ + t2 = a & c; \ + t3 = a | d; \ + t4 = c ^ d; \ + t5 = t1 & t3; \ + t6 = t2 | t5; \ + g = t4 ^ t6; \ + t8 = b ^ t3; \ + t9 = t6 ^ t8; \ + t10 = t4 & t9; \ + e = t1 ^ t10; \ + t12 = g & e; \ + f = t9 ^ t12; \ + t14 = b | d; \ + t15 = t4 ^ t12; \ + h = t14 ^ t15 +*/ + +/* 17 terms */ + +#define ib3(a,b,c,d,e,f,g,h) \ + t1 = b ^ c; \ + t2 = b | c; \ + t3 = a ^ c; \ + t7 = a ^ d; \ + t4 = t2 ^ t3; \ + t5 = d | t4; \ + t9 = t2 ^ t7; \ + e = t1 ^ t5; \ + t8 = t1 | t5; \ + t11 = a & t4; \ + g = t8 ^ t9; \ + t12 = e | t9; \ + f = t11 ^ t12; \ + t14 = a & g; \ + t15 = t2 ^ t14; \ + t16 = e & t15; \ + h = t4 ^ t16 + +/* 15 terms */ + +#define sb4(a,b,c,d,e,f,g,h) \ + t1 = a ^ d; \ + t2 = d & t1; \ + t3 = c ^ t2; \ + t4 = b | t3; \ + h = t1 ^ t4; \ + t6 = ~b; \ + t7 = t1 | t6; \ + e = t3 ^ t7; \ + t9 = a & e; \ + t10 = t1 ^ t6; \ + t11 = t4 & t10; \ + g = t9 ^ t11; \ + t13 = a ^ t3; \ + t14 = t10 & g; \ + f = t13 ^ t14 + +/* 17 terms */ + +#define ib4(a,b,c,d,e,f,g,h) \ + t1 = c ^ d; \ + t2 = c | d; \ + t3 = b ^ t2; \ + t4 = a & t3; \ + f = t1 ^ t4; \ + t6 = a ^ d; \ + t7 = b | d; \ + t8 = t6 & t7; \ + h = t3 ^ t8; \ + t10 = ~a; \ + t11 = c ^ h; \ + t12 = t10 | t11;\ + e = t3 ^ t12; \ + t14 = c | t4; \ + t15 = t7 ^ t14; \ + t16 = h | t10; \ + g = t15 ^ t16 + +/* 16 terms */ + +#define sb5(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = a ^ d; \ + t4 = c ^ t1; \ + t5 = t2 | t3; \ + e = t4 ^ t5; \ + t7 = d & e; \ + t8 = t2 ^ e; \ + t10 = t1 | e; \ + f = t7 ^ t8; \ + t11 = t2 | t7; \ + t12 = t3 ^ t10; \ + t14 = b ^ t7; \ + g = t11 ^ t12; \ + t15 = f & t12; \ + h = t14 ^ t15 + +/* 16 terms */ + +#define ib5(a,b,c,d,e,f,g,h) \ + t1 = ~c; \ + t2 = b & t1; \ + t3 = d ^ t2; \ + t4 = a & t3; \ + t5 = b ^ t1; \ + h = t4 ^ t5; \ + t7 = b | h; \ + t8 = a & t7; \ + f = t3 ^ t8; \ + t10 = a | d; \ + t11 = t1 ^ t7; \ + e = t10 ^ t11; \ + t13 = a ^ c; \ + t14 = b & t10; \ + t15 = t4 | t13; \ + g = t14 ^ t15 + +/* 15 terms */ + +#define sb6(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ d; \ + t3 = b ^ t2; \ + t4 = t1 | t2; \ + t5 = c ^ t4; \ + f = b ^ t5; \ + t13 = ~t5; \ + t7 = t2 | f; \ + t8 = d ^ t7; \ + t9 = t5 & t8; \ + g = t3 ^ t9; \ + t11 = t5 ^ t8; \ + e = g ^ t11; \ + t14 = t3 & t11; \ + h = t13 ^ t14 + +/* 15 terms */ + +#define ib6(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = c ^ t2; \ + t4 = c | t1; \ + t5 = d ^ t4; \ + t13 = d & t1; \ + f = t3 ^ t5; \ + t7 = t3 & t5; \ + t8 = t2 ^ t7; \ + t9 = b | t8; \ + h = t5 ^ t9; \ + t11 = b | h; \ + e = t8 ^ t11; \ + t14 = t3 ^ t11; \ + g = t13 ^ t14 + +/* 17 terms */ + +#define sb7(a,b,c,d,e,f,g,h) \ + t1 = ~c; \ + t2 = b ^ c; \ + t3 = b | t1; \ + t4 = d ^ t3; \ + t5 = a & t4; \ + t7 = a ^ d; \ + h = t2 ^ t5; \ + t8 = b ^ t5; \ + t9 = t2 | t8; \ + t11 = d & t3; \ + f = t7 ^ t9; \ + t12 = t5 ^ f; \ + t15 = t1 | t4; \ + t13 = h & t12; \ + g = t11 ^ t13; \ + t16 = t12 ^ g; \ + e = t15 ^ t16 + +/* 17 terms */ + +#define ib7(a,b,c,d,e,f,g,h) \ + t1 = a & b; \ + t2 = a | b; \ + t3 = c | t1; \ + t4 = d & t2; \ + h = t3 ^ t4; \ + t6 = ~d; \ + t7 = b ^ t4; \ + t8 = h ^ t6; \ + t11 = c ^ t7; \ + t9 = t7 | t8; \ + f = a ^ t9; \ + t12 = d | f; \ + e = t11 ^ t12; \ + t14 = a & h; \ + t15 = t3 ^ f; \ + t16 = e ^ t14; \ + g = t15 ^ t16 + +#define k_xor(r,a,b,c,d) \ + a ^= skey->serpent.K[4 * (r) + 0]; \ + b ^= skey->serpent.K[4 * (r) + 1]; \ + c ^= skey->serpent.K[4 * (r) + 2]; \ + d ^= skey->serpent.K[4 * (r) + 3] + +#define k_set(r,a,b,c,d) \ + a = lkey[4 * (r) + 8]; \ + b = lkey[4 * (r) + 9]; \ + c = lkey[4 * (r) + 10]; \ + d = lkey[4 * (r) + 11] + +#define k_get(r,a,b,c,d) \ + skey->serpent.K[4 * (r) + 0] = a; \ + skey->serpent.K[4 * (r) + 1] = b; \ + skey->serpent.K[4 * (r) + 2] = c; \ + skey->serpent.K[4 * (r) + 3] = d + +/* the linear transformation and its inverse */ + +#define rot(a,b,c,d) \ + a = ROL(a, 13); \ + c = ROL(c, 3); \ + d ^= c ^ (a << 3); \ + b ^= a ^ c; \ + d = ROL(d, 7); \ + b = ROL(b, 1); \ + a ^= b ^ d; \ + c ^= d ^ (b << 7); \ + a = ROL(a, 5); \ + c = ROL(c, 22) + +#define irot(a,b,c,d) \ + c = ROR(c, 22); \ + a = ROR(a, 5); \ + c ^= d ^ (b << 7); \ + a ^= b ^ d; \ + d = ROR(d, 7); \ + b = ROR(b, 1); \ + d ^= c ^ (a << 3); \ + b ^= a ^ c; \ + c = ROR(c, 3); \ + a = ROR(a, 13) + +#ifdef CLEAN_STACK +static int _serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + unsigned long lkey[140], t, a, b, c, d, e, f, g, h, x; + unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + unsigned char buf[32]; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check rounds */ + if (num_rounds != 0 && num_rounds != 32) { + return CRYPT_INVALID_ROUNDS; + } + + /* check keylen */ + if (keylen < 16 || keylen > 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* copy key and expand to 32bytes as required */ + for (x = 0; x < (unsigned long)keylen; x++) { + buf[x] = key[x]; + } + + if (x < 32) { + buf[x++] = (unsigned char)0x01; + while (x < 32) { + buf[x++] = (unsigned char)0; + } + } + + /* copy key into 32-bit words */ + for (x = 0; x < 8; x++) { + LOAD32L(lkey[x], &buf[x*4]); + } + + /* expand using the LFSR to 140 words */ + for (x = 0; x < 132; x++) { + t = lkey[x] ^ lkey[x+3] ^ lkey[x+5] ^ lkey[x+7] ^ x ^ 0x9E3779B9UL; + lkey[x + 8] = ROL(t, 11); + } + + /* perform the substituions */ + for (x = 0; x < 32; ) { + k_set( x,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + k_set( x,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x; + } + k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h); + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _serpent_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(unsigned long)*166 + sizeof(unsigned char)*32); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + unsigned long a,b,c,d,e,f,g,h; + unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + LOAD32L(a, &pt[0]);LOAD32L(b, &pt[4]);LOAD32L(c, &pt[8]);LOAD32L(d, &pt[12]); + k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d); + STORE32L(a, &ct[0]);STORE32L(b, &ct[4]);STORE32L(c, &ct[8]);STORE32L(d, &ct[12]); +} + +#ifdef CLEAN_STACK +void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + _serpent_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned long)*24); +} +#endif + +#ifdef CLEAN_STACK +static void _serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + unsigned long a,b,c,d,e,f,g,h; + unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + LOAD32L(a, &ct[0]);LOAD32L(b, &ct[4]);LOAD32L(c, &ct[8]);LOAD32L(d, &ct[12]); + k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d); + STORE32L(a, &pt[0]);STORE32L(b, &pt[4]);STORE32L(c, &pt[8]);STORE32L(d, &pt[12]); +} + +#ifdef CLEAN_STACK +void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + _serpent_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned long)*24); +} +#endif + +int serpent_test(void) +{ + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, + 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49 } + }, + { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0x4a, 0xe9, 0xa2, 0x0b, 0x2b, 0x14, 0xa1, 0x02, + 0x90, 0xcb, 0xb8, 0x20, 0xb7, 0xff, 0xb5, 0x10 } + }, + { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }, + { 0xe1, 0x1b, 0x01, 0x52, 0x4e, 0xa1, 0xf4, 0x65, + 0xa2, 0xa2, 0x00, 0x43, 0xeb, 0x9f, 0x7e, 0x8a } + }, + { + 32, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xe0, 0x88, 0x5d, 0x44, 0x60, 0x37, 0x34, 0x69, + 0xd1, 0xfa, 0x6c, 0x36, 0xa6, 0xe1, 0xc5, 0x2f } + }, + { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0xc6, 0x25, 0x8e, 0x60, 0x09, 0xe2, 0x82, + 0x66, 0x18, 0x69, 0xd5, 0x25, 0xf7, 0xd2, 0x04 } + }, + { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9f, 0xe1, 0x43, 0x25, 0x0d, 0x00, 0xe2, 0x56, + 0x96, 0xb0, 0x1e, 0x0a, 0x2e, 0xd0, 0x5d, 0xb3 } + } + }; + + unsigned char buf[2][16]; + int x, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key))!= CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + serpent_ecb_encrypt(tests[x].pt, buf[0], &key); + serpent_ecb_decrypt(buf[0], buf[1], &key); + + /* compare */ + if (memcmp(buf[0], tests[x].ct, 16) != 0 || memcmp(buf[1], tests[x].pt, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +int serpent_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize > 32) + *desired_keysize = 32; + return CRYPT_OK; +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sha1.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,223 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* SHA1 code by Tom St Denis */ +#include "mycrypt.h" + +#ifdef SHA1 + +const struct _hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test +}; + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#ifdef CLEAN_STACK +static void _sha1_compress(hash_state *md, unsigned char *buf) +#else +static void sha1_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 a,b,c,d,e,W[80],i; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->sha1.state[0]; + b = md->sha1.state[1]; + c = md->sha1.state[2]; + d = md->sha1.state[3]; + e = md->sha1.state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30); + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); + FF0(e,a,b,c,d,i++); + FF0(d,e,a,b,c,i++); + FF0(c,d,e,a,b,i++); + FF0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); + FF1(e,a,b,c,d,i++); + FF1(d,e,a,b,c,i++); + FF1(c,d,e,a,b,i++); + FF1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); + FF2(e,a,b,c,d,i++); + FF2(d,e,a,b,c,i++); + FF2(c,d,e,a,b,i++); + FF2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); + FF3(e,a,b,c,d,i++); + FF3(d,e,a,b,c,i++); + FF3(c,d,e,a,b,i++); + FF3(b,c,d,e,a,i++); + } + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->sha1.state[0] = md->sha1.state[0] + a; + md->sha1.state[1] = md->sha1.state[1] + b; + md->sha1.state[2] = md->sha1.state[2] + c; + md->sha1.state[3] = md->sha1.state[3] + d; + md->sha1.state[4] = md->sha1.state[4] + e; +} + +#ifdef CLEAN_STACK +static void sha1_compress(hash_state *md, unsigned char *buf) +{ + _sha1_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); +} +#endif + +void sha1_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; +} + +HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) + +int sha1_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha1.curlen >= sizeof(md->sha1.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + sha1_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + sha1_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha1_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha1_init(&md); + sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha1_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 20) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sha224.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* SHA-224 new NIST standard based off of SHA-256 truncated to 224 bits */ +const struct _hash_descriptor sha224_desc = +{ + "sha224", + 10, + 28, + 64, + &sha224_init, + &sha256_process, + &sha224_done, + &sha224_test +}; + +/* init the sha256 er... sha224 state ;-) */ +void sha224_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; +} + +int sha224_done(hash_state * md, unsigned char *hash) +{ + unsigned char buf[32]; + int err; + + err = sha256_done(md, buf); + memcpy(hash, buf, 28); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +int sha224_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, + 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, + 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, + 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, + 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, + 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, + 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } + }, + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha224_init(&md); + sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha224_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 28) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sha256.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,305 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + + +/* SHA256 by Tom St Denis */ + +#include "mycrypt.h" + +#ifdef SHA256 + +const struct _hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test +}; + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +/* compress 512-bits */ +#ifdef CLEAN_STACK +static void _sha256_compress(hash_state * md, unsigned char *buf) +#else +static void sha256_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong32 S[8], W[64], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha256.state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef SMALL_CODE +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + +#endif + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha256.state[i] = md->sha256.state[i] + S[i]; + } + +} + +#ifdef CLEAN_STACK +static void sha256_compress(hash_state * md, unsigned char *buf) +{ + _sha256_compress(md, buf); + burn_stack(sizeof(ulong32) * 74); +} +#endif + +/* init the sha256 state */ +void sha256_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; +} + +HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) + +int sha256_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha256.curlen >= sizeof(md->sha256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->sha256.length += md->sha256.curlen * 8; + + /* append the '1' bit */ + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha256.curlen > 56) { + while (md->sha256.curlen < 64) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + sha256_compress(md, md->sha256.buf); + md->sha256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha256.curlen < 56) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha256.length, md->sha256.buf+56); + sha256_compress(md, md->sha256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->sha256.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha256_init(&md); + sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 32) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef SHA224 +#include "sha224.c" +#endif + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sha384.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* included in sha512.c */ + +const struct _hash_descriptor sha384_desc = +{ + "sha384", + 4, + 48, + 128, + &sha384_init, + &sha512_process, + &sha384_done, + &sha384_test +}; + +void sha384_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); + md->sha512.state[1] = CONST64(0x629a292a367cd507); + md->sha512.state[2] = CONST64(0x9159015a3070dd17); + md->sha512.state[3] = CONST64(0x152fecd8f70e5939); + md->sha512.state[4] = CONST64(0x67332667ffc00b31); + md->sha512.state[5] = CONST64(0x8eb44a8768581511); + md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); + md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); +} + +int sha384_done(hash_state * md, unsigned char *hash) +{ + unsigned char buf[64]; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + memcpy(hash, buf, 48); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +int sha384_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[48]; + } tests[] = { + { "abc", + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } + }, + }; + + int i; + unsigned char tmp[48]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha384_init(&md); + sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha384_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 48) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sha512.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,282 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* SHA512 by Tom St Denis */ + +#include "mycrypt.h" + +#ifdef SHA512 + +const struct _hash_descriptor sha512_desc = +{ + "sha512", + 5, + 64, + 128, + &sha512_init, + &sha512_process, + &sha512_done, + &sha512_test +}; + +/* the K array */ +static const ulong64 K[80] = { +CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), +CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), +CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), +CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), +CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), +CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), +CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), +CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), +CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), +CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), +CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), +CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), +CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), +CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), +CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), +CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), +CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), +CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), +CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), +CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), +CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), +CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), +CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), +CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), +CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), +CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), +CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), +CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), +CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), +CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), +CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), +CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), +CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), +CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), +CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), +CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), +CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), +CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), +CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), +CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64((x),(n)) +#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + +/* compress 1024-bits */ +#ifdef CLEAN_STACK +static void _sha512_compress(hash_state * md, unsigned char *buf) +#else +static void sha512_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong64 S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha512.state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef SMALL_CODE + for (i = 0; i < 80; i++) { + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; + t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3] + t0; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t0 + t1; + } +#else +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#endif + + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha512.state[i] = md->sha512.state[i] + S[i]; + } +} + +/* compress 1024-bits */ +#ifdef CLEAN_STACK +static void sha512_compress(hash_state * md, unsigned char *buf) +{ + _sha512_compress(md, buf); + burn_stack(sizeof(ulong64) * 90 + sizeof(int)); +} +#endif + +/* init the sha512 state */ +void sha512_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); + md->sha512.state[1] = CONST64(0xbb67ae8584caa73b); + md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b); + md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1); + md->sha512.state[4] = CONST64(0x510e527fade682d1); + md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); + md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); + md->sha512.state[7] = CONST64(0x5be0cd19137e2179); +} + +HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) + +int sha512_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha512.length += md->sha512.curlen * CONST64(8); + + /* append the '1' bit */ + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha512.curlen > 112) { + while (md->sha512.curlen < 128) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + sha512_compress(md, md->sha512.buf); + md->sha512.curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while (md->sha512.curlen < 120) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha512.length, md->sha512.buf+120); + sha512_compress(md, md->sha512.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->sha512.state[i], hash+(8*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha512_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[64]; + } tests[] = { + { "abc", + { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } + }, + }; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_init(&md); + sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 64) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef SHA384 + #include "sha384.c" +#endif + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/skipjack.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,290 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Skipjack Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef SKIPJACK + +const struct _cipher_descriptor skipjack_desc = +{ + "skipjack", + 17, + 10, 10, 8, 32, + &skipjack_setup, + &skipjack_ecb_encrypt, + &skipjack_ecb_decrypt, + &skipjack_test, + &skipjack_keysize +}; + +static const unsigned char sbox[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/* simple x + 1 (mod 10) in one step. */ +static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + +/* simple x - 1 (mod 10) in one step */ +static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 10) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 32 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* make sure the key is in range for platforms where CHAR_BIT != 8 */ + for (x = 0; x < 10; x++) { + skey->skipjack.key[x] = key[x] & 255; + } + + return CRYPT_OK; +} + +#define RULE_A \ + tmp = g_func(w1, &kp, key->skipjack.key); \ + w1 = tmp ^ w4 ^ x; \ + w4 = w3; w3 = w2; \ + w2 = tmp; + +#define RULE_B \ + tmp = g_func(w1, &kp, key->skipjack.key); \ + tmp1 = w4; w4 = w3; \ + w3 = w1 ^ w2 ^ x; \ + w1 = tmp1; w2 = tmp; + +#define RULE_A1 \ + tmp = w1 ^ w2 ^ x; \ + w1 = ig_func(w2, &kp, key->skipjack.key); \ + w2 = w3; w3 = w4; w4 = tmp; + +#define RULE_B1 \ + tmp = ig_func(w2, &kp, key->skipjack.key); \ + w2 = tmp ^ w3 ^ x; \ + w3 = w4; w4 = w1; w1 = tmp; + +static unsigned g_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +static unsigned ig_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +#ifdef CLEAN_STACK +static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + unsigned w1,w2,w3,w4,tmp,tmp1; + int x, kp; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + /* load block */ + w1 = ((unsigned)pt[0]<<8)|pt[1]; + w2 = ((unsigned)pt[2]<<8)|pt[3]; + w3 = ((unsigned)pt[4]<<8)|pt[5]; + w4 = ((unsigned)pt[6]<<8)|pt[7]; + + /* 8 rounds of RULE A */ + for (x = 1, kp = 0; x < 9; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 17; x++) { + RULE_B; + } + + /* 8 rounds of RULE A */ + for (; x < 25; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 33; x++) { + RULE_B; + } + + /* store block */ + ct[0] = (w1>>8)&255; ct[1] = w1&255; + ct[2] = (w2>>8)&255; ct[3] = w2&255; + ct[4] = (w3>>8)&255; ct[5] = w3&255; + ct[6] = (w4>>8)&255; ct[7] = w4&255; +} + +#ifdef CLEAN_STACK +void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _skipjack_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); +} +#endif + +#ifdef CLEAN_STACK +static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + unsigned w1,w2,w3,w4,tmp; + int x, kp; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + /* load block */ + w1 = ((unsigned)ct[0]<<8)|ct[1]; + w2 = ((unsigned)ct[2]<<8)|ct[3]; + w3 = ((unsigned)ct[4]<<8)|ct[5]; + w4 = ((unsigned)ct[6]<<8)|ct[7]; + + /* 8 rounds of RULE B^-1 + + Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8 + */ + for (x = 32, kp = 8; x > 24; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 16; x--) { + RULE_A1; + } + + + /* 8 rounds of RULE B^-1 */ + for (; x > 8; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 0; x--) { + RULE_A1; + } + + /* store block */ + pt[0] = (w1>>8)&255; pt[1] = w1&255; + pt[2] = (w2>>8)&255; pt[3] = w2&255; + pt[4] = (w3>>8)&255; pt[5] = w3&255; + pt[6] = (w4>>8)&255; pt[7] = w4&255; +} + +#ifdef CLEAN_STACK +void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _skipjack_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); +} +#endif + +int skipjack_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[10], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, + { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }, + { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 } + } + }; + unsigned char buf[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + skipjack_ecb_encrypt(tests[x].pt, buf[0], &key); + skipjack_ecb_decrypt(buf[0], buf[1], &key); + + /* compare */ + if (memcmp(buf[0], tests[x].ct, 8) != 0 || memcmp(buf[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key); + for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int skipjack_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 10) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 10) { + *desired_keysize = 10; + } + return CRYPT_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sprng.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* A secure PRNG using the RNG functions. Basically this is a + * wrapper that allows you to use a secure RNG as a PRNG + * in the various other functions. + */ +#include "mycrypt.h" + +#ifdef SPRNG + +const struct _prng_descriptor sprng_desc = +{ + "sprng", + &sprng_start, + &sprng_add_entropy, + &sprng_ready, + &sprng_read +}; + +int sprng_start(prng_state *prng) +{ + return CRYPT_OK; +} + +int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + return CRYPT_OK; +} + +int sprng_ready(prng_state *prng) +{ + return CRYPT_OK; +} + +unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + return rng_get_bytes(buf, len, NULL); +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/strings.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Future releases will make use of this */ +#include "mycrypt.h" + +static const char *err_2_str[] = +{ + "CRYPT_OK", + "CRYPT_ERROR", + "Non-fatal 'no-operation' requested.", + + "Invalid keysize for block cipher.", + "Invalid number of rounds for block cipher.", + "Algorithm failed test vectors.", + + "Buffer overflow.", + "Invalid input packet.", + + "Invalid number of bits for a PRNG.", + "Error reading the PRNG.", + + "Invalid cipher specified.", + "Invalid hash specified.", + "Invalid PRNG specified.", + + "Out of memory.", + + "Invalid PK key or key type specified for function.", + "A private PK key is required.", + + "Invalid argument provided.", + "File Not Found", + + "Invalid PK type.", + "Invalid PK system.", + "Duplicate PK key found on keyring.", + "Key not found in keyring.", + "Invalid sized parameter.", + + "Invalid size for prime.", + +}; + +#ifdef MPI +static const struct { + int mpi_code, ltc_code; +} mpi_to_ltc_codes[] = { + { MP_OKAY , CRYPT_OK}, + { MP_MEM , CRYPT_MEM}, + { MP_VAL , CRYPT_INVALID_ARG}, +}; +#endif + +const char *error_to_string(int err) +{ + if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { + return "Invalid error code."; + } else { + return err_2_str[err]; + } +} + +#ifdef MPI +/* convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) */ +int mpi_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { + if (err == mpi_to_ltc_codes[x].mpi_code) { + return mpi_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tiger.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,772 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +#include "mycrypt.h" + +#ifdef TIGER + +const struct _hash_descriptor tiger_desc = +{ + "tiger", + 1, + 24, + 64, + &tiger_init, + &tiger_process, + &tiger_done, + &tiger_test +}; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +static const ulong64 table[4*256] = { + CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */, + CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */, + CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */, + CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */, + CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */, + CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */, + CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */, + CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */, + CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */, + CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */, + CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */, + CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */, + CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */, + CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */, + CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */, + CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */, + CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */, + CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */, + CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */, + CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */, + CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */, + CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */, + CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */, + CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */, + CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */, + CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */, + CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */, + CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */, + CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */, + CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */, + CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */, + CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */, + CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */, + CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */, + CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */, + CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */, + CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */, + CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */, + CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */, + CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */, + CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */, + CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */, + CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */, + CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */, + CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */, + CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */, + CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */, + CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */, + CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */, + CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */, + CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */, + CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */, + CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */, + CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */, + CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */, + CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */, + CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */, + CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */, + CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */, + CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */, + CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */, + CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */, + CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */, + CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */, + CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */, + CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */, + CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */, + CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */, + CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */, + CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */, + CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */, + CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */, + CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */, + CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */, + CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */, + CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */, + CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */, + CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */, + CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */, + CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */, + CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */, + CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */, + CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */, + CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */, + CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */, + CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */, + CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */, + CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */, + CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */, + CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */, + CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */, + CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */, + CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */, + CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */, + CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */, + CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */, + CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */, + CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */, + CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */, + CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */, + CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */, + CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */, + CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */, + CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */, + CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */, + CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */, + CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */, + CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */, + CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */, + CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */, + CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */, + CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */, + CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */, + CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */, + CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */, + CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */, + CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */, + CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */, + CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */, + CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */, + CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */, + CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */, + CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */, + CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */, + CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */, + CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */, + CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */, + CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */, + CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */, + CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */, + CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */, + CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */, + CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */, + CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */, + CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */, + CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */, + CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */, + CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */, + CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */, + CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */, + CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */, + CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */, + CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */, + CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */, + CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */, + CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */, + CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */, + CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */, + CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */, + CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */, + CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */, + CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */, + CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */, + CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */, + CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */, + CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */, + CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */, + CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */, + CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */, + CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */, + CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */, + CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */, + CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */, + CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */, + CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */, + CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */, + CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */, + CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */, + CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */, + CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */, + CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */, + CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */, + CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */, + CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */, + CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */, + CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */, + CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */, + CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */, + CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */, + CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */, + CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */, + CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */, + CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */, + CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */, + CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */, + CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */, + CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */, + CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */, + CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */, + CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */, + CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */, + CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */, + CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */, + CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */, + CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */, + CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */, + CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */, + CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */, + CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */, + CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */, + CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */, + CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */, + CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */, + CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */, + CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */, + CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */, + CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */, + CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */, + CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */, + CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */, + CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */, + CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */, + CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */, + CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */, + CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */, + CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */, + CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */, + CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */, + CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */, + CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */, + CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */, + CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */, + CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */, + CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */, + CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */, + CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */, + CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */, + CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */, + CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */, + CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */, + CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */, + CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */, + CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */, + CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */, + CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */, + CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */, + CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */, + CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */, + CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */, + CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */, + CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */, + CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */, + CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */, + CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */, + CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */, + CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */, + CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */, + CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */, + CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */, + CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */, + CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */, + CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */, + CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */, + CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */, + CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */, + CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */, + CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */, + CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */, + CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */, + CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */, + CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */, + CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */, + CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */, + CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */, + CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */, + CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */, + CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */, + CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */, + CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */, + CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */, + CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */, + CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */, + CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */, + CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */, + CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */, + CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */, + CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */, + CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */, + CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */, + CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */, + CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */, + CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */, + CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */, + CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */, + CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */, + CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */, + CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */, + CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */, + CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */, + CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */, + CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */, + CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */, + CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */, + CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */, + CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */, + CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */, + CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */, + CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */, + CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */, + CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */, + CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */, + CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */, + CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */, + CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */, + CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */, + CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */, + CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */, + CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */, + CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */, + CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */, + CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */, + CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */, + CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */, + CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */, + CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */, + CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */, + CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */, + CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */, + CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */, + CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */, + CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */, + CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */, + CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */, + CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */, + CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */, + CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */, + CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */, + CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */, + CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */, + CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */, + CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */, + CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */, + CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */, + CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */, + CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */, + CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */, + CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */, + CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */, + CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */, + CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */, + CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */, + CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */, + CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */, + CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */, + CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */, + CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */, + CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */, + CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */, + CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */, + CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */, + CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */, + CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */, + CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */, + CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */, + CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */, + CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */, + CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */, + CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */, + CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */, + CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */, + CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */, + CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */, + CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */, + CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */, + CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */, + CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */, + CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */, + CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */, + CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */, + CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */, + CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */, + CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */, + CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */, + CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */, + CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */, + CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */, + CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */, + CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */, + CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */, + CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */, + CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */, + CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */, + CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */, + CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */, + CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */, + CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */, + CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */, + CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */, + CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */, + CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */, + CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */, + CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */, + CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */, + CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */, + CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */, + CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */, + CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */, + CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */, + CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */, + CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */, + CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */, + CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */, + CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */, + CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */, + CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */, + CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */, + CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */, + CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */, + CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */, + CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */, + CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */, + CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */, + CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */, + CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */, + CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */, + CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */, + CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */, + CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */, + CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */, + CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */, + CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */, + CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */, + CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */, + CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */, + CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */, + CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */, + CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */, + CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */, + CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */, + CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */, + CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */, + CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */, + CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */, + CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */, + CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */, + CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */, + CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */, + CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */, + CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */, + CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */, + CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */, + CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */, + CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */, + CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */, + CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */, + CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */, + CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */, + CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */, + CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */, + CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */, + CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */, + CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */, + CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */, + CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */, + CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */, + CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */, + CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */, + CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */, + CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */, + CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */, + CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */, + CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */, + CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */, + CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */, + CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */, + CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */, + CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */, + CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */, + CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */, + CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */, + CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */, + CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */, + CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */, + CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */, + CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */, + CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */, + CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */, + CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */, + CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */, + CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */, + CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */, + CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */, + CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */, + CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */, + CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */, + CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */, + CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */, + CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */, + CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */, + CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */, + CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */, + CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */, + CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */, + CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */, + CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */, + CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */, + CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */, + CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */, + CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */, + CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */, + CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */, + CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */, + CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */, + CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */, + CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */, + CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */, + CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */, + CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */, + CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */, + CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */, + CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */, + CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +/* one round of the hash function */ +INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) +{ + ulong64 tmp; + tmp = (*c ^= x); + *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; + tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); + switch (mul) { + case 5: *b = (tmp << 2) + tmp; break; + case 7: *b = (tmp << 3) - tmp; break; + case 9: *b = (tmp << 3) + tmp; break; + } +} + +/* one complete pass */ +static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) +{ + round(a,b,c,x[0],mul); + round(b,c,a,x[1],mul); + round(c,a,b,x[2],mul); + round(a,b,c,x[3],mul); + round(b,c,a,x[4],mul); + round(c,a,b,x[5],mul); + round(a,b,c,x[6],mul); + round(b,c,a,x[7],mul); +} + +/* The key mixing schedule */ +static void key_schedule(ulong64 *x) +{ + x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1])<<19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ ((~x[4])>>23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7])<<19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ ((~x[2])>>23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); +} + +#ifdef CLEAN_STACK +static void _tiger_compress(hash_state *md, unsigned char *buf) +#else +static void tiger_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 a, b, c, x[8]; + unsigned long i; + + /* load words */ + for (i = 0; i < 8; i++) { + LOAD64L(x[i],&buf[8*i]); + } + a = md->tiger.state[0]; + b = md->tiger.state[1]; + c = md->tiger.state[2]; + + pass(&a,&b,&c,x,5); + key_schedule(x); + pass(&c,&a,&b,x,7); + key_schedule(x); + pass(&b,&c,&a,x,9); + + /* store state */ + md->tiger.state[0] = a ^ md->tiger.state[0]; + md->tiger.state[1] = b - md->tiger.state[1]; + md->tiger.state[2] = c + md->tiger.state[2]; +} + +#ifdef CLEAN_STACK +static void tiger_compress(hash_state *md, unsigned char *buf) +{ + _tiger_compress(md, buf); + burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); +} +#endif + +void tiger_init(hash_state *md) +{ + _ARGCHK(md != NULL); + md->tiger.state[0] = CONST64(0x0123456789ABCDEF); + md->tiger.state[1] = CONST64(0xFEDCBA9876543210); + md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); + md->tiger.curlen = 0; + md->tiger.length = 0; +} + +HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) + +int tiger_done(hash_state * md, unsigned char *hash) +{ + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->tiger.curlen >= sizeof(md->tiger.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->tiger.length += md->tiger.curlen * 8; + + /* append the '1' bit */ + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. */ + if (md->tiger.curlen > 56) { + while (md->tiger.curlen < 64) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + tiger_compress(md, md->tiger.buf); + md->tiger.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->tiger.curlen < 56) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->tiger.length, md->tiger.buf+56); + tiger_compress(md, md->tiger.buf); + + /* copy output */ + STORE64L(md->tiger.state[0], &hash[0]); + STORE64L(md->tiger.state[1], &hash[8]); + STORE64L(md->tiger.state[2], &hash[16]); +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + + return CRYPT_OK; +} + +int tiger_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[24]; + } tests[] = { + { "", + { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24, + 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16, + 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 } + }, + { "abc", + { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2, + 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52, + 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 } + }, + { "Tiger", + { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f, + 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27, + 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87, + 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47, + 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00, + 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76, + 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 } + }, + }; + + int i; + unsigned char tmp[24]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + tiger_init(&md); + tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + tiger_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 24) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +/* +Hash of "": + 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A +Hash of "abc": + F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 +Hash of "Tiger": + 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789": + 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham": + 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.": + EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.": + 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 +*/ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tommath.h Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,558 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://math.libtomcrypt.org + */ +#ifndef BN_H_ +#define BN_H_ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <limits.h> + +#define NO_LTM_TOOM 1 + +#undef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#undef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef unsigned char mp_digit; + typedef unsigned short mp_word; +#elif defined(MP_16BIT) + typedef unsigned short mp_digit; + typedef unsigned long mp_word; +#elif defined(MP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long long ulong64; + typedef signed long long long64; +#endif + + typedef ulong64 mp_digit; + typedef unsigned long mp_word __attribute__ ((mode(TI))); + + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + + typedef unsigned long mp_digit; + typedef ulong64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + +/* define heap macros */ +#ifndef CRYPT + /* default to libc stuff */ + #ifndef XMALLOC + #define XMALLOC malloc + #define XFREE free + #define XREALLOC realloc + #define XCALLOC calloc + #else + /* prototypes for our heap functions */ + extern void *XMALLOC(size_t n); + extern void *REALLOC(void *p, size_t n); + extern void *XCALLOC(size_t n, size_t s); + extern void XFREE(void *p); + #endif +#endif + + +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_OFF 0x0004 /* force 2nd MSB to 0 */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; + +/* define this to use lower memory usage routines (exptmods mostly) */ +/* #define MP_LOW_MEM */ + +/* default precision */ +#ifndef MP_PREC + #ifdef MP_LOW_MEM + #define MP_PREC 64 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + +/* error code to char* string */ +char *mp_error_to_string(int code); + +/* ---> init and deinit bignum functions <--- */ +/* init a bignum */ +int mp_init(mp_int *a); + +/* free a bignum */ +void mp_clear(mp_int *a); + +/* init a null terminated series of arguments */ +int mp_init_multi(mp_int *mp, ...); + +/* clear a null terminated series of arguments */ +void mp_clear_multi(mp_int *mp, ...); + +/* exchange two ints */ +void mp_exch(mp_int *a, mp_int *b); + +/* shrink ram required for a bignum */ +int mp_shrink(mp_int *a); + +/* grow an int to a given size */ +int mp_grow(mp_int *a, int size); + +/* init to a given number of digits */ +int mp_init_size(mp_int *a, int size); + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + +/* set to zero */ +void mp_zero(mp_int *a); + +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); + +/* get a 32-bit value */ +unsigned long mp_get_int(mp_int * a); + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b); + +/* initialize and set 32-bit value */ +int mp_init_set_int (mp_int * a, unsigned long b); + +/* copy, b = a */ +int mp_copy(mp_int *a, mp_int *b); + +/* inits and copies, a = b */ +int mp_init_copy(mp_int *a, mp_int *b); + +/* trim unused digits */ +void mp_clamp(mp_int *a); + +/* ---> digit manipulation <--- */ + +/* right shift by "b" digits */ +void mp_rshd(mp_int *a, int b); + +/* left shift by "b" digits */ +int mp_lshd(mp_int *a, int b); + +/* c = a / 2**b */ +int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); + +/* b = a/2 */ +int mp_div_2(mp_int *a, mp_int *b); + +/* c = a * 2**b */ +int mp_mul_2d(mp_int *a, int b, mp_int *c); + +/* b = a*2 */ +int mp_mul_2(mp_int *a, mp_int *b); + +/* c = a mod 2**d */ +int mp_mod_2d(mp_int *a, int b, mp_int *c); + +/* computes a = 2**b */ +int mp_2expt(mp_int *a, int b); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a); + +/* I Love Earth! */ + +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); + +/* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(mp_int *a, mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(mp_int *a, mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(mp_int *a, mp_int *b, mp_int *c); + +/* ---> Basic arithmetic <--- */ + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + +/* compare a to b */ +int mp_cmp(mp_int *a, mp_int *b); + +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + +/* c = a + b */ +int mp_add(mp_int *a, mp_int *b, mp_int *c); + +/* c = a - b */ +int mp_sub(mp_int *a, mp_int *b, mp_int *c); + +/* c = a * b */ +int mp_mul(mp_int *a, mp_int *b, mp_int *c); + +/* b = a*a */ +int mp_sqr(mp_int *a, mp_int *b); + +/* a/b => cb + d == a */ +int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a mod b, 0 <= c < b */ +int mp_mod(mp_int *a, mp_int *b, mp_int *c); + +/* ---> single digit functions <--- */ + +/* compare against a single digit */ +int mp_cmp_d(mp_int *a, mp_digit b); + +/* c = a + b */ +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a - b */ +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a * b */ +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); + +/* a/b => cb + d == a */ +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); + +/* a/3 => 3c + d == a */ +int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); + +/* c = a**b */ +int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a mod b, 0 <= c < b */ +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); + +/* ---> number theory <--- */ + +/* d = a + b (mod c) */ +int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a - b (mod c) */ +int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a * b (mod c) */ +int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a * a (mod b) */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = 1/a (mod b) */ +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = (a, b) */ +int mp_gcd(mp_int *a, mp_int *b, mp_int *c); + +/* produces value such that U1*a + U2*b = U3 */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); + +/* c = [a, b] or (a*b)/(a, b) */ +int mp_lcm(mp_int *a, mp_int *b, mp_int *c); + +/* finds one of the b'th root of a, such that |c|**b <= |a| + * + * returns error if a < 0 and b is even + */ +int mp_n_root(mp_int *a, mp_digit b, mp_int *c); + +/* special sqrt algo */ +int mp_sqrt(mp_int *arg, mp_int *ret); + +/* is number a square? */ +int mp_is_square(mp_int *arg, int *ret); + +/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ +int mp_jacobi(mp_int *a, mp_int *n, int *c); + +/* used to setup the Barrett reduction for a given modulus b */ +int mp_reduce_setup(mp_int *a, mp_int *b); + +/* Barrett Reduction, computes a (mod b) with a precomputed value c + * + * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + */ +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); + +/* setups the montgomery reduction */ +int mp_montgomery_setup(mp_int *a, mp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); + +/* returns 1 if a is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a); + +/* sets the value of "d" required for mp_dr_reduce */ +void mp_dr_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b using the Diminished Radix method */ +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); + +/* returns true if a can be reduced with mp_reduce_2k */ +int mp_reduce_is_2k(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); + +/* d = a**b (mod c) */ +int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* ---> Primes <--- */ + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +/* table of first PRIME_SIZE primes */ +extern const mp_digit __prime_tab[]; + +/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ +int mp_prime_is_divisible(mp_int *a, int *result); + +/* performs one Fermat test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_fermat(mp_int *a, mp_int *b, int *result); + +/* performs one Miller-Rabin test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); + +/* This gives [for a given bit size] the number of trials required + * such that Miller-Rabin gives a prob of failure lower than 2^-96 + */ +int mp_prime_rabin_miller_trials(int size); + +/* performs t rounds of Miller-Rabin on "a" using the first + * t prime bases. Also performs an initial sieve of trial + * division. Determines if "a" is prime with probability + * of error no more than (1/4)**t. + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime(mp_int *a, int t, int *result); + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ +#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); + +/* ---> radix conversion <--- */ +int mp_count_bits(mp_int *a); + +int mp_unsigned_bin_size(mp_int *a); +int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); +int mp_to_unsigned_bin(mp_int *a, unsigned char *b); + +int mp_signed_bin_size(mp_int *a); +int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); + +int mp_read_radix(mp_int *a, char *str, int radix); +int mp_toradix(mp_int *a, char *str, int radix); +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); +int mp_radix_size(mp_int *a, int radix, int *size); + +int mp_fread(mp_int *a, int radix, FILE *stream); +int mp_fwrite(mp_int *a, int radix, FILE *stream); + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/* lowlevel functions, do not call! */ +int s_mp_add(mp_int *a, mp_int *b, mp_int *c); +int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(mp_int *a, mp_int *b); +int s_mp_sqr(mp_int *a, mp_int *b); +int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_karatsuba_sqr(mp_int *a, mp_int *b); +int mp_toom_sqr(mp_int *a, mp_int *b); +int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +void bn_reverse(unsigned char *s, int len); + +extern const char *mp_s_rmap; + +#ifdef __cplusplus + } +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/twofish.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,661 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* Implementation of Twofish by Tom St Denis */ +#include "mycrypt.h" + +#ifdef TWOFISH + +/* first TWOFISH_ALL_TABLES must ensure TWOFISH_TABLES is defined */ +#ifdef TWOFISH_ALL_TABLES +#ifndef TWOFISH_TABLES +#define TWOFISH_TABLES +#endif +#endif + +const struct _cipher_descriptor twofish_desc = +{ + "twofish", + 7, + 16, 32, 16, 16, + &twofish_setup, + &twofish_ecb_encrypt, + &twofish_ecb_decrypt, + &twofish_test, + &twofish_keysize +}; + +/* the two polynomials */ +#define MDS_POLY 0x169 +#define RS_POLY 0x14D + +/* The 4x4 MDS Linear Transform */ +static const unsigned char MDS[4][4] = { + { 0x01, 0xEF, 0x5B, 0x5B }, + { 0x5B, 0xEF, 0xEF, 0x01 }, + { 0xEF, 0x5B, 0x01, 0xEF }, + { 0xEF, 0x01, 0xEF, 0x5B } +}; + +/* The 4x8 RS Linear Transform */ +static const unsigned char RS[4][8] = { + { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, + { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 }, + { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 }, + { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 } +}; + +/* sbox usage orderings */ +static const unsigned char qord[4][5] = { + { 1, 1, 0, 0, 1 }, + { 0, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1 }, + { 1, 0, 1, 1, 0 } +}; + +#ifdef TWOFISH_TABLES + +#include "twofish_tab.c" + +#define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) + +#else + +/* The Q-box tables */ +static const unsigned char qbox[2][4][16] = { +{ + { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 }, + { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD }, + { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 }, + { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA } +}, +{ + { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 }, + { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 }, + { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF }, + { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA } +} +}; + +/* computes S_i[x] */ +#ifdef CLEAN_STACK +static ulong32 _sbox(int i, ulong32 x) +#else +static ulong32 sbox(int i, ulong32 x) +#endif +{ + unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y; + + /* a0,b0 = [x/16], x mod 16 */ + a0 = (unsigned char)((x>>4)&15); + b0 = (unsigned char)((x)&15); + + /* a1 = a0 ^ b0 */ + a1 = a0 ^ b0; + + /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */ + b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15; + + /* a2,b2 = t0[a1], t1[b1] */ + a2 = qbox[i][0][(int)a1]; + b2 = qbox[i][1][(int)b1]; + + /* a3 = a2 ^ b2 */ + a3 = a2 ^ b2; + + /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */ + b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15; + + /* a4,b4 = t2[a3], t3[b3] */ + a4 = qbox[i][2][(int)a3]; + b4 = qbox[i][3][(int)b3]; + + /* y = 16b4 + a4 */ + y = (b4 << 4) + a4; + + /* return result */ + return (ulong32)y; +} + +#ifdef CLEAN_STACK +static ulong32 sbox(int i, ulong32 x) +{ + ulong32 y; + y = _sbox(i, x); + burn_stack(sizeof(unsigned char) * 11); + return y; +} +#endif /* CLEAN_STACK */ + +#endif /* TWOFISH_TABLES */ + +/* computes ab mod p */ +static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p) +{ + ulong32 result, B[2], P[2]; + + P[1] = p; + B[1] = b; + result = P[0] = B[0] = 0; + + /* unrolled branchless GF multiplier */ + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; + + return result; +} + +/* computes [y0 y1 y2 y3] = MDS . [x0] */ +#ifndef TWOFISH_TABLES +static ulong32 mds_column_mult(unsigned char in, int col) +{ + ulong32 x01, x5B, xEF; + + x01 = in; + x5B = gf_mult(in, 0x5B, MDS_POLY); + xEF = gf_mult(in, 0xEF, MDS_POLY); + + switch (col) { + case 0: + return (x01 << 0 ) | + (x5B << 8 ) | + (xEF << 16) | + (xEF << 24); + case 1: + return (xEF << 0 ) | + (xEF << 8 ) | + (x5B << 16) | + (x01 << 24); + case 2: + return (x5B << 0 ) | + (xEF << 8 ) | + (x01 << 16) | + (xEF << 24); + case 3: + return (x5B << 0 ) | + (x01 << 8 ) | + (xEF << 16) | + (x5B << 24); + } + /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */ + return 0; +} + +#else /* !TWOFISH_TABLES */ + +#define mds_column_mult(x, i) mds_tab[i][x] + +#endif /* TWOFISH_TABLES */ + +/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */ +static void mds_mult(const unsigned char *in, unsigned char *out) +{ + int x; + ulong32 tmp; + for (tmp = x = 0; x < 4; x++) { + tmp ^= mds_column_mult(in[x], x); + } + STORE32L(tmp, out); +} + +#ifdef TWOFISH_ALL_TABLES +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + ulong32 tmp; + tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^ + rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]]; + STORE32L(tmp, out); +} + +#else /* !TWOFISH_ALL_TABLES */ + +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + int x, y; + for (x = 0; x < 4; x++) { + out[x] = 0; + for (y = 0; y < 8; y++) { + out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY); + } + } +} + +#endif + +/* computes h(x) */ +static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset) +{ + int x; + unsigned char y[4]; + for (x = 0; x < 4; x++) { + y[x] = in[x]; + } + switch (k) { + case 4: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); + y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); + y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]); + case 3: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]); + y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]); + y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]); + case 2: + y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0])); + y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1])); + y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2])); + y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3])); + } + mds_mult(y, out); +} + +#ifndef TWOFISH_SMALL + +/* for GCC we don't use pointer aliases */ +#if defined(__GNUC__) + #define S1 key->twofish.S[0] + #define S2 key->twofish.S[1] + #define S3 key->twofish.S[2] + #define S4 key->twofish.S[3] +#endif + +/* the G function */ +#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)]) +#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)]) + +#else + +#ifdef CLEAN_STACK +static ulong32 _g_func(ulong32 x, symmetric_key *key) +#else +static ulong32 g_func(ulong32 x, symmetric_key *key) +#endif +{ + unsigned char g, i, y, z; + ulong32 res; + + res = 0; + for (y = 0; y < 4; y++) { + z = key->twofish.start; + + /* do unkeyed substitution */ + g = sbox(qord[y][z++], (x >> (8*y)) & 255); + + /* first subkey */ + i = 0; + + /* do key mixing+sbox until z==5 */ + while (z != 5) { + g = g ^ key->twofish.S[4*i++ + y]; + g = sbox(qord[y][z++], g); + } + + /* multiply g by a column of the MDS */ + res ^= mds_column_mult(g, y); + } + return res; +} + +#define g1_func(x, key) g_func(ROL(x, 8), key) + +#ifdef CLEAN_STACK +static ulong32 g_func(ulong32 x, symmetric_key *key) +{ + ulong32 y; + y = _g_func(x, key); + burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32)); + return y; +} +#endif /* CLEAN_STACK */ + +#endif /* TWOFISH_SMALL */ + +#ifdef CLEAN_STACK +static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ +#ifndef TWOFISH_SMALL + unsigned char S[4*4], tmpx0, tmpx1; +#endif + int k, x, y; + unsigned char tmp[4], tmp2[4], M[8*4]; + ulong32 A, B; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* invalid arguments? */ + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* k = keysize/64 [but since our keysize is in bytes...] */ + k = keylen / 8; + + /* copy the key into M */ + for (x = 0; x < keylen; x++) { + M[x] = key[x] & 255; + } + + /* create the S[..] words */ +#ifndef TWOFISH_SMALL + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), S+(x*4)); + } +#else + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), skey->twofish.S+(x*4)); + } +#endif + + /* make subkeys */ + for (x = 0; x < 20; x++) { + /* A = h(p * 2x, Me) */ + for (y = 0; y < 4; y++) { + tmp[y] = x+x; + } + h_func(tmp, tmp2, M, k, 0); + LOAD32L(A, tmp2); + + /* B = ROL(h(p * (2x + 1), Mo), 8) */ + for (y = 0; y < 4; y++) { + tmp[y] = (unsigned char)(x+x+1); + } + h_func(tmp, tmp2, M, k, 1); + LOAD32L(B, tmp2); + B = ROL(B, 8); + + /* K[2i] = A + B */ + skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; + + /* K[2i+1] = (A + 2B) <<< 9 */ + skey->twofish.K[x+x+1] = ROL(B + B + A, 9); + } + +#ifndef TWOFISH_SMALL + /* make the sboxes (large ram variant) */ + if (k == 2) { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); + } + } else if (k == 3) { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); + } + } else { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); + } + } +#else + /* where to start in the sbox layers */ + /* small ram variant */ + switch (k) { + case 4 : skey->twofish.start = 0; break; + case 3 : skey->twofish.start = 1; break; + default: skey->twofish.start = 2; break; + } +#endif + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _twofish_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + S1 = key->twofish.S[0]; + S2 = key->twofish.S[1]; + S3 = key->twofish.S[2]; + S4 = key->twofish.S[3]; +#endif + + LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); + LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); + a ^= key->twofish.K[0]; + b ^= key->twofish.K[1]; + c ^= key->twofish.K[2]; + d ^= key->twofish.K[3]; + + k = key->twofish.K + 8; + for (r = 8; r != 0; --r) { + t2 = g1_func(b, key); + t1 = g_func(a, key) + t2; + c = ROR(c ^ (t1 + k[0]), 1); + d = ROL(d, 1) ^ (t2 + t1 + k[1]); + + t2 = g1_func(d, key); + t1 = g_func(c, key) + t2; + a = ROR(a ^ (t1 + k[2]), 1); + b = ROL(b, 1) ^ (t2 + t1 + k[3]); + k += 4; + } + + /* output with "undo last swap" */ + ta = c ^ key->twofish.K[4]; + tb = d ^ key->twofish.K[5]; + tc = a ^ key->twofish.K[6]; + td = b ^ key->twofish.K[7]; + + /* store output */ + STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); + STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); +} + +#ifdef CLEAN_STACK +void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _twofish_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + S1 = key->twofish.S[0]; + S2 = key->twofish.S[1]; + S3 = key->twofish.S[2]; + S4 = key->twofish.S[3]; +#endif + + /* load input */ + LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); + LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); + + /* undo undo final swap */ + a = tc ^ key->twofish.K[6]; + b = td ^ key->twofish.K[7]; + c = ta ^ key->twofish.K[4]; + d = tb ^ key->twofish.K[5]; + + k = key->twofish.K + 36; + for (r = 8; r != 0; --r) { + t2 = g1_func(d, key); + t1 = g_func(c, key) + t2; + a = ROL(a, 1) ^ (t1 + k[2]); + b = ROR(b ^ (t2 + t1 + k[3]), 1); + + t2 = g1_func(b, key); + t1 = g_func(a, key) + t2; + c = ROL(c, 1) ^ (t1 + k[0]); + d = ROR(d ^ (t2 + t1 + k[1]), 1); + k -= 4; + } + + /* pre-white */ + a ^= key->twofish.K[0]; + b ^= key->twofish.K[1]; + c ^= key->twofish.K[2]; + d ^= key->twofish.K[3]; + + /* store */ + STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); + STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); +} + +#ifdef CLEAN_STACK +void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _twofish_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); +} +#endif + +int twofish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, + { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, + 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, + { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, + 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } + }, { + 24, + { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, + 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, + 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, + { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, + 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, + { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, + 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } + }, { + 32, + { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, + 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, + 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, + { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, + 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, + { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } + } +}; + + + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); + twofish_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +int twofish_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize); + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + return CRYPT_OK; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + return CRYPT_OK; + } else { + *desired_keysize = 32; + return CRYPT_OK; + } +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/twofish_tab.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,488 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +#ifdef TWOFISH_TABLES + +/* pre generated 8x8 tables from the four 4x4s */ +static const unsigned char SBOX[2][256] = { +{ + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, + 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98, + 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, + 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, + 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01, + 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, + 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, + 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, + 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5, + 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, + 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, + 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d, + 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, + 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, + 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, + 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f, + 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, + 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, + 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7, + 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, + 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, + 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, + 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0}, +{ + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, + 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd, + 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, + 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, + 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84, + 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, + 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, + 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff, + 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, + 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, + 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94, + 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, + 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, + 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, + 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e, + 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, + 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, + 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e, + 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, + 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, + 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, + 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91} +}; + +/* the 4x4 MDS in a nicer format */ +static const ulong32 mds_tab[4][256] = { +{ +0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL, +0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL, +0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL, +0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL, +0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL, +0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL, +0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL, +0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL, +0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL, +0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL, +0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL, +0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL, +0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL, +0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL, +0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL, +0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL, +0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL, +0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL, +0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL, +0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL, +0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL, +0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL, +0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL, +0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL, +0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL, +0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL, +0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL, +0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL, +0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL, +0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL, +0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL, +0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL +}, +{ +0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL, +0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL, +0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL, +0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL, +0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL, +0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL, +0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL, +0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL, +0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL, +0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL, +0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL, +0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL, +0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL, +0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL, +0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL, +0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL, +0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL, +0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL, +0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL, +0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL, +0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL, +0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL, +0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL, +0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL, +0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL, +0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL, +0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL, +0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL, +0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL, +0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL, +0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL, +0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL +}, +{ +0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL, +0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL, +0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL, +0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL, +0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL, +0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL, +0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL, +0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL, +0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL, +0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL, +0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL, +0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL, +0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL, +0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL, +0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL, +0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL, +0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL, +0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL, +0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL, +0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL, +0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL, +0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL, +0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL, +0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL, +0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL, +0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL, +0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL, +0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL, +0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL, +0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL, +0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL, +0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL +}, +{ +0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL, +0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL, +0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL, +0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL, +0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL, +0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL, +0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL, +0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL, +0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL, +0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL, +0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL, +0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL, +0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL, +0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL, +0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL, +0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL, +0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL, +0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL, +0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL, +0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL, +0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL, +0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL, +0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL, +0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL, +0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL, +0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL, +0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL, +0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL, +0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL, +0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL, +0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL, +0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL +}}; + +#ifdef TWOFISH_ALL_TABLES + +/* the 4x8 RS transform */ +static const ulong32 rs_tab0[256] = { +0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU, +0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU, +0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU, +0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU, +0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU, +0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU, +0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU, +0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU, +0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU, +0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU, +0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU, +0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU, +0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU, +0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU, +0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU, +0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU, +0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU, +0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU, +0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU, +0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU, +0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU, +0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU, +0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU, +0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU, +0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU, +0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU, +0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU, +0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU, +0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU, +0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU, +0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU, +0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU }; + +static const ulong32 rs_tab1[256] = { +0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU, +0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU, +0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU, +0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU, +0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU, +0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU, +0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU, +0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU, +0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU, +0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU, +0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU, +0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU, +0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU, +0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU, +0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU, +0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU, +0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU, +0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU, +0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU, +0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU, +0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU, +0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU, +0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU, +0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU, +0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU, +0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU, +0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU, +0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU, +0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU, +0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU, +0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU, +0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU }; + +static const ulong32 rs_tab2[256] = { +0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU, +0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU, +0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU, +0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU, +0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU, +0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU, +0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU, +0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU, +0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU, +0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU, +0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU, +0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU, +0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU, +0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU, +0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU, +0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU, +0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU, +0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU, +0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU, +0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU, +0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU, +0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU, +0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU, +0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU, +0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU, +0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU, +0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU, +0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU, +0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU, +0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU, +0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU, +0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU }; + +static const ulong32 rs_tab3[256] = { +0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU, +0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU, +0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU, +0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU, +0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU, +0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU, +0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU, +0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU, +0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU, +0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU, +0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU, +0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU, +0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU, +0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU, +0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU, +0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU, +0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU, +0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU, +0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU, +0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU, +0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU, +0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU, +0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU, +0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU, +0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU, +0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU, +0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU, +0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU, +0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU, +0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU, +0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU, +0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU }; + +static const ulong32 rs_tab4[256] = { +0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU, +0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU, +0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU, +0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU, +0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU, +0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU, +0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU, +0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU, +0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU, +0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU, +0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU, +0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU, +0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU, +0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU, +0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU, +0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU, +0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU, +0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU, +0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU, +0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU, +0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU, +0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU, +0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU, +0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU, +0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU, +0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU, +0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU, +0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU, +0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU, +0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU, +0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU, +0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU }; + +static const ulong32 rs_tab5[256] = { +0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU, +0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU, +0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU, +0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU, +0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU, +0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU, +0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU, +0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU, +0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU, +0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU, +0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU, +0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU, +0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU, +0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU, +0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU, +0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU, +0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU, +0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU, +0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU, +0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU, +0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU, +0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU, +0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU, +0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU, +0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU, +0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU, +0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU, +0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU, +0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU, +0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU, +0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU, +0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU }; + +static const ulong32 rs_tab6[256] = { +0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU, +0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU, +0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU, +0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU, +0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU, +0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU, +0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU, +0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU, +0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU, +0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU, +0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU, +0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU, +0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU, +0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU, +0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU, +0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU, +0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU, +0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU, +0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU, +0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU, +0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU, +0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU, +0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU, +0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU, +0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU, +0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU, +0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU, +0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU, +0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU, +0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU, +0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU, +0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU }; + +static const ulong32 rs_tab7[256] = { +0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU, +0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU, +0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU, +0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU, +0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU, +0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU, +0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU, +0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU, +0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU, +0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU, +0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU, +0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU, +0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU, +0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU, +0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU, +0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU, +0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU, +0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU, +0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU, +0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU, +0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU, +0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU, +0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU, +0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU, +0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU, +0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU, +0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU, +0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU, +0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU, +0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU, +0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU, +0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU }; + +#endif /* TWOFISH_ALL_TABLES */ + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/whirl.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,275 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +/* WHIRLPOOL (using their new sbox) hash function by Tom St Denis */ + +#include "mycrypt.h" + +#ifdef WHIRLPOOL + +const struct _hash_descriptor whirlpool_desc = +{ + "whirlpool", + 11, + 64, + 64, + &whirlpool_init, + &whirlpool_process, + &whirlpool_done, + &whirlpool_test +}; + +/* the sboxes */ +#include "whirltab.c" + +/* get a_{i,j} */ +#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255) + +/* shortcut macro to perform three functions at once */ +#define theta_pi_gamma(a, i) \ + SB0(GB(a, i-0, 7)) ^ \ + SB1(GB(a, i-1, 6)) ^ \ + SB2(GB(a, i-2, 5)) ^ \ + SB3(GB(a, i-3, 4)) ^ \ + SB4(GB(a, i-4, 3)) ^ \ + SB5(GB(a, i-5, 2)) ^ \ + SB6(GB(a, i-6, 1)) ^ \ + SB7(GB(a, i-7, 0)) + +#ifdef CLEAN_STACK +static void _whirlpool_compress(hash_state *md, unsigned char *buf) +#else +static void whirlpool_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 K[2][8], T[3][8]; + int x, y; + + /* load the block/state */ + for (x = 0; x < 8; x++) { + K[0][x] = md->whirlpool.state[x]; + + LOAD64H(T[0][x], buf + (8 * x)); + T[2][x] = T[0][x]; + T[0][x] ^= K[0][x]; + } + + /* do rounds 1..10 */ + for (x = 0; x < 10; x += 2) { + /* odd round */ + /* apply main transform to K[0] into K[1] */ + for (y = 0; y < 8; y++) { + K[1][y] = theta_pi_gamma(K[0], y); + } + /* xor the constant */ + K[1][0] ^= cont[x]; + + /* apply main transform to T[0] into T[1] */ + for (y = 0; y < 8; y++) { + T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y]; + } + + /* even round */ + /* apply main transform to K[1] into K[0] */ + for (y = 0; y < 8; y++) { + K[0][y] = theta_pi_gamma(K[1], y); + } + /* xor the constant */ + K[0][0] ^= cont[x+1]; + + /* apply main transform to T[0] into T[1] */ + for (y = 0; y < 8; y++) { + T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y]; + } + } + + /* store state */ + for (x = 0; x < 8; x++) { + md->whirlpool.state[x] ^= T[0][x] ^ T[2][x]; + } +} + + +#ifdef CLEAN_STACK +static void whirlpool_compress(hash_state *md, unsigned char *buf) +{ + _whirlpool_compress(md, buf); + burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int))); +} +#endif + + +void whirlpool_init(hash_state * md) +{ + _ARGCHK(md != NULL); + zeromem(&md->whirlpool, sizeof(md->whirlpool)); +} + +HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64) + +int whirlpool_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->whirlpool.length += md->whirlpool.curlen * 8; + + /* append the '1' bit */ + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 32 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->whirlpool.curlen > 32) { + while (md->whirlpool.curlen < 64) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + whirlpool_compress(md, md->whirlpool.buf); + md->whirlpool.curlen = 0; + } + + /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */ + while (md->whirlpool.curlen < 56) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->whirlpool.length, md->whirlpool.buf+56); + whirlpool_compress(md, md->whirlpool.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->whirlpool.state[i], hash+(8*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(*md)); +#endif + return CRYPT_OK; +} + + +int whirlpool_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int len; + unsigned char msg[128], hash[64]; + } tests[] = { + + /* NULL Message */ +{ + 0, + { 0x00 }, + { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26, + 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7, + 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57, + 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 } +}, + + + /* 448-bits of 0 bits */ +{ + + 56, + { 0x00 }, + { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03, + 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70, + 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61, + 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 } +}, + + /* 520-bits of 0 bits */ +{ + 65, + { 0x00 }, + { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D, + 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4, + 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF, + 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 } +}, + + /* 512-bits, leading set */ +{ + 64, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A, + 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94, + 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6, + 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB } +}, + + /* 512-bits, leading set of second byte */ +{ + 64, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E, + 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F, + 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35, + 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 } +}, + + /* 512-bits, leading set of last byte */ +{ + 64, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6, + 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F, + 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B, + 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 } +}, + +}; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + whirlpool_init(&md); + whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len); + whirlpool_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 64) != 0) { +#if 0 + printf("\nFailed test %d\n", i); + for (i = 0; i < 64; ) { + printf("%02x ", tmp[i]); + if (!(++i & 15)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/whirltab.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,575 @@ +static const ulong64 sbox0[] = { +CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb), +CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d), +CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e), +CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8), +CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a), +CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80), +CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c), +CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5), +CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e), +CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944), +CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a), +CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9), +CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507), +CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78), +CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7), +CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56), +CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71), +CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a), +CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f), +CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6), +CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de), +CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f), +CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc), +CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59), +CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4), +CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032), +CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d), +CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7), +CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f), +CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482), +CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df), +CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8), +CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e), +CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3), +CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea), +CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4), +CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9), +CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e), +CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f), +CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae), +CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7), +CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152), +CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab), +CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816), +CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598), +CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e), +CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee), +CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824), +CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65), +CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819), +CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299), +CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0), +CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c), +CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05), +CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b), +CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88), +CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1), +CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b), +CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c), +CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba), +CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241), +CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6), +CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed), +CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2) +}; + +#ifdef SMALL_CODE + +#define SB0(x) sbox0[x] +#define SB1(x) ROR64(sbox0[x], 8) +#define SB2(x) ROR64(sbox0[x], 16) +#define SB3(x) ROR64(sbox0[x], 24) +#define SB4(x) ROR64(sbox0[x], 32) +#define SB5(x) ROR64(sbox0[x], 40) +#define SB6(x) ROR64(sbox0[x], 48) +#define SB7(x) ROR64(sbox0[x], 56) + +#else + +#define SB0(x) sbox0[x] +#define SB1(x) sbox1[x] +#define SB2(x) sbox2[x] +#define SB3(x) sbox3[x] +#define SB4(x) sbox4[x] +#define SB5(x) sbox5[x] +#define SB6(x) sbox6[x] +#define SB7(x) sbox7[x] + + +static const ulong64 sbox1[] = { +CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd), +CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e), +CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7), +CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4), +CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01), +CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a), +CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99), +CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae), +CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7), +CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9), +CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214), +CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17), +CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5), +CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce), +CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b), +CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad), +CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc), +CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21), +CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e), +CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66), +CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2), +CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf), +CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d), +CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d), +CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d), +CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590), +CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe), +CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41), +CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44), +CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24), +CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5), +CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a), +CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756), +CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736), +CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0), +CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3), +CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9), +CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d), +CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a), +CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809), +CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e), +CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431), +CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2), +CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198), +CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605), +CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2), +CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c), +CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408), +CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a), +CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448), +CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522), +CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb), +CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3), +CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb), +CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06), +CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f), +CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6), +CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8), +CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c), +CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df), +CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12), +CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7), +CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55), +CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411) +}; + +static const ulong64 sbox2[] = { +CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f), +CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e), +CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06), +CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07), +CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c), +CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1), +CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed), +CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216), +CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56), +CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95), +CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022), +CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab), +CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303), +CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6), +CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d), +CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f), +CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3), +CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc), +CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b), +CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff), +CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8), +CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a), +CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492), +CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a), +CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba), +CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75), +CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e), +CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c), +CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa), +CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a), +CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b), +CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9), +CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587), +CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877), +CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d), +CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74), +CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365), +CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7), +CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264), +CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498), +CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863), +CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4), +CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220), +CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61), +CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486), +CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8), +CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066), +CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014), +CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839), +CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4), +CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855), +CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60), +CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c), +CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8), +CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f), +CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137), +CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202), +CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1), +CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43), +CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42), +CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d), +CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e), +CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e), +CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4) +}; + +static const ulong64 sbox3[] = { +CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813), +CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42), +CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb), +CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa), +CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04), +CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5), +CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e), +CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782), +CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b), +CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e), +CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50), +CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c), +CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3), +CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f), +CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c), +CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e), +CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617), +CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84), +CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738), +CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385), +CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af), +CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986), +CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834), +CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9), +CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074), +CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a), +CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2), +CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19), +CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d), +CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290), +CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33), +CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5), +CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45), +CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8), +CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba), +CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b), +CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03), +CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e), +CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52), +CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24), +CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8), +CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4), +CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2), +CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a), +CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14), +CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f), +CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0), +CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420), +CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68), +CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d), +CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188), +CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b), +CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb), +CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6), +CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318), +CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921), +CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2), +CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47), +CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a), +CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b), +CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948), +CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b), +CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449), +CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644) +}; + +static const ulong64 sbox4[] = { +CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8), +CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f), +CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5), +CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552), +CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e), +CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435), +CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2), +CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157), +CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5), +CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda), +CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a), +CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85), +CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4), +CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167), +CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b), +CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8), +CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566), +CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e), +CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07), +CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33), +CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971), +CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9), +CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88), +CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0), +CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80), +CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48), +CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f), +CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae), +CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822), +CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812), +CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec), +CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d), +CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b), +CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b), +CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50), +CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef), +CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea), +CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0), +CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d), +CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a), +CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f), +CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296), +CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959), +CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c), +CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c), +CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961), +CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e), +CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004), +CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d), +CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024), +CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411), +CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb), +CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7), +CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3), +CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03), +CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9), +CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153), +CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c), +CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546), +CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1), +CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409), +CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed), +CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4), +CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286) +}; + +static const ulong64 sbox5[] = { +CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887), +CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21), +CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3), +CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255), +CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02), +CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4), +CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f), +CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741), +CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3), +CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f), +CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28), +CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e), +CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7), +CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781), +CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16), +CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847), +CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685), +CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42), +CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c), +CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc), +CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9), +CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943), +CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a), +CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa), +CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a), +CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d), +CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61), +CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82), +CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288), +CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248), +CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97), +CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4), +CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac), +CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c), +CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d), +CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b), +CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f), +CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027), +CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29), +CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12), +CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c), +CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662), +CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979), +CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d), +CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a), +CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199), +CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78), +CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410), +CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34), +CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490), +CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144), +CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b), +CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb), +CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b), +CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c), +CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e), +CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351), +CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad), +CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605), +CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3), +CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924), +CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93), +CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa), +CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622) +}; + +static const ulong64 sbox6[] = { +CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8), +CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f), +CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5), +CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252), +CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e), +CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535), +CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2), +CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757), +CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5), +CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada), +CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a), +CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585), +CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4), +CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767), +CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b), +CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8), +CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666), +CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e), +CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707), +CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333), +CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171), +CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9), +CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888), +CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0), +CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080), +CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848), +CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f), +CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae), +CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222), +CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212), +CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec), +CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d), +CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b), +CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b), +CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050), +CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef), +CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea), +CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0), +CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d), +CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a), +CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f), +CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696), +CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959), +CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c), +CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c), +CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161), +CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e), +CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404), +CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d), +CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424), +CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111), +CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb), +CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7), +CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3), +CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303), +CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9), +CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353), +CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c), +CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646), +CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1), +CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909), +CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded), +CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4), +CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686) +}; + +static const ulong64 sbox7[] = { +CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8), +CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f), +CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5), +CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852), +CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e), +CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035), +CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2), +CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557), +CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5), +CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da), +CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a), +CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985), +CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4), +CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867), +CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b), +CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8), +CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166), +CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e), +CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07), +CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633), +CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71), +CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9), +CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88), +CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0), +CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480), +CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248), +CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f), +CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae), +CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22), +CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212), +CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec), +CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d), +CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b), +CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b), +CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50), +CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef), +CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea), +CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0), +CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d), +CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a), +CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f), +CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296), +CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59), +CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c), +CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c), +CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61), +CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e), +CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404), +CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d), +CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924), +CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911), +CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb), +CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7), +CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3), +CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03), +CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9), +CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153), +CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c), +CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46), +CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1), +CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109), +CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed), +CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4), +CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286) +}; + +#endif + +static const ulong64 cont[] = { +CONST64(0x1823c6e887b8014f), +CONST64(0x36a6d2f5796f9152), +CONST64(0x60bc9b8ea30c7b35), +CONST64(0x1de0d7c22e4bfe57), +CONST64(0x157737e59ff04ada), +CONST64(0x58c9290ab1a06b85), +CONST64(0xbd5d10f4cb3e0567), +CONST64(0xe427418ba77d95d8), +CONST64(0xfbee7c66dd17479e), +CONST64(0xca2dbf07ad5a8333), +CONST64(0x6302aa71c81949d9), +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xtea.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,169 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +#include "mycrypt.h" + +#ifdef XTEA + +const struct _cipher_descriptor xtea_desc = +{ + "xtea", + 1, + 16, 16, 8, 32, + &xtea_setup, + &xtea_ecb_encrypt, + &xtea_ecb_decrypt, + &xtea_test, + &xtea_keysize +}; + +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned long x, sum, K[4]; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 32) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32L(K[0], key+0); + LOAD32L(K[1], key+4); + LOAD32L(K[2], key+8); + LOAD32L(K[3], key+12); + + for (x = sum = 0; x < 32; x++) { + skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL; + sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL; + skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL; + } + +#ifdef CLEAN_STACK + zeromem(&K, sizeof(K)); +#endif + + return CRYPT_OK; +} + +void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + unsigned long y, z; + int r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32L(y, &pt[0]); + LOAD32L(z, &pt[4]); + for (r = 0; r < 32; r += 4) { + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+1])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+1])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+2])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+2])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+3])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &ct[0]); + STORE32L(z, &ct[4]); +} + +void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + unsigned long y, z; + int r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32L(y, &ct[0]); + LOAD32L(z, &ct[4]); + for (r = 31; r >= 0; r -= 4) { + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-1])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-1])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-2])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-2])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-3])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &pt[0]); + STORE32L(z, &pt[4]); +} + +int xtea_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char key[16] = + { 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a, + 0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d }; + static const unsigned char pt[8] = + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + static const unsigned char ct[8] = + { 0x75, 0xd7, 0xc5, 0xbf, 0xcf, 0x58, 0xc9, 0x3f }; + unsigned char tmp[2][8]; + symmetric_key skey; + int err, y; + + if ((err = xtea_setup(key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + xtea_ecb_encrypt(pt, tmp[0], &skey); + xtea_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (memcmp(tmp[0], ct, 8) != 0 || memcmp(tmp[1], pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +int xtea_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 16; + return CRYPT_OK; +} + + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/yarrow.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,167 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ + +#include "mycrypt.h" + +#ifdef YARROW + +const struct _prng_descriptor yarrow_desc = +{ + "yarrow", + &yarrow_start, + &yarrow_add_entropy, + &yarrow_ready, + &yarrow_read +}; + +int yarrow_start(prng_state *prng) +{ + int err; + + _ARGCHK(prng != NULL); + + /* these are the default hash/cipher combo used */ +#ifdef RIJNDAEL + prng->yarrow.cipher = register_cipher(&rijndael_desc); +#elif defined(BLOWFISH) + prng->yarrow.cipher = register_cipher(&blowfish_desc); +#elif defined(TWOFISH) + prng->yarrow.cipher = register_cipher(&twofish_desc); +#elif defined(RC6) + prng->yarrow.cipher = register_cipher(&rc6_desc); +#elif defined(RC5) + prng->yarrow.cipher = register_cipher(&rc5_desc); +#elif defined(SAFERP) + prng->yarrow.cipher = register_cipher(&saferp_desc); +#elif defined(RC2) + prng->yarrow.cipher = register_cipher(&rc2_desc); +#elif defined(NOEKEON) + prng->yarrow.cipher = register_cipher(&noekeon_desc); +#elif defined(CAST5) + prng->yarrow.cipher = register_cipher(&cast5_desc); +#elif defined(XTEA) + prng->yarrow.cipher = register_cipher(&xtea_desc); +#elif defined(SAFER) + prng->yarrow.cipher = register_cipher(&safer_sk128_desc); +#elif defined(DES) + prng->yarrow.cipher = register_cipher(&des3_desc); +#elif + #error YARROW needs at least one CIPHER +#endif + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + +#ifdef SHA256 + prng->yarrow.hash = register_hash(&sha256_desc); +#elif defined(SHA512) + prng->yarrow.hash = register_hash(&sha512_desc); +#elif defined(TIGER) + prng->yarrow.hash = register_hash(&tiger_desc); +#elif defined(SHA1) + prng->yarrow.hash = register_hash(&sha1_desc); +#elif defined(RIPEMD160) + prng->yarrow.hash = register_hash(&rmd160_desc); +#elif defined(RIPEMD128) + prng->yarrow.hash = register_hash(&rmd128_desc); +#elif defined(MD5) + prng->yarrow.hash = register_hash(&md5_desc); +#elif defined(MD4) + prng->yarrow.hash = register_hash(&md4_desc); +#elif defined(MD2) + prng->yarrow.hash = register_hash(&md2_desc); +#else + #error YARROW needs at least one HASH +#endif + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* zero the memory used */ + zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); + + return CRYPT_OK; +} + +int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + hash_state md; + int err; + + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* start the hash */ + hash_descriptor[prng->yarrow.hash].init(&md); + + /* hash the current pool */ + hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize); + + /* add the new entropy */ + hash_descriptor[prng->yarrow.hash].process(&md, buf, len); + + /* store result */ + hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); + + return CRYPT_OK; +} + +int yarrow_ready(prng_state *prng) +{ + int ks, err; + + _ARGCHK(prng != NULL); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + + /* setup CTR mode using the "pool" as the key */ + ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; + if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { + return err; + } + + if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ + prng->yarrow.pool, /* IV */ + prng->yarrow.pool, ks, /* KEY and key size */ + 0, /* number of rounds */ + &prng->yarrow.ctr)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +} + +unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + /* put buf in predictable state first */ + zeromem(buf, len); + + /* now randomize it */ + if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) { + return 0; + } + return len; +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zeromem.c Mon May 31 18:21:40 2004 +0000 @@ -0,0 +1,19 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, [email protected], http://libtomcrypt.org + */ +#include "mycrypt.h" + +void zeromem(void *dst, size_t len) +{ + unsigned char *mem = (unsigned char *)dst; + _ARGCHK(dst != NULL); + while (len-- > 0) + *mem++ = 0; +}