;;;; twofish.lisp -- implementation of Counterpane's Twofish AES candidate (in-package :crypto) ;;; various constant data arrays used by Twofish (declaim (type (simple-array (unsigned-byte 8) (256)) +twofish-q0+ +twofish-q1+)) (declaim (type (simple-array (unsigned-byte 8) (255)) +twofish-exp-to-poly+ +twofish-poly-to-exp+)) (defconst +twofish-q0+ #8@(#xA9 #x67 #xB3 #xE8 #x04 #xFD #xA3 #x76 #x9A #x92 #x80 #x78 #xE4 #xDD #xD1 #x38 #x0D #xC6 #x35 #x98 #x18 #xF7 #xEC #x6C #x43 #x75 #x37 #x26 #xFA #x13 #x94 #x48 #xF2 #xD0 #x8B #x30 #x84 #x54 #xDF #x23 #x19 #x5B #x3D #x59 #xF3 #xAE #xA2 #x82 #x63 #x01 #x83 #x2E #xD9 #x51 #x9B #x7C #xA6 #xEB #xA5 #xBE #x16 #x0C #xE3 #x61 #xC0 #x8C #x3A #xF5 #x73 #x2C #x25 #x0B #xBB #x4E #x89 #x6B #x53 #x6A #xB4 #xF1 #xE1 #xE6 #xBD #x45 #xE2 #xF4 #xB6 #x66 #xCC #x95 #x03 #x56 #xD4 #x1C #x1E #xD7 #xFB #xC3 #x8E #xB5 #xE9 #xCF #xBF #xBA #xEA #x77 #x39 #xAF #x33 #xC9 #x62 #x71 #x81 #x79 #x09 #xAD #x24 #xCD #xF9 #xD8 #xE5 #xC5 #xB9 #x4D #x44 #x08 #x86 #xE7 #xA1 #x1D #xAA #xED #x06 #x70 #xB2 #xD2 #x41 #x7B #xA0 #x11 #x31 #xC2 #x27 #x90 #x20 #xF6 #x60 #xFF #x96 #x5C #xB1 #xAB #x9E #x9C #x52 #x1B #x5F #x93 #x0A #xEF #x91 #x85 #x49 #xEE #x2D #x4F #x8F #x3B #x47 #x87 #x6D #x46 #xD6 #x3E #x69 #x64 #x2A #xCE #xCB #x2F #xFC #x97 #x05 #x7A #xAC #x7F #xD5 #x1A #x4B #x0E #xA7 #x5A #x28 #x14 #x3F #x29 #x88 #x3C #x4C #x02 #xB8 #xDA #xB0 #x17 #x55 #x1F #x8A #x7D #x57 #xC7 #x8D #x74 #xB7 #xC4 #x9F #x72 #x7E #x15 #x22 #x12 #x58 #x07 #x99 #x34 #x6E #x50 #xDE #x68 #x65 #xBC #xDB #xF8 #xC8 #xA8 #x2B #x40 #xDC #xFE #x32 #xA4 #xCA #x10 #x21 #xF0 #xD3 #x5D #x0F #x00 #x6F #x9D #x36 #x42 #x4A #x5E #xC1 #xE0)) (defconst +twofish-q1+ #8@(#x75 #xF3 #xC6 #xF4 #xDB #x7B #xFB #xC8 #x4A #xD3 #xE6 #x6B #x45 #x7D #xE8 #x4B #xD6 #x32 #xD8 #xFD #x37 #x71 #xF1 #xE1 #x30 #x0F #xF8 #x1B #x87 #xFA #x06 #x3F #x5E #xBA #xAE #x5B #x8A #x00 #xBC #x9D #x6D #xC1 #xB1 #x0E #x80 #x5D #xD2 #xD5 #xA0 #x84 #x07 #x14 #xB5 #x90 #x2C #xA3 #xB2 #x73 #x4C #x54 #x92 #x74 #x36 #x51 #x38 #xB0 #xBD #x5A #xFC #x60 #x62 #x96 #x6C #x42 #xF7 #x10 #x7C #x28 #x27 #x8C #x13 #x95 #x9C #xC7 #x24 #x46 #x3B #x70 #xCA #xE3 #x85 #xCB #x11 #xD0 #x93 #xB8 #xA6 #x83 #x20 #xFF #x9F #x77 #xC3 #xCC #x03 #x6F #x08 #xBF #x40 #xE7 #x2B #xE2 #x79 #x0C #xAA #x82 #x41 #x3A #xEA #xB9 #xE4 #x9A #xA4 #x97 #x7E #xDA #x7A #x17 #x66 #x94 #xA1 #x1D #x3D #xF0 #xDE #xB3 #x0B #x72 #xA7 #x1C #xEF #xD1 #x53 #x3E #x8F #x33 #x26 #x5F #xEC #x76 #x2A #x49 #x81 #x88 #xEE #x21 #xC4 #x1A #xEB #xD9 #xC5 #x39 #x99 #xCD #xAD #x31 #x8B #x01 #x18 #x23 #xDD #x1F #x4E #x2D #xF9 #x48 #x4F #xF2 #x65 #x8E #x78 #x5C #x58 #x19 #x8D #xE5 #x98 #x57 #x67 #x7F #x05 #x64 #xAF #x63 #xB6 #xFE #xF5 #xB7 #x3C #xA5 #xCE #xE9 #x68 #x44 #xE0 #x4D #x43 #x69 #x29 #x2E #xAC #x15 #x59 #xA8 #x0A #x9E #x6E #x47 #xDF #x34 #x35 #x6A #xCF #xDC #x22 #xC9 #xC0 #x9B #x89 #xD4 #xED #xAB #x12 #xA2 #x0D #x52 #xBB #x02 #x2F #xA9 #xD7 #x61 #x1E #xB4 #x50 #x04 #xF6 #xC2 #x16 #x25 #x86 #x56 #x55 #x09 #xBE #x91)) (defconst +twofish-rs+ #8@(#x01 #xA4 #x02 #xA4 #xA4 #x56 #xA1 #x55 #x55 #x82 #xFC #x87 #x87 #xF3 #xC1 #x5A #x5A #x1E #x47 #x58 #x58 #xC6 #xAE #xDB #xDB #x68 #x3D #x9E #x9E #xE5 #x19 #x03)) (defconst +twofish-exp-to-poly+ #8@(#x01 #x02 #x04 #x08 #x10 #x20 #x40 #x80 #x4D #x9A #x79 #xF2 #xA9 #x1F #x3E #x7C #xF8 #xBD #x37 #x6E #xDC #xF5 #xA7 #x03 #x06 #x0C #x18 #x30 #x60 #xC0 #xCD #xD7 #xE3 #x8B #x5B #xB6 #x21 #x42 #x84 #x45 #x8A #x59 #xB2 #x29 #x52 #xA4 #x05 #x0A #x14 #x28 #x50 #xA0 #x0D #x1A #x34 #x68 #xD0 #xED #x97 #x63 #xC6 #xC1 #xCF #xD3 #xEB #x9B #x7B #xF6 #xA1 #x0F #x1E #x3C #x78 #xF0 #xAD #x17 #x2E #x5C #xB8 #x3D #x7A #xF4 #xA5 #x07 #x0E #x1C #x38 #x70 #xE0 #x8D #x57 #xAE #x11 #x22 #x44 #x88 #x5D #xBA #x39 #x72 #xE4 #x85 #x47 #x8E #x51 #xA2 #x09 #x12 #x24 #x48 #x90 #x6D #xDA #xF9 #xBF #x33 #x66 #xCC #xD5 #xE7 #x83 #x4B #x96 #x61 #xC2 #xC9 #xDF #xF3 #xAB #x1B #x36 #x6C #xD8 #xFD #xB7 #x23 #x46 #x8C #x55 #xAA #x19 #x32 #x64 #xC8 #xDD #xF7 #xA3 #x0B #x16 #x2C #x58 #xB0 #x2D #x5A #xB4 #x25 #x4A #x94 #x65 #xCA #xD9 #xFF #xB3 #x2B #x56 #xAC #x15 #x2A #x54 #xA8 #x1D #x3A #x74 #xE8 #x9D #x77 #xEE #x91 #x6F #xDE #xF1 #xAF #x13 #x26 #x4C #x98 #x7D #xFA #xB9 #x3F #x7E #xFC #xB5 #x27 #x4E #x9C #x75 #xEA #x99 #x7F #xFE #xB1 #x2F #x5E #xBC #x35 #x6A #xD4 #xE5 #x87 #x43 #x86 #x41 #x82 #x49 #x92 #x69 #xD2 #xE9 #x9F #x73 #xE6 #x81 #x4F #x9E #x71 #xE2 #x89 #x5F #xBE #x31 #x62 #xC4 #xC5 #xC7 #xC3 #xCB #xDB #xFB #xBB #x3B #x76 #xEC #x95 #x67 #xCE #xD1 #xEF #x93 #x6B #xD6 #xE1 #x8F #x53 #xA6)) (defconst +twofish-poly-to-exp+ #8@(#x00 #x01 #x17 #x02 #x2E #x18 #x53 #x03 #x6A #x2F #x93 #x19 #x34 #x54 #x45 #x04 #x5C #x6B #xB6 #x30 #xA6 #x94 #x4B #x1A #x8C #x35 #x81 #x55 #xAA #x46 #x0D #x05 #x24 #x5D #x87 #x6C #x9B #xB7 #xC1 #x31 #x2B #xA7 #xA3 #x95 #x98 #x4C #xCA #x1B #xE6 #x8D #x73 #x36 #xCD #x82 #x12 #x56 #x62 #xAB #xF0 #x47 #x4F #x0E #xBD #x06 #xD4 #x25 #xD2 #x5E #x27 #x88 #x66 #x6D #xD6 #x9C #x79 #xB8 #x08 #xC2 #xDF #x32 #x68 #x2C #xFD #xA8 #x8A #xA4 #x5A #x96 #x29 #x99 #x22 #x4D #x60 #xCB #xE4 #x1C #x7B #xE7 #x3B #x8E #x9E #x74 #xF4 #x37 #xD8 #xCE #xF9 #x83 #x6F #x13 #xB2 #x57 #xE1 #x63 #xDC #xAC #xC4 #xF1 #xAF #x48 #x0A #x50 #x42 #x0F #xBA #xBE #xC7 #x07 #xDE #xD5 #x78 #x26 #x65 #xD3 #xD1 #x5F #xE3 #x28 #x21 #x89 #x59 #x67 #xFC #x6E #xB1 #xD7 #xF8 #x9D #xF3 #x7A #x3A #xB9 #xC6 #x09 #x41 #xC3 #xAE #xE0 #xDB #x33 #x44 #x69 #x92 #x2D #x52 #xFE #x16 #xA9 #x0C #x8B #x80 #xA5 #x4A #x5B #xB5 #x97 #xC9 #x2A #xA2 #x9A #xC0 #x23 #x86 #x4E #xBC #x61 #xEF #xCC #x11 #xE5 #x72 #x1D #x3D #x7C #xEB #xE8 #xE9 #x3C #xEA #x8F #x7D #x9F #xEC #x75 #x1E #xF5 #x3E #x38 #xF6 #xD9 #x3F #xCF #x76 #xFA #x1F #x84 #xA0 #x70 #xED #x14 #x90 #xB3 #x7E #x58 #xFB #xE2 #x20 #x64 #xD0 #xDD #x77 #xAD #xDA #xC5 #x40 #xF2 #x39 #xB0 #xF7 #x49 #xB4 #x0B #x7F #x51 #x15 #x43 #x91 #x10 #x71 #xBB #xEE #xBF #x85 #xC8 #xA1)) (declaim (type (simple-array (unsigned-byte 32) (256)) +twofish-MDS0+ +twofish-MDS1+ +twofish-MDS2+ +twofish-MDS3+)) (defconst +twofish-MDS0+ #32@(#xBCBC3275 #xECEC21F3 #x202043C6 #xB3B3C9F4 #xDADA03DB #x02028B7B #xE2E22BFB #x9E9EFAC8 #xC9C9EC4A #xD4D409D3 #x18186BE6 #x1E1E9F6B #x98980E45 #xB2B2387D #xA6A6D2E8 #x2626B74B #x3C3C57D6 #x93938A32 #x8282EED8 #x525298FD #x7B7BD437 #xBBBB3771 #x5B5B97F1 #x474783E1 #x24243C30 #x5151E20F #xBABAC6F8 #x4A4AF31B #xBFBF4887 #x0D0D70FA #xB0B0B306 #x7575DE3F #xD2D2FD5E #x7D7D20BA #x666631AE #x3A3AA35B #x59591C8A #x00000000 #xCDCD93BC #x1A1AE09D #xAEAE2C6D #x7F7FABC1 #x2B2BC7B1 #xBEBEB90E #xE0E0A080 #x8A8A105D #x3B3B52D2 #x6464BAD5 #xD8D888A0 #xE7E7A584 #x5F5FE807 #x1B1B1114 #x2C2CC2B5 #xFCFCB490 #x3131272C #x808065A3 #x73732AB2 #x0C0C8173 #x79795F4C #x6B6B4154 #x4B4B0292 #x53536974 #x94948F36 #x83831F51 #x2A2A3638 #xC4C49CB0 #x2222C8BD #xD5D5F85A #xBDBDC3FC #x48487860 #xFFFFCE62 #x4C4C0796 #x4141776C #xC7C7E642 #xEBEB24F7 #x1C1C1410 #x5D5D637C #x36362228 #x6767C027 #xE9E9AF8C #x4444F913 #x1414EA95 #xF5F5BB9C #xCFCF18C7 #x3F3F2D24 #xC0C0E346 #x7272DB3B #x54546C70 #x29294CCA #xF0F035E3 #x0808FE85 #xC6C617CB #xF3F34F11 #x8C8CE4D0 #xA4A45993 #xCACA96B8 #x68683BA6 #xB8B84D83 #x38382820 #xE5E52EFF #xADAD569F #x0B0B8477 #xC8C81DC3 #x9999FFCC #x5858ED03 #x19199A6F #x0E0E0A08 #x95957EBF #x70705040 #xF7F730E7 #x6E6ECF2B #x1F1F6EE2 #xB5B53D79 #x09090F0C #x616134AA #x57571682 #x9F9F0B41 #x9D9D803A #x111164EA #x2525CDB9 #xAFAFDDE4 #x4545089A #xDFDF8DA4 #xA3A35C97 #xEAEAD57E #x353558DA #xEDEDD07A #x4343FC17 #xF8F8CB66 #xFBFBB194 #x3737D3A1 #xFAFA401D #xC2C2683D #xB4B4CCF0 #x32325DDE #x9C9C71B3 #x5656E70B #xE3E3DA72 #x878760A7 #x15151B1C #xF9F93AEF #x6363BFD1 #x3434A953 #x9A9A853E #xB1B1428F #x7C7CD133 #x88889B26 #x3D3DA65F #xA1A1D7EC #xE4E4DF76 #x8181942A #x91910149 #x0F0FFB81 #xEEEEAA88 #x161661EE #xD7D77321 #x9797F5C4 #xA5A5A81A #xFEFE3FEB #x6D6DB5D9 #x7878AEC5 #xC5C56D39 #x1D1DE599 #x7676A4CD #x3E3EDCAD #xCBCB6731 #xB6B6478B #xEFEF5B01 #x12121E18 #x6060C523 #x6A6AB0DD #x4D4DF61F #xCECEE94E #xDEDE7C2D #x55559DF9 #x7E7E5A48 #x2121B24F #x03037AF2 #xA0A02665 #x5E5E198E #x5A5A6678 #x65654B5C #x62624E58 #xFDFD4519 #x0606F48D #x404086E5 #xF2F2BE98 #x3333AC57 #x17179067 #x05058E7F #xE8E85E05 #x4F4F7D64 #x89896AAF #x10109563 #x74742FB6 #x0A0A75FE #x5C5C92F5 #x9B9B74B7 #x2D2D333C #x3030D6A5 #x2E2E49CE #x494989E9 #x46467268 #x77775544 #xA8A8D8E0 #x9696044D #x2828BD43 #xA9A92969 #xD9D97929 #x8686912E #xD1D187AC #xF4F44A15 #x8D8D1559 #xD6D682A8 #xB9B9BC0A #x42420D9E #xF6F6C16E #x2F2FB847 #xDDDD06DF #x23233934 #xCCCC6235 #xF1F1C46A #xC1C112CF #x8585EBDC #x8F8F9E22 #x7171A1C9 #x9090F0C0 #xAAAA539B #x0101F189 #x8B8BE1D4 #x4E4E8CED #x8E8E6FAB #xABABA212 #x6F6F3EA2 #xE6E6540D #xDBDBF252 #x92927BBB #xB7B7B602 #x6969CA2F #x3939D9A9 #xD3D30CD7 #xA7A72361 #xA2A2AD1E #xC3C399B4 #x6C6C4450 #x07070504 #x04047FF6 #x272746C2 #xACACA716 #xD0D07625 #x50501386 #xDCDCF756 #x84841A55 #xE1E15109 #x7A7A25BE #x1313EF91)) (defconst +twofish-MDS1+ #32@(#xA9D93939 #x67901717 #xB3719C9C #xE8D2A6A6 #x04050707 #xFD985252 #xA3658080 #x76DFE4E4 #x9A084545 #x92024B4B #x80A0E0E0 #x78665A5A #xE4DDAFAF #xDDB06A6A #xD1BF6363 #x38362A2A #x0D54E6E6 #xC6432020 #x3562CCCC #x98BEF2F2 #x181E1212 #xF724EBEB #xECD7A1A1 #x6C774141 #x43BD2828 #x7532BCBC #x37D47B7B #x269B8888 #xFA700D0D #x13F94444 #x94B1FBFB #x485A7E7E #xF27A0303 #xD0E48C8C #x8B47B6B6 #x303C2424 #x84A5E7E7 #x54416B6B #xDF06DDDD #x23C56060 #x1945FDFD #x5BA33A3A #x3D68C2C2 #x59158D8D #xF321ECEC #xAE316666 #xA23E6F6F #x82165757 #x63951010 #x015BEFEF #x834DB8B8 #x2E918686 #xD9B56D6D #x511F8383 #x9B53AAAA #x7C635D5D #xA63B6868 #xEB3FFEFE #xA5D63030 #xBE257A7A #x16A7ACAC #x0C0F0909 #xE335F0F0 #x6123A7A7 #xC0F09090 #x8CAFE9E9 #x3A809D9D #xF5925C5C #x73810C0C #x2C273131 #x2576D0D0 #x0BE75656 #xBB7B9292 #x4EE9CECE #x89F10101 #x6B9F1E1E #x53A93434 #x6AC4F1F1 #xB499C3C3 #xF1975B5B #xE1834747 #xE66B1818 #xBDC82222 #x450E9898 #xE26E1F1F #xF4C9B3B3 #xB62F7474 #x66CBF8F8 #xCCFF9999 #x95EA1414 #x03ED5858 #x56F7DCDC #xD4E18B8B #x1C1B1515 #x1EADA2A2 #xD70CD3D3 #xFB2BE2E2 #xC31DC8C8 #x8E195E5E #xB5C22C2C #xE9894949 #xCF12C1C1 #xBF7E9595 #xBA207D7D #xEA641111 #x77840B0B #x396DC5C5 #xAF6A8989 #x33D17C7C #xC9A17171 #x62CEFFFF #x7137BBBB #x81FB0F0F #x793DB5B5 #x0951E1E1 #xADDC3E3E #x242D3F3F #xCDA47676 #xF99D5555 #xD8EE8282 #xE5864040 #xC5AE7878 #xB9CD2525 #x4D049696 #x44557777 #x080A0E0E #x86135050 #xE730F7F7 #xA1D33737 #x1D40FAFA #xAA346161 #xED8C4E4E #x06B3B0B0 #x706C5454 #xB22A7373 #xD2523B3B #x410B9F9F #x7B8B0202 #xA088D8D8 #x114FF3F3 #x3167CBCB #xC2462727 #x27C06767 #x90B4FCFC #x20283838 #xF67F0404 #x60784848 #xFF2EE5E5 #x96074C4C #x5C4B6565 #xB1C72B2B #xAB6F8E8E #x9E0D4242 #x9CBBF5F5 #x52F2DBDB #x1BF34A4A #x5FA63D3D #x9359A4A4 #x0ABCB9B9 #xEF3AF9F9 #x91EF1313 #x85FE0808 #x49019191 #xEE611616 #x2D7CDEDE #x4FB22121 #x8F42B1B1 #x3BDB7272 #x47B82F2F #x8748BFBF #x6D2CAEAE #x46E3C0C0 #xD6573C3C #x3E859A9A #x6929A9A9 #x647D4F4F #x2A948181 #xCE492E2E #xCB17C6C6 #x2FCA6969 #xFCC3BDBD #x975CA3A3 #x055EE8E8 #x7AD0EDED #xAC87D1D1 #x7F8E0505 #xD5BA6464 #x1AA8A5A5 #x4BB72626 #x0EB9BEBE #xA7608787 #x5AF8D5D5 #x28223636 #x14111B1B #x3FDE7575 #x2979D9D9 #x88AAEEEE #x3C332D2D #x4C5F7979 #x02B6B7B7 #xB896CACA #xDA583535 #xB09CC4C4 #x17FC4343 #x551A8484 #x1FF64D4D #x8A1C5959 #x7D38B2B2 #x57AC3333 #xC718CFCF #x8DF40606 #x74695353 #xB7749B9B #xC4F59797 #x9F56ADAD #x72DAE3E3 #x7ED5EAEA #x154AF4F4 #x229E8F8F #x12A2ABAB #x584E6262 #x07E85F5F #x99E51D1D #x34392323 #x6EC1F6F6 #x50446C6C #xDE5D3232 #x68724646 #x6526A0A0 #xBC93CDCD #xDB03DADA #xF8C6BABA #xC8FA9E9E #xA882D6D6 #x2BCF6E6E #x40507070 #xDCEB8585 #xFE750A0A #x328A9393 #xA48DDFDF #xCA4C2929 #x10141C1C #x2173D7D7 #xF0CCB4B4 #xD309D4D4 #x5D108A8A #x0FE25151 #x00000000 #x6F9A1919 #x9DE01A1A #x368F9494 #x42E6C7C7 #x4AECC9C9 #x5EFDD2D2 #xC1AB7F7F #xE0D8A8A8)) (defconst +twofish-MDS2+ #32@(#xBC75BC32 #xECF3EC21 #x20C62043 #xB3F4B3C9 #xDADBDA03 #x027B028B #xE2FBE22B #x9EC89EFA #xC94AC9EC #xD4D3D409 #x18E6186B #x1E6B1E9F #x9845980E #xB27DB238 #xA6E8A6D2 #x264B26B7 #x3CD63C57 #x9332938A #x82D882EE #x52FD5298 #x7B377BD4 #xBB71BB37 #x5BF15B97 #x47E14783 #x2430243C #x510F51E2 #xBAF8BAC6 #x4A1B4AF3 #xBF87BF48 #x0DFA0D70 #xB006B0B3 #x753F75DE #xD25ED2FD #x7DBA7D20 #x66AE6631 #x3A5B3AA3 #x598A591C #x00000000 #xCDBCCD93 #x1A9D1AE0 #xAE6DAE2C #x7FC17FAB #x2BB12BC7 #xBE0EBEB9 #xE080E0A0 #x8A5D8A10 #x3BD23B52 #x64D564BA #xD8A0D888 #xE784E7A5 #x5F075FE8 #x1B141B11 #x2CB52CC2 #xFC90FCB4 #x312C3127 #x80A38065 #x73B2732A #x0C730C81 #x794C795F #x6B546B41 #x4B924B02 #x53745369 #x9436948F #x8351831F #x2A382A36 #xC4B0C49C #x22BD22C8 #xD55AD5F8 #xBDFCBDC3 #x48604878 #xFF62FFCE #x4C964C07 #x416C4177 #xC742C7E6 #xEBF7EB24 #x1C101C14 #x5D7C5D63 #x36283622 #x672767C0 #xE98CE9AF #x441344F9 #x149514EA #xF59CF5BB #xCFC7CF18 #x3F243F2D #xC046C0E3 #x723B72DB #x5470546C #x29CA294C #xF0E3F035 #x088508FE #xC6CBC617 #xF311F34F #x8CD08CE4 #xA493A459 #xCAB8CA96 #x68A6683B #xB883B84D #x38203828 #xE5FFE52E #xAD9FAD56 #x0B770B84 #xC8C3C81D #x99CC99FF #x580358ED #x196F199A #x0E080E0A #x95BF957E #x70407050 #xF7E7F730 #x6E2B6ECF #x1FE21F6E #xB579B53D #x090C090F #x61AA6134 #x57825716 #x9F419F0B #x9D3A9D80 #x11EA1164 #x25B925CD #xAFE4AFDD #x459A4508 #xDFA4DF8D #xA397A35C #xEA7EEAD5 #x35DA3558 #xED7AEDD0 #x431743FC #xF866F8CB #xFB94FBB1 #x37A137D3 #xFA1DFA40 #xC23DC268 #xB4F0B4CC #x32DE325D #x9CB39C71 #x560B56E7 #xE372E3DA #x87A78760 #x151C151B #xF9EFF93A #x63D163BF #x345334A9 #x9A3E9A85 #xB18FB142 #x7C337CD1 #x8826889B #x3D5F3DA6 #xA1ECA1D7 #xE476E4DF #x812A8194 #x91499101 #x0F810FFB #xEE88EEAA #x16EE1661 #xD721D773 #x97C497F5 #xA51AA5A8 #xFEEBFE3F #x6DD96DB5 #x78C578AE #xC539C56D #x1D991DE5 #x76CD76A4 #x3EAD3EDC #xCB31CB67 #xB68BB647 #xEF01EF5B #x1218121E #x602360C5 #x6ADD6AB0 #x4D1F4DF6 #xCE4ECEE9 #xDE2DDE7C #x55F9559D #x7E487E5A #x214F21B2 #x03F2037A #xA065A026 #x5E8E5E19 #x5A785A66 #x655C654B #x6258624E #xFD19FD45 #x068D06F4 #x40E54086 #xF298F2BE #x335733AC #x17671790 #x057F058E #xE805E85E #x4F644F7D #x89AF896A #x10631095 #x74B6742F #x0AFE0A75 #x5CF55C92 #x9BB79B74 #x2D3C2D33 #x30A530D6 #x2ECE2E49 #x49E94989 #x46684672 #x77447755 #xA8E0A8D8 #x964D9604 #x284328BD #xA969A929 #xD929D979 #x862E8691 #xD1ACD187 #xF415F44A #x8D598D15 #xD6A8D682 #xB90AB9BC #x429E420D #xF66EF6C1 #x2F472FB8 #xDDDFDD06 #x23342339 #xCC35CC62 #xF16AF1C4 #xC1CFC112 #x85DC85EB #x8F228F9E #x71C971A1 #x90C090F0 #xAA9BAA53 #x018901F1 #x8BD48BE1 #x4EED4E8C #x8EAB8E6F #xAB12ABA2 #x6FA26F3E #xE60DE654 #xDB52DBF2 #x92BB927B #xB702B7B6 #x692F69CA #x39A939D9 #xD3D7D30C #xA761A723 #xA21EA2AD #xC3B4C399 #x6C506C44 #x07040705 #x04F6047F #x27C22746 #xAC16ACA7 #xD025D076 #x50865013 #xDC56DCF7 #x8455841A #xE109E151 #x7ABE7A25 #x139113EF)) (defconst +twofish-MDS3+ #32@(#xD939A9D9 #x90176790 #x719CB371 #xD2A6E8D2 #x05070405 #x9852FD98 #x6580A365 #xDFE476DF #x08459A08 #x024B9202 #xA0E080A0 #x665A7866 #xDDAFE4DD #xB06ADDB0 #xBF63D1BF #x362A3836 #x54E60D54 #x4320C643 #x62CC3562 #xBEF298BE #x1E12181E #x24EBF724 #xD7A1ECD7 #x77416C77 #xBD2843BD #x32BC7532 #xD47B37D4 #x9B88269B #x700DFA70 #xF94413F9 #xB1FB94B1 #x5A7E485A #x7A03F27A #xE48CD0E4 #x47B68B47 #x3C24303C #xA5E784A5 #x416B5441 #x06DDDF06 #xC56023C5 #x45FD1945 #xA33A5BA3 #x68C23D68 #x158D5915 #x21ECF321 #x3166AE31 #x3E6FA23E #x16578216 #x95106395 #x5BEF015B #x4DB8834D #x91862E91 #xB56DD9B5 #x1F83511F #x53AA9B53 #x635D7C63 #x3B68A63B #x3FFEEB3F #xD630A5D6 #x257ABE25 #xA7AC16A7 #x0F090C0F #x35F0E335 #x23A76123 #xF090C0F0 #xAFE98CAF #x809D3A80 #x925CF592 #x810C7381 #x27312C27 #x76D02576 #xE7560BE7 #x7B92BB7B #xE9CE4EE9 #xF10189F1 #x9F1E6B9F #xA93453A9 #xC4F16AC4 #x99C3B499 #x975BF197 #x8347E183 #x6B18E66B #xC822BDC8 #x0E98450E #x6E1FE26E #xC9B3F4C9 #x2F74B62F #xCBF866CB #xFF99CCFF #xEA1495EA #xED5803ED #xF7DC56F7 #xE18BD4E1 #x1B151C1B #xADA21EAD #x0CD3D70C #x2BE2FB2B #x1DC8C31D #x195E8E19 #xC22CB5C2 #x8949E989 #x12C1CF12 #x7E95BF7E #x207DBA20 #x6411EA64 #x840B7784 #x6DC5396D #x6A89AF6A #xD17C33D1 #xA171C9A1 #xCEFF62CE #x37BB7137 #xFB0F81FB #x3DB5793D #x51E10951 #xDC3EADDC #x2D3F242D #xA476CDA4 #x9D55F99D #xEE82D8EE #x8640E586 #xAE78C5AE #xCD25B9CD #x04964D04 #x55774455 #x0A0E080A #x13508613 #x30F7E730 #xD337A1D3 #x40FA1D40 #x3461AA34 #x8C4EED8C #xB3B006B3 #x6C54706C #x2A73B22A #x523BD252 #x0B9F410B #x8B027B8B #x88D8A088 #x4FF3114F #x67CB3167 #x4627C246 #xC06727C0 #xB4FC90B4 #x28382028 #x7F04F67F #x78486078 #x2EE5FF2E #x074C9607 #x4B655C4B #xC72BB1C7 #x6F8EAB6F #x0D429E0D #xBBF59CBB #xF2DB52F2 #xF34A1BF3 #xA63D5FA6 #x59A49359 #xBCB90ABC #x3AF9EF3A #xEF1391EF #xFE0885FE #x01914901 #x6116EE61 #x7CDE2D7C #xB2214FB2 #x42B18F42 #xDB723BDB #xB82F47B8 #x48BF8748 #x2CAE6D2C #xE3C046E3 #x573CD657 #x859A3E85 #x29A96929 #x7D4F647D #x94812A94 #x492ECE49 #x17C6CB17 #xCA692FCA #xC3BDFCC3 #x5CA3975C #x5EE8055E #xD0ED7AD0 #x87D1AC87 #x8E057F8E #xBA64D5BA #xA8A51AA8 #xB7264BB7 #xB9BE0EB9 #x6087A760 #xF8D55AF8 #x22362822 #x111B1411 #xDE753FDE #x79D92979 #xAAEE88AA #x332D3C33 #x5F794C5F #xB6B702B6 #x96CAB896 #x5835DA58 #x9CC4B09C #xFC4317FC #x1A84551A #xF64D1FF6 #x1C598A1C #x38B27D38 #xAC3357AC #x18CFC718 #xF4068DF4 #x69537469 #x749BB774 #xF597C4F5 #x56AD9F56 #xDAE372DA #xD5EA7ED5 #x4AF4154A #x9E8F229E #xA2AB12A2 #x4E62584E #xE85F07E8 #xE51D99E5 #x39233439 #xC1F66EC1 #x446C5044 #x5D32DE5D #x72466872 #x26A06526 #x93CDBC93 #x03DADB03 #xC6BAF8C6 #xFA9EC8FA #x82D6A882 #xCF6E2BCF #x50704050 #xEB85DCEB #x750AFE75 #x8A93328A #x8DDFA48D #x4C29CA4C #x141C1014 #x73D72173 #xCCB4F0CC #x09D4D309 #x108A5D10 #xE2510FE2 #x00000000 #x9A196F9A #xE01A9DE0 #x8F94368F #xE6C742E6 #xECC94AEC #xFDD25EFD #xAB7FC1AB #xD8A8E0D8)) ;;; the actual implementation of Twofish (deftype twofish-s-boxes () '(simple-array (unsigned-byte 32) (1024))) (deftype twofish-round-keys () '(simple-array (unsigned-byte 32) (40))) (defclass twofish (cipher 16-byte-block-mixin) ((round-keys :accessor round-keys :type twofish-round-keys) (s-boxes :accessor s-boxes :type twofish-s-boxes))) (defun reed-solomon-multiply (box box-offset key rs0 rs1 rs2 rs3) (declare (type (simple-array (unsigned-byte 8) (16)) box)) (declare (type (integer 0 12) box-offset)) (unless (zerop key) (let ((temp (aref +twofish-poly-to-exp+ (1- key)))) ;; Lispworks doesn't seem to like doing this with a straight ;; MACROLET and no #., so we go ahead and build everything at ;; read-time. #.(flet ((mod-box-element (index) (let ((rs-sym (intern (format nil "RS~D" index)))) `(setf (aref box (+ box-offset ,index)) (logxor (aref box (+ box-offset ,index)) (aref +twofish-exp-to-poly+ (mod (+ temp (aref +twofish-poly-to-exp+ (1- ,rs-sym))) 255))))))) `(progn ,(mod-box-element 0) ,(mod-box-element 1) ,(mod-box-element 2) ,(mod-box-element 3))))) (values)) (defun twofish-key-schedule (key) (declare (type (simple-array (unsigned-byte 8) (*)) key)) (let ((rs-box (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)) (round-keys (make-array 40 :element-type '(unsigned-byte 32))) (s-boxes (make-array 1024 :element-type '(unsigned-byte 32)))) (declare (type (simple-array (unsigned-byte 8) (16)) rs-box)) (declare (dynamic-extent rs-box)) ;; fill the rs-box (dotimes (i (length key)) (reed-solomon-multiply rs-box (* 4 (truncate i 8)) (aref key i) (aref +twofish-rs+ (mod (* 4 i) 32)) (aref +twofish-rs+ (mod (+ (* 4 i) 1) 32)) (aref +twofish-rs+ (mod (+ (* 4 i) 2) 32)) (aref +twofish-rs+ (mod (+ (* 4 i) 3) 32)))) (case (length key) (16 (twofish-schedule-16-byte-key round-keys s-boxes key rs-box)) (24 (twofish-schedule-24-byte-key round-keys s-boxes key rs-box)) (32 (twofish-schedule-32-byte-key round-keys s-boxes key rs-box))))) (macrolet ((s-box (s-boxes which index) `(aref ,s-boxes (+ (* 256 ,which) ,index))) (s-box-0 (s-boxes index) `(s-box ,s-boxes 0 ,index)) (s-box-1 (s-boxes index) `(s-box ,s-boxes 1 ,index)) (s-box-2 (s-boxes index) `(s-box ,s-boxes 2 ,index)) (s-box-3 (s-boxes index) `(s-box ,s-boxes 3 ,index))) (defun twofish-schedule-16-byte-key (round-keys s-boxes key box) (declare (type twofish-round-keys round-keys) (type twofish-s-boxes s-boxes) (type (simple-array (unsigned-byte 8) (16)) key box)) (macrolet ((q-frob (i1 i2 d1 d2) (let ((q0 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 1) i1)))) (q1 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 0) i1))))) `(logxor (aref ,q0 (logxor (aref ,q1 ,i2) ,d1)) ,d2)))) (dotimes (i 256) (setf (s-box-0 s-boxes i) (aref +twofish-mds0+ (q-frob 0 i (aref box 0) (aref box 4))) (s-box-1 s-boxes i) (aref +twofish-mds1+ (q-frob 1 i (aref box 1) (aref box 5))) (s-box-2 s-boxes i) (aref +twofish-mds2+ (q-frob 2 i (aref box 2) (aref box 6))) (s-box-3 s-boxes i) (aref +twofish-mds3+ (q-frob 3 i (aref box 3) (aref box 7))))) (loop for i from 0 below 40 by 2 do (let ((x (logxor (aref +twofish-mds0+ (q-frob 0 i (aref key 8) (aref key 0))) (aref +twofish-mds1+ (q-frob 1 i (aref key 9) (aref key 1))) (aref +twofish-mds2+ (q-frob 2 i (aref key 10) (aref key 2))) (aref +twofish-mds3+ (q-frob 3 i (aref key 11) (aref key 3))))) (y (logxor (aref +twofish-mds0+ (q-frob 0 (1+ i) (aref key 12) (aref key 4))) (aref +twofish-mds1+ (q-frob 1 (1+ i) (aref key 13) (aref key 5))) (aref +twofish-mds2+ (q-frob 2 (1+ i) (aref key 14) (aref key 6))) (aref +twofish-mds3+ (q-frob 3 (1+ i) (aref key 15) (aref key 7)))))) (declare (type (unsigned-byte 32) x y)) (setf y (rol32 y 8)) (setf x (mod32+ x y)) (setf y (mod32+ y x)) (setf (aref round-keys i) x (aref round-keys (1+ i)) (rol32 y 9))) finally (return (values round-keys s-boxes))))) (defun twofish-schedule-24-byte-key (round-keys s-boxes key box) (declare (type twofish-round-keys round-keys) (type twofish-s-boxes s-boxes) (type (simple-array (unsigned-byte 8) (24)) key) (type (simple-array (unsigned-byte 8) (16)) box)) (macrolet ((q-frob (i1 i2 d1 d2 d3) (let ((q0 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 2) i1)))) (q1 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 1) i1)))) (q2 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 0) i1))))) `(logxor (aref ,q0 (logxor (aref ,q1 (logxor (aref ,q2 ,i2) ,d1)) ,d2)) ,d3)))) (dotimes (i 256) (setf (s-box-0 s-boxes i) (aref +twofish-mds0+ (q-frob 1 i (aref box 0) (aref box 4) (aref box 8))) (s-box-1 s-boxes i) (aref +twofish-mds1+ (q-frob 3 i (aref box 1) (aref box 5) (aref box 9))) (s-box-2 s-boxes i) (aref +twofish-mds2+ (q-frob 4 i (aref box 2) (aref box 6) (aref box 10))) (s-box-3 s-boxes i) (aref +twofish-mds3+ (q-frob 6 i (aref box 3) (aref box 7) (aref box 11))))) (loop for i from 0 below 40 by 2 do (let ((x (logxor (aref +twofish-mds0+ (q-frob 1 i (aref key 16) (aref key 8) (aref key 0))) (aref +twofish-mds1+ (q-frob 3 i (aref key 17) (aref key 9) (aref key 1))) (aref +twofish-mds2+ (q-frob 4 i (aref key 18) (aref key 10) (aref key 2))) (aref +twofish-mds3+ (q-frob 6 i (aref key 19) (aref key 11) (aref key 3))))) (y (logxor (aref +twofish-mds0+ (q-frob 1 (1+ i) (aref key 20) (aref key 12) (aref key 4))) (aref +twofish-mds1+ (q-frob 3 (1+ i) (aref key 21) (aref key 13) (aref key 5))) (aref +twofish-mds2+ (q-frob 4 (1+ i) (aref key 22) (aref key 14) (aref key 6))) (aref +twofish-mds3+ (q-frob 6 (1+ i) (aref key 23) (aref key 15) (aref key 7)))))) (declare (type (unsigned-byte 32) x y)) (setf y (rol32 y 8)) (setf x (mod32+ x y)) (setf y (mod32+ y x)) (setf (aref round-keys i) x (aref round-keys (1+ i)) (rol32 y 9))) finally (return (values round-keys s-boxes))))) (defun twofish-schedule-32-byte-key (round-keys s-boxes key box) (declare (type twofish-round-keys round-keys) (type twofish-s-boxes s-boxes) (type (simple-array (unsigned-byte 8) (32)) key) (type (simple-array (unsigned-byte 8) (16)) box)) (macrolet ((q-frob (i1 i2 d1 d2 d3 d4) (let ((q0 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 3) i1)))) (q1 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 2) i1)))) (q2 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 1) i1)))) (q3 (intern (format nil "+TWOFISH-Q~A+" (ldb (byte 1 0) i1))))) `(logxor (aref ,q0 (logxor (aref ,q1 (logxor (aref ,q2 (logxor (aref ,q3 ,i2) ,d1)) ,d2)) ,d3)) ,d4)))) (dotimes (i 256) (setf (s-box-0 s-boxes i) (aref +twofish-mds0+ (q-frob #b0011 i (aref box 0) (aref box 4) (aref box 8) (aref box 12))) (s-box-1 s-boxes i) (aref +twofish-mds1+ (q-frob #b0110 i (aref box 1) (aref box 5) (aref box 9) (aref box 13))) (s-box-2 s-boxes i) (aref +twofish-mds2+ (q-frob #b1000 i (aref box 2) (aref box 6) (aref box 10) (aref box 14))) (s-box-3 s-boxes i) (aref +twofish-mds3+ (q-frob #b1101 i (aref box 3) (aref box 7) (aref box 11) (aref box 15))))) (loop for i from 0 below 40 by 2 do (let ((x (logxor (aref +twofish-mds0+ (q-frob #b0011 i (aref key 24) (aref key 16) (aref key 8) (aref key 0))) (aref +twofish-mds1+ (q-frob #b0110 i (aref key 25) (aref key 17) (aref key 9) (aref key 1))) (aref +twofish-mds2+ (q-frob #b1000 i (aref key 26) (aref key 18) (aref key 10) (aref key 2))) (aref +twofish-mds3+ (q-frob #b1101 i (aref key 27) (aref key 19) (aref key 11) (aref key 3))))) (y (logxor (aref +twofish-mds0+ (q-frob #b0011 (1+ i) (aref key 28) (aref key 20) (aref key 12) (aref key 4))) (aref +twofish-mds1+ (q-frob #b0110 (1+ i) (aref key 29) (aref key 21) (aref key 13) (aref key 5))) (aref +twofish-mds2+ (q-frob #b1000 (1+ i) (aref key 30) (aref key 22) (aref key 14) (aref key 6))) (aref +twofish-mds3+ (q-frob #b1101 (1+ i) (aref key 31) (aref key 23) (aref key 15) (aref key 7)))))) (declare (type (unsigned-byte 32) x y)) (setf y (rol32 y 8)) (setf x (mod32+ x y)) (setf y (mod32+ y x)) (setf (aref round-keys i) x (aref round-keys (1+ i)) (rol32 y 9))) finally (return (values round-keys s-boxes))))) (define-block-encryptor twofish 16 (let ((round-keys (round-keys context)) (s-boxes (s-boxes context))) (declare (type twofish-round-keys round-keys)) (declare (type twofish-s-boxes s-boxes)) (macrolet ((encrypt-round (a b c d round) `(let ((x (logxor (s-box-0 s-boxes (first-byte ,a)) (s-box-1 s-boxes (second-byte ,a)) (s-box-2 s-boxes (third-byte ,a)) (s-box-3 s-boxes (fourth-byte ,a)))) (y (logxor (s-box-0 s-boxes (fourth-byte ,b)) (s-box-1 s-boxes (first-byte ,b)) (s-box-2 s-boxes (second-byte ,b)) (s-box-3 s-boxes (third-byte ,b))))) (declare (type (unsigned-byte 32) x y)) (setf x (mod32+ x y)) (setf y (mod32+ y (mod32+ x (aref round-keys (+ (* ,round 2) 9))))) (setf x (mod32+ x (aref round-keys (+ (* ,round 2) 8)))) (setf ,c (rol32 (logxor ,c x) 31) ,d (logxor (rol32 ,d 1) y))))) (with-words ((a b c d) plaintext plaintext-start :big-endian nil) (setf a (logxor a (aref round-keys 0)) b (logxor b (aref round-keys 1)) c (logxor c (aref round-keys 2)) d (logxor d (aref round-keys 3))) #.(loop for i from 0 below 16 if (evenp i) collect `(encrypt-round a b c d ,i) into rounds else collect `(encrypt-round c d a b ,i) into rounds finally (return `(progn ,@rounds))) (setf c (logxor c (aref round-keys 4)) d (logxor d (aref round-keys 5)) a (logxor a (aref round-keys 6)) b (logxor b (aref round-keys 7))) (store-words ciphertext ciphertext-start c d a b) (values))))) (define-block-decryptor twofish 16 (let ((round-keys (round-keys context)) (s-boxes (s-boxes context))) (declare (type twofish-round-keys round-keys)) (declare (type twofish-s-boxes s-boxes)) (macrolet ((decrypt-round (a b c d round) `(let ((x (logxor (s-box-0 s-boxes (first-byte ,a)) (s-box-1 s-boxes (second-byte ,a)) (s-box-2 s-boxes (third-byte ,a)) (s-box-3 s-boxes (fourth-byte ,a)))) (y (logxor (s-box-0 s-boxes (fourth-byte ,b)) (s-box-1 s-boxes (first-byte ,b)) (s-box-2 s-boxes (second-byte ,b)) (s-box-3 s-boxes (third-byte ,b))))) (declare (type (unsigned-byte 32) x y)) (setf x (mod32+ x y)) (setf y (mod32+ y (mod32+ x (aref round-keys (+ (* ,round 2) 9))))) (setf x (mod32+ x (aref round-keys (+ (* ,round 2) 8)))) (setf ,c (logxor (rol32 ,c 1) x) ,d (rol32 (logxor ,d y) 31))))) (with-words ((c d a b) ciphertext ciphertext-start :big-endian nil) (setf c (logxor c (aref round-keys 4)) d (logxor d (aref round-keys 5)) a (logxor a (aref round-keys 6)) b (logxor b (aref round-keys 7))) #.(loop for i from 15 downto 0 if (evenp i) collect `(decrypt-round a b c d ,i) into rounds else collect `(decrypt-round c d a b ,i) into rounds finally (return `(progn ,@rounds))) (setf a (logxor a (aref round-keys 0)) b (logxor b (aref round-keys 1)) c (logxor c (aref round-keys 2)) d (logxor d (aref round-keys 3))) (store-words plaintext plaintext-start a b c d) (values))))) ) ; MACROLET (defmethod schedule-key ((cipher twofish) key) (multiple-value-bind (round-keys s-boxes) (twofish-key-schedule key) (setf (round-keys cipher) round-keys (s-boxes cipher) s-boxes) cipher)) (defcipher twofish (:encrypt-function twofish-encrypt-block) (:decrypt-function twofish-decrypt-block) (:block-length 16) (:key-length (:fixed 16 24 32)))