comparison libtomcrypt/src/ciphers/twofish/twofish.c @ 382:0cbe8f6dbf9e

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f) to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:41:05 +0000
parents 1b9e69c058d2
children eef377591301
comparison
equal deleted inserted replaced
379:b66a00272a90 382:0cbe8f6dbf9e
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
412 412
413 #ifndef TWOFISH_SMALL 413 #ifndef TWOFISH_SMALL
414 /* make the sboxes (large ram variant) */ 414 /* make the sboxes (large ram variant) */
415 if (k == 2) { 415 if (k == 2) {
416 for (x = 0; x < 256; x++) { 416 for (x = 0; x < 256; x++) {
417 tmpx0 = sbox(0, x); 417 tmpx0 = (unsigned char)sbox(0, x);
418 tmpx1 = sbox(1, x); 418 tmpx1 = (unsigned char)sbox(1, x);
419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); 419 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); 420 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); 421 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); 422 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3);
423 } 423 }
424 } else if (k == 3) { 424 } else if (k == 3) {
425 for (x = 0; x < 256; x++) { 425 for (x = 0; x < 256; x++) {
426 tmpx0 = sbox(0, x); 426 tmpx0 = (unsigned char)sbox(0, x);
427 tmpx1 = sbox(1, x); 427 tmpx1 = (unsigned char)sbox(1, x);
428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); 428 skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); 429 skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); 430 skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); 431 skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3);
432 } 432 }
433 } else { 433 } else {
434 for (x = 0; x < 256; x++) { 434 for (x = 0; x < 256; x++) {
435 tmpx0 = sbox(0, x); 435 tmpx0 = (unsigned char)sbox(0, x);
436 tmpx1 = sbox(1, x); 436 tmpx1 = (unsigned char)sbox(1, x);
437 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); 437 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);
438 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); 438 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);
439 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); 439 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);
440 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); 440 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);
441 } 441 }
465 /** 465 /**
466 Encrypts a block of text with Twofish 466 Encrypts a block of text with Twofish
467 @param pt The input plaintext (16 bytes) 467 @param pt The input plaintext (16 bytes)
468 @param ct The output ciphertext (16 bytes) 468 @param ct The output ciphertext (16 bytes)
469 @param skey The key as scheduled 469 @param skey The key as scheduled
470 @return CRYPT_OK if successful
470 */ 471 */
471 #ifdef LTC_CLEAN_STACK 472 #ifdef LTC_CLEAN_STACK
472 static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 473 static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
473 #else 474 #else
474 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 475 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
475 #endif 476 #endif
476 { 477 {
477 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 478 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
478 int r; 479 int r;
479 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) 480 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
519 td = b ^ skey->twofish.K[7]; 520 td = b ^ skey->twofish.K[7];
520 521
521 /* store output */ 522 /* store output */
522 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); 523 STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
523 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); 524 STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
524 } 525
525 526 return CRYPT_OK;
526 #ifdef LTC_CLEAN_STACK 527 }
527 void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 528
528 { 529 #ifdef LTC_CLEAN_STACK
529 _twofish_ecb_encrypt(pt, ct, skey); 530 int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
531 {
532 int err = _twofish_ecb_encrypt(pt, ct, skey);
530 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); 533 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
534 return err;
531 } 535 }
532 #endif 536 #endif
533 537
534 /** 538 /**
535 Decrypts a block of text with Twofish 539 Decrypts a block of text with Twofish
536 @param ct The input ciphertext (16 bytes) 540 @param ct The input ciphertext (16 bytes)
537 @param pt The output plaintext (16 bytes) 541 @param pt The output plaintext (16 bytes)
538 @param skey The key as scheduled 542 @param skey The key as scheduled
543 @return CRYPT_OK if successful
539 */ 544 */
540 #ifdef LTC_CLEAN_STACK 545 #ifdef LTC_CLEAN_STACK
541 static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 546 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
542 #else 547 #else
543 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 548 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
544 #endif 549 #endif
545 { 550 {
546 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 551 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
547 int r; 552 int r;
548 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) 553 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
591 d ^= skey->twofish.K[3]; 596 d ^= skey->twofish.K[3];
592 597
593 /* store */ 598 /* store */
594 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); 599 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
595 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); 600 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
596 } 601 return CRYPT_OK;
597 602 }
598 #ifdef LTC_CLEAN_STACK 603
599 void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 604 #ifdef LTC_CLEAN_STACK
600 { 605 int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
601 _twofish_ecb_decrypt(ct, pt, skey); 606 {
607 int err =_twofish_ecb_decrypt(ct, pt, skey);
602 burn_stack(sizeof(ulong32) * 10 + sizeof(int)); 608 burn_stack(sizeof(ulong32) * 10 + sizeof(int));
609 return err;
603 } 610 }
604 #endif 611 #endif
605 612
606 /** 613 /**
607 Performs a self-test of the Twofish block cipher 614 Performs a self-test of the Twofish block cipher
654 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { 661 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
655 return err; 662 return err;
656 } 663 }
657 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); 664 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
658 twofish_ecb_decrypt(tmp[0], tmp[1], &key); 665 twofish_ecb_decrypt(tmp[0], tmp[1], &key);
659 if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { 666 if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) {
667 #if 0
668 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16));
669 #endif
660 return CRYPT_FAIL_TESTVECTOR; 670 return CRYPT_FAIL_TESTVECTOR;
661 } 671 }
662 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ 672 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
663 for (y = 0; y < 16; y++) tmp[0][y] = 0; 673 for (y = 0; y < 16; y++) tmp[0][y] = 0;
664 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); 674 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
702 712
703 713
704 714
705 715
706 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ 716 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */
707 /* $Revision: 1.8 $ */ 717 /* $Revision: 1.14 $ */
708 /* $Date: 2005/05/05 14:35:58 $ */ 718 /* $Date: 2006/12/04 21:34:03 $ */