Mercurial > dropbear
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); |