Mercurial > dropbear
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 $ */ |