comparison libtomcrypt/src/ciphers/twofish/twofish.c @ 1710:1ff2a1034c52

Fix whitespace changes vs upstream libtomcrypt
author Matt Johnston <matt@ucc.asn.au>
date Wed, 10 Jun 2020 23:01:33 +0800
parents 6dba84798cd5
children
comparison
equal deleted inserted replaced
1709:04155ce30759 1710:1ff2a1034c52
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 9
10 /** 10 /**
11 @file twofish.c 11 @file twofish.c
12 Implementation of Twofish by Tom St Denis 12 Implementation of Twofish by Tom St Denis
13 */ 13 */
14 #include "tomcrypt.h" 14 #include "tomcrypt.h"
15 15
16 #ifdef LTC_TWOFISH 16 #ifdef LTC_TWOFISH
17 17
143 P[1] = p; 143 P[1] = p;
144 B[1] = b; 144 B[1] = b;
145 result = P[0] = B[0] = 0; 145 result = P[0] = B[0] = 0;
146 146
147 /* unrolled branchless GF multiplier */ 147 /* unrolled branchless GF multiplier */
148 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 148 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
149 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 149 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
150 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 150 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
151 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 151 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
152 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 152 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
153 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 153 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
154 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); 154 result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
155 result ^= B[a&1]; 155 result ^= B[a&1];
156 156
157 return result; 157 return result;
158 } 158 }
159 159
160 /* computes [y0 y1 y2 y3] = MDS . [x0] */ 160 /* computes [y0 y1 y2 y3] = MDS . [x0] */
241 { 241 {
242 int x; 242 int x;
243 unsigned char y[4]; 243 unsigned char y[4];
244 for (x = 0; x < 4; x++) { 244 for (x = 0; x < 4; x++) {
245 y[x] = in[x]; 245 y[x] = in[x];
246 } 246 }
247 switch (k) { 247 switch (k) {
248 case 4: 248 case 4:
249 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); 249 y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]);
250 y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); 250 y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]);
251 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); 251 y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]);
437 #else 437 #else
438 /* where to start in the sbox layers */ 438 /* where to start in the sbox layers */
439 /* small ram variant */ 439 /* small ram variant */
440 switch (k) { 440 switch (k) {
441 case 4 : skey->twofish.start = 0; break; 441 case 4 : skey->twofish.start = 0; break;
442 case 3 : skey->twofish.start = 1; break; 442 case 3 : skey->twofish.start = 1; break;
443 default: skey->twofish.start = 2; break; 443 default: skey->twofish.start = 2; break;
444 } 444 }
445 #endif 445 #endif
446 return CRYPT_OK; 446 return CRYPT_OK;
447 } 447 }
471 { 471 {
472 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 472 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
473 int r; 473 int r;
474 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) 474 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
475 ulong32 *S1, *S2, *S3, *S4; 475 ulong32 *S1, *S2, *S3, *S4;
476 #endif 476 #endif
477 477
478 LTC_ARGCHK(pt != NULL); 478 LTC_ARGCHK(pt != NULL);
479 LTC_ARGCHK(ct != NULL); 479 LTC_ARGCHK(ct != NULL);
480 LTC_ARGCHK(skey != NULL); 480 LTC_ARGCHK(skey != NULL);
481 481
482 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) 482 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
483 S1 = skey->twofish.S[0]; 483 S1 = skey->twofish.S[0];
484 S2 = skey->twofish.S[1]; 484 S2 = skey->twofish.S[1];
485 S3 = skey->twofish.S[2]; 485 S3 = skey->twofish.S[2];
486 S4 = skey->twofish.S[3]; 486 S4 = skey->twofish.S[3];
487 #endif 487 #endif
488 488
489 LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); 489 LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
490 LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); 490 LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
491 a ^= skey->twofish.K[0]; 491 a ^= skey->twofish.K[0];
492 b ^= skey->twofish.K[1]; 492 b ^= skey->twofish.K[1];
493 c ^= skey->twofish.K[2]; 493 c ^= skey->twofish.K[2];
494 d ^= skey->twofish.K[3]; 494 d ^= skey->twofish.K[3];
495 495
496 k = skey->twofish.K + 8; 496 k = skey->twofish.K + 8;
497 for (r = 8; r != 0; --r) { 497 for (r = 8; r != 0; --r) {
498 t2 = g1_func(b, skey); 498 t2 = g1_func(b, skey);
499 t1 = g_func(a, skey) + t2; 499 t1 = g_func(a, skey) + t2;
500 c = RORc(c ^ (t1 + k[0]), 1); 500 c = RORc(c ^ (t1 + k[0]), 1);
501 d = ROLc(d, 1) ^ (t2 + t1 + k[1]); 501 d = ROLc(d, 1) ^ (t2 + t1 + k[1]);
502 502
503 t2 = g1_func(d, skey); 503 t2 = g1_func(d, skey);
504 t1 = g_func(c, skey) + t2; 504 t1 = g_func(c, skey) + t2;
505 a = RORc(a ^ (t1 + k[2]), 1); 505 a = RORc(a ^ (t1 + k[2]), 1);
506 b = ROLc(b, 1) ^ (t2 + t1 + k[3]); 506 b = ROLc(b, 1) ^ (t2 + t1 + k[3]);
507 k += 4; 507 k += 4;
508 } 508 }
509 509
510 /* output with "undo last swap" */ 510 /* output with "undo last swap" */
511 ta = c ^ skey->twofish.K[4]; 511 ta = c ^ skey->twofish.K[4];
512 tb = d ^ skey->twofish.K[5]; 512 tb = d ^ skey->twofish.K[5];
513 tc = a ^ skey->twofish.K[6]; 513 tc = a ^ skey->twofish.K[6];
531 531
532 /** 532 /**
533 Decrypts a block of text with Twofish 533 Decrypts a block of text with Twofish
534 @param ct The input ciphertext (16 bytes) 534 @param ct The input ciphertext (16 bytes)
535 @param pt The output plaintext (16 bytes) 535 @param pt The output plaintext (16 bytes)
536 @param skey The key as scheduled 536 @param skey The key as scheduled
537 @return CRYPT_OK if successful 537 @return CRYPT_OK if successful
538 */ 538 */
539 #ifdef LTC_CLEAN_STACK 539 #ifdef LTC_CLEAN_STACK
540 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 540 static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
541 #else 541 #else
544 { 544 {
545 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; 545 ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
546 int r; 546 int r;
547 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) 547 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
548 ulong32 *S1, *S2, *S3, *S4; 548 ulong32 *S1, *S2, *S3, *S4;
549 #endif 549 #endif
550 550
551 LTC_ARGCHK(pt != NULL); 551 LTC_ARGCHK(pt != NULL);
552 LTC_ARGCHK(ct != NULL); 552 LTC_ARGCHK(ct != NULL);
553 LTC_ARGCHK(skey != NULL); 553 LTC_ARGCHK(skey != NULL);
554 554
555 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) 555 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
556 S1 = skey->twofish.S[0]; 556 S1 = skey->twofish.S[0];
557 S2 = skey->twofish.S[1]; 557 S2 = skey->twofish.S[1];
558 S3 = skey->twofish.S[2]; 558 S3 = skey->twofish.S[2];
559 S4 = skey->twofish.S[3]; 559 S4 = skey->twofish.S[3];
560 #endif 560 #endif
561 561
562 /* load input */ 562 /* load input */
563 LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); 563 LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
564 LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); 564 LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]);
565 565
586 /* pre-white */ 586 /* pre-white */
587 a ^= skey->twofish.K[0]; 587 a ^= skey->twofish.K[0];
588 b ^= skey->twofish.K[1]; 588 b ^= skey->twofish.K[1];
589 c ^= skey->twofish.K[2]; 589 c ^= skey->twofish.K[2];
590 d ^= skey->twofish.K[3]; 590 d ^= skey->twofish.K[3];
591 591
592 /* store */ 592 /* store */
593 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); 593 STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
594 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); 594 STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
595 return CRYPT_OK; 595 return CRYPT_OK;
596 } 596 }
610 */ 610 */
611 int twofish_test(void) 611 int twofish_test(void)
612 { 612 {
613 #ifndef LTC_TEST 613 #ifndef LTC_TEST
614 return CRYPT_NOP; 614 return CRYPT_NOP;
615 #else 615 #else
616 static const struct { 616 static const struct {
617 int keylen; 617 int keylen;
618 unsigned char key[32], pt[16], ct[16]; 618 unsigned char key[32], pt[16], ct[16];
619 } tests[] = { 619 } tests[] = {
620 { 16, 620 { 16,
621 { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 621 { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
631 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, 631 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 },
632 { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 632 { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
633 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, 633 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
634 { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 634 { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
635 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } 635 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
636 }, { 636 }, {
637 32, 637 32,
638 { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 638 { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
639 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 639 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
640 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 640 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
641 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, 641 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F },
645 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } 645 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }
646 } 646 }
647 }; 647 };
648 648
649 649
650 symmetric_key key; 650 symmetric_key key;
651 unsigned char tmp[2][16]; 651 unsigned char tmp[2][16];
652 int err, i, y; 652 int err, i, y;
653 653
654 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { 654 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
655 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { 655 if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
656 return err; 656 return err;
657 } 657 }
658 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); 658 twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
659 twofish_ecb_decrypt(tmp[0], tmp[1], &key); 659 twofish_ecb_decrypt(tmp[0], tmp[1], &key);
660 if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Twofish Encrypt", i) != 0 || 660 if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Twofish Encrypt", i) != 0 ||
661 compare_testvector(tmp[1], 16, tests[i].pt, 16, "Twofish Decrypt", i) != 0) { 661 compare_testvector(tmp[1], 16, tests[i].pt, 16, "Twofish Decrypt", i) != 0) {
662 return CRYPT_FAIL_TESTVECTOR; 662 return CRYPT_FAIL_TESTVECTOR;
663 } 663 }
664 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ 664 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
665 for (y = 0; y < 16; y++) tmp[0][y] = 0; 665 for (y = 0; y < 16; y++) tmp[0][y] = 0;
666 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); 666 for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
667 for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); 667 for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
668 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; 668 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
669 } 669 }
670 return CRYPT_OK; 670 return CRYPT_OK;
671 #endif 671 #endif
672 } 672 }
673 673
674 /** Terminate the context 674 /** Terminate the context
675 @param skey The scheduled key 675 @param skey The scheduled key
676 */ 676 */
677 void twofish_done(symmetric_key *skey) 677 void twofish_done(symmetric_key *skey)
678 { 678 {
679 LTC_UNUSED_PARAM(skey); 679 LTC_UNUSED_PARAM(skey);