⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twofish.c

📁 该压缩包中包括 tom的加密函数库及pdf说明 ,以及Rinick s ECC:椭圆曲线非对称加密密钥生成器
💻 C
📖 第 1 页 / 共 2 页
字号:
   LTC_ARGCHK(key  != NULL);   LTC_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 = ROLc(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] = ROLc(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 LTC_CLEAN_STACKint 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/**  Encrypts a block of text with Twofish  @param pt The input plaintext (16 bytes)  @param ct The output ciphertext (16 bytes)  @param skey The key as scheduled*/#ifdef LTC_CLEAN_STACKstatic void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)#elsevoid twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)#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        LTC_ARGCHK(pt   != NULL);    LTC_ARGCHK(ct   != NULL);    LTC_ARGCHK(skey != NULL);    #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)    S1 = skey->twofish.S[0];    S2 = skey->twofish.S[1];    S3 = skey->twofish.S[2];    S4 = skey->twofish.S[3];#endif        LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);    LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);    a ^= skey->twofish.K[0];    b ^= skey->twofish.K[1];    c ^= skey->twofish.K[2];    d ^= skey->twofish.K[3];        k  = skey->twofish.K + 8;    for (r = 8; r != 0; --r) {        t2 = g1_func(b, skey);        t1 = g_func(a, skey) + t2;        c  = RORc(c ^ (t1 + k[0]), 1);        d  = ROLc(d, 1) ^ (t2 + t1 + k[1]);                t2 = g1_func(d, skey);        t1 = g_func(c, skey) + t2;        a  = RORc(a ^ (t1 + k[2]), 1);        b  = ROLc(b, 1) ^ (t2 + t1 + k[3]);        k += 4;   }    /* output with "undo last swap" */    ta = c ^ skey->twofish.K[4];    tb = d ^ skey->twofish.K[5];    tc = a ^ skey->twofish.K[6];    td = b ^ skey->twofish.K[7];    /* store output */    STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);    STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);}#ifdef LTC_CLEAN_STACKvoid twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey){   _twofish_ecb_encrypt(pt, ct, skey);   burn_stack(sizeof(ulong32) * 10 + sizeof(int));}#endif/**  Decrypts a block of text with Twofish  @param ct The input ciphertext (16 bytes)  @param pt The output plaintext (16 bytes)  @param skey The key as scheduled */#ifdef LTC_CLEAN_STACKstatic void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)#elsevoid twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)#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        LTC_ARGCHK(pt   != NULL);    LTC_ARGCHK(ct   != NULL);    LTC_ARGCHK(skey != NULL);    #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)    S1 = skey->twofish.S[0];    S2 = skey->twofish.S[1];    S3 = skey->twofish.S[2];    S4 = skey->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 ^ skey->twofish.K[6];    b = td ^ skey->twofish.K[7];    c = ta ^ skey->twofish.K[4];    d = tb ^ skey->twofish.K[5];    k = skey->twofish.K + 36;    for (r = 8; r != 0; --r) {        t2 = g1_func(d, skey);        t1 = g_func(c, skey) + t2;        a = ROLc(a, 1) ^ (t1 + k[2]);        b = RORc(b ^ (t2 + t1 + k[3]), 1);        t2 = g1_func(b, skey);        t1 = g_func(a, skey) + t2;        c = ROLc(c, 1) ^ (t1 + k[0]);        d = RORc(d ^ (t2 +  t1 + k[1]), 1);        k -= 4;    }    /* pre-white */    a ^= skey->twofish.K[0];    b ^= skey->twofish.K[1];    c ^= skey->twofish.K[2];    d ^= skey->twofish.K[3];        /* store */    STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);    STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);}#ifdef LTC_CLEAN_STACKvoid twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey){   _twofish_ecb_decrypt(ct, pt, skey);   burn_stack(sizeof(ulong32) * 10 + sizeof(int));}#endif/**  Performs a self-test of the Twofish block cipher  @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled*/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 }/** Terminate the context    @param skey    The scheduled key*/void twofish_done(symmetric_key *skey){}/**  Gets suitable key size  @param keysize [in/out] The length of the recommended key (in bytes).  This function will store the suitable size back in this variable.  @return CRYPT_OK if the input key size is acceptable.*/int twofish_keysize(int *keysize){   LTC_ARGCHK(keysize);   if (*keysize < 16)      return CRYPT_INVALID_KEYSIZE;   if (*keysize < 24) {      *keysize = 16;      return CRYPT_OK;   } else if (*keysize < 32) {      *keysize = 24;      return CRYPT_OK;   } else {      *keysize = 32;      return CRYPT_OK;   }}#endif/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ *//* $Revision: 1.8 $ *//* $Date: 2005/05/05 14:35:58 $ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -