comparison src/ciphers/twofish/twofish.c @ 380:d5faf4814ddb libtomcrypt-orig libtomcrypt-1.16

Update to LibTomCrypt 1.16
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:22:00 +0000
parents 59400faa4b44
children 999a5eb4ed10
comparison
equal deleted inserted replaced
280:59400faa4b44 380:d5faf4814ddb
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 11
12 /** 12 /**
13 @file twofish.c 13 @file twofish.c
14 Implementation of Twofish by Tom St Denis 14 Implementation of Twofish by Tom St Denis
33 &twofish_ecb_encrypt, 33 &twofish_ecb_encrypt,
34 &twofish_ecb_decrypt, 34 &twofish_ecb_decrypt,
35 &twofish_test, 35 &twofish_test,
36 &twofish_done, 36 &twofish_done,
37 &twofish_keysize, 37 &twofish_keysize,
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL 38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
39 }; 39 };
40 40
41 /* the two polynomials */ 41 /* the two polynomials */
42 #define MDS_POLY 0x169 42 #define MDS_POLY 0x169
43 #define RS_POLY 0x14D 43 #define RS_POLY 0x14D
410 410
411 #ifndef TWOFISH_SMALL 411 #ifndef TWOFISH_SMALL
412 /* make the sboxes (large ram variant) */ 412 /* make the sboxes (large ram variant) */
413 if (k == 2) { 413 if (k == 2) {
414 for (x = 0; x < 256; x++) { 414 for (x = 0; x < 256; x++) {
415 tmpx0 = sbox(0, x); 415 tmpx0 = (unsigned char)sbox(0, x);
416 tmpx1 = sbox(1, x); 416 tmpx1 = (unsigned char)sbox(1, x);
417 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); 417 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
418 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); 418 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
419 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); 419 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
420 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); 420 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3);
421 } 421 }
422 } else if (k == 3) { 422 } else if (k == 3) {
423 for (x = 0; x < 256; x++) { 423 for (x = 0; x < 256; x++) {
424 tmpx0 = sbox(0, x); 424 tmpx0 = (unsigned char)sbox(0, x);
425 tmpx1 = sbox(1, x); 425 tmpx1 = (unsigned char)sbox(1, x);
426 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); 426 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
427 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); 427 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
428 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); 428 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
429 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); 429 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3);
430 } 430 }
431 } else { 431 } else {
432 for (x = 0; x < 256; x++) { 432 for (x = 0; x < 256; x++) {
433 tmpx0 = sbox(0, x); 433 tmpx0 = (unsigned char)sbox(0, x);
434 tmpx1 = sbox(1, x); 434 tmpx1 = (unsigned char)sbox(1, x);
435 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); 435 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);
436 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); 436 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);
437 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); 437 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);
438 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); 438 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);
439 } 439 }
463 /** 463 /**
464 Encrypts a block of text with Twofish 464 Encrypts a block of text with Twofish
465 @param pt The input plaintext (16 bytes) 465 @param pt The input plaintext (16 bytes)
466 @param ct The output ciphertext (16 bytes) 466 @param ct The output ciphertext (16 bytes)
467 @param skey The key as scheduled 467 @param skey The key as scheduled
468 @return CRYPT_OK if successful
468 */ 469 */
469 #ifdef LTC_CLEAN_STACK 470 #ifdef LTC_CLEAN_STACK
470 static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 471 static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
471 #else 472 #else
472 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 473 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
473 #endif 474 #endif
474 { 475 {
475 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 476 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
476 int r; 477 int r;
477 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) 478 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
517 td = b ^ skey->twofish.K[7]; 518 td = b ^ skey->twofish.K[7];
518 519
519 /* store output */ 520 /* store output */
520 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); 521 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
521 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); 522 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
522 } 523
523 524 return CRYPT_OK;
524 #ifdef LTC_CLEAN_STACK 525 }
525 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 526
526 { 527 #ifdef LTC_CLEAN_STACK
527 _twofish_ecb_encrypt(pt, ct, skey); 528 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
529 {
530 int err = _twofish_ecb_encrypt(pt, ct, skey);
528 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); 531 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
532 return err;
529 } 533 }
530 #endif 534 #endif
531 535
532 /** 536 /**
533 Decrypts a block of text with Twofish 537 Decrypts a block of text with Twofish
534 @param ct The input ciphertext (16 bytes) 538 @param ct The input ciphertext (16 bytes)
535 @param pt The output plaintext (16 bytes) 539 @param pt The output plaintext (16 bytes)
536 @param skey The key as scheduled 540 @param skey The key as scheduled
541 @return CRYPT_OK if successful
537 */ 542 */
538 #ifdef LTC_CLEAN_STACK 543 #ifdef LTC_CLEAN_STACK
539 static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 544 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
540 #else 545 #else
541 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 546 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
542 #endif 547 #endif
543 { 548 {
544 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 549 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
545 int r; 550 int r;
546 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) 551 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
589 d ^= skey->twofish.K[3]; 594 d ^= skey->twofish.K[3];
590 595
591 /* store */ 596 /* store */
592 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); 597 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
593 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); 598 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
594 } 599 return CRYPT_OK;
595 600 }
596 #ifdef LTC_CLEAN_STACK 601
597 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 602 #ifdef LTC_CLEAN_STACK
598 { 603 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
599 _twofish_ecb_decrypt(ct, pt, skey); 604 {
605 int err =_twofish_ecb_decrypt(ct, pt, skey);
600 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); 606 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
607 return err;
601 } 608 }
602 #endif 609 #endif
603 610
604 /** 611 /**
605 Performs a self-test of the Twofish block cipher 612 Performs a self-test of the Twofish block cipher
652 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { 659 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
653 return err; 660 return err;
654 } 661 }
655 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); 662 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
656 twofish_ecb_decrypt(tmp[0], tmp[1], &key); 663 twofish_ecb_decrypt(tmp[0], tmp[1], &key);
657 if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { 664 if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) {
665 #if 0
666 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16));
667 #endif
658 return CRYPT_FAIL_TESTVECTOR; 668 return CRYPT_FAIL_TESTVECTOR;
659 } 669 }
660 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ 670 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
661 for (y = 0; y < 16; y++) tmp[0][y] = 0; 671 for (y = 0; y < 16; y++) tmp[0][y] = 0;
662 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); 672 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
700 710
701 711
702 712
703 713
704 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ 714 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */
705 /* $Revision: 1.8 $ */ 715 /* $Revision: 1.14 $ */
706 /* $Date: 2005/05/05 14:35:58 $ */ 716 /* $Date: 2006/12/04 21:34:03 $ */