blobsets/src/blobsets/priv/nimcrypto/rijndael.nim

1041 lines
56 KiB
Nim

#
#
# NimCrypto
# (c) Copyright 2016 Eugene Kabanov
#
# See the file "LICENSE", included in this
# distribution, for details about the copyright.
#
## This module implements Rijndael(AES) crypto algorithm by Vincent Rijmen,
## Antoon Bosselaers and Paulo Barreto.
##
## Code based on version 3.0 (December 2000) of
## `Optimised ANSI C code for the Rijndael cipher`
## [http://www.fastcrypto.org/front/misc/rijndael-alg-fst.c].
##
## Tests made according to official test vectors (Appendix B and Appendix C)
## [http://csrc.nist.gov/groups/STM/cavp/documents/aes/AESAVS.pdf].
import utils
{.deadCodeElim:on.}
const
MaxNr = 14
Te0 = [
0xC66363A5'u32, 0xF87C7C84'u32, 0xEE777799'u32, 0xF67B7B8D'u32,
0xFFF2F20D'u32, 0xD66B6BBD'u32, 0xDE6F6FB1'u32, 0x91C5C554'u32,
0x60303050'u32, 0x02010103'u32, 0xCE6767A9'u32, 0x562B2B7D'u32,
0xE7FEFE19'u32, 0xB5D7D762'u32, 0x4DABABE6'u32, 0xEC76769A'u32,
0x8FCACA45'u32, 0x1F82829D'u32, 0x89C9C940'u32, 0xFA7D7D87'u32,
0xEFFAFA15'u32, 0xB25959EB'u32, 0x8E4747C9'u32, 0xFBF0F00B'u32,
0x41ADADEC'u32, 0xB3D4D467'u32, 0x5FA2A2FD'u32, 0x45AFAFEA'u32,
0x239C9CBF'u32, 0x53A4A4F7'u32, 0xE4727296'u32, 0x9BC0C05B'u32,
0x75B7B7C2'u32, 0xE1FDFD1C'u32, 0x3D9393AE'u32, 0x4C26266A'u32,
0x6C36365A'u32, 0x7E3F3F41'u32, 0xF5F7F702'u32, 0x83CCCC4F'u32,
0x6834345C'u32, 0x51A5A5F4'u32, 0xD1E5E534'u32, 0xF9F1F108'u32,
0xE2717193'u32, 0xABD8D873'u32, 0x62313153'u32, 0x2A15153F'u32,
0x0804040C'u32, 0x95C7C752'u32, 0x46232365'u32, 0x9DC3C35E'u32,
0x30181828'u32, 0x379696A1'u32, 0x0A05050F'u32, 0x2F9A9AB5'u32,
0x0E070709'u32, 0x24121236'u32, 0x1B80809B'u32, 0xDFE2E23D'u32,
0xCDEBEB26'u32, 0x4E272769'u32, 0x7FB2B2CD'u32, 0xEA75759F'u32,
0x1209091B'u32, 0x1D83839E'u32, 0x582C2C74'u32, 0x341A1A2E'u32,
0x361B1B2D'u32, 0xDC6E6EB2'u32, 0xB45A5AEE'u32, 0x5BA0A0FB'u32,
0xA45252F6'u32, 0x763B3B4D'u32, 0xB7D6D661'u32, 0x7DB3B3CE'u32,
0x5229297B'u32, 0xDDE3E33E'u32, 0x5E2F2F71'u32, 0x13848497'u32,
0xA65353F5'u32, 0xB9D1D168'u32, 0x00000000'u32, 0xC1EDED2C'u32,
0x40202060'u32, 0xE3FCFC1F'u32, 0x79B1B1C8'u32, 0xB65B5BED'u32,
0xD46A6ABE'u32, 0x8DCBCB46'u32, 0x67BEBED9'u32, 0x7239394B'u32,
0x944A4ADE'u32, 0x984C4CD4'u32, 0xB05858E8'u32, 0x85CFCF4A'u32,
0xBBD0D06B'u32, 0xC5EFEF2A'u32, 0x4FAAAAE5'u32, 0xEDFBFB16'u32,
0x864343C5'u32, 0x9A4D4DD7'u32, 0x66333355'u32, 0x11858594'u32,
0x8A4545CF'u32, 0xE9F9F910'u32, 0x04020206'u32, 0xFE7F7F81'u32,
0xA05050F0'u32, 0x783C3C44'u32, 0x259F9FBA'u32, 0x4BA8A8E3'u32,
0xA25151F3'u32, 0x5DA3A3FE'u32, 0x804040C0'u32, 0x058F8F8A'u32,
0x3F9292AD'u32, 0x219D9DBC'u32, 0x70383848'u32, 0xF1F5F504'u32,
0x63BCBCDF'u32, 0x77B6B6C1'u32, 0xAFDADA75'u32, 0x42212163'u32,
0x20101030'u32, 0xE5FFFF1A'u32, 0xFDF3F30E'u32, 0xBFD2D26D'u32,
0x81CDCD4C'u32, 0x180C0C14'u32, 0x26131335'u32, 0xC3ECEC2F'u32,
0xBE5F5FE1'u32, 0x359797A2'u32, 0x884444CC'u32, 0x2E171739'u32,
0x93C4C457'u32, 0x55A7A7F2'u32, 0xFC7E7E82'u32, 0x7A3D3D47'u32,
0xC86464AC'u32, 0xBA5D5DE7'u32, 0x3219192B'u32, 0xE6737395'u32,
0xC06060A0'u32, 0x19818198'u32, 0x9E4F4FD1'u32, 0xA3DCDC7F'u32,
0x44222266'u32, 0x542A2A7E'u32, 0x3B9090AB'u32, 0x0B888883'u32,
0x8C4646CA'u32, 0xC7EEEE29'u32, 0x6BB8B8D3'u32, 0x2814143C'u32,
0xA7DEDE79'u32, 0xBC5E5EE2'u32, 0x160B0B1D'u32, 0xADDBDB76'u32,
0xDBE0E03B'u32, 0x64323256'u32, 0x743A3A4E'u32, 0x140A0A1E'u32,
0x924949DB'u32, 0x0C06060A'u32, 0x4824246C'u32, 0xB85C5CE4'u32,
0x9FC2C25D'u32, 0xBDD3D36E'u32, 0x43ACACEF'u32, 0xC46262A6'u32,
0x399191A8'u32, 0x319595A4'u32, 0xD3E4E437'u32, 0xF279798B'u32,
0xD5E7E732'u32, 0x8BC8C843'u32, 0x6E373759'u32, 0xDA6D6DB7'u32,
0x018D8D8C'u32, 0xB1D5D564'u32, 0x9C4E4ED2'u32, 0x49A9A9E0'u32,
0xD86C6CB4'u32, 0xAC5656FA'u32, 0xF3F4F407'u32, 0xCFEAEA25'u32,
0xCA6565AF'u32, 0xF47A7A8E'u32, 0x47AEAEE9'u32, 0x10080818'u32,
0x6FBABAD5'u32, 0xF0787888'u32, 0x4A25256F'u32, 0x5C2E2E72'u32,
0x381C1C24'u32, 0x57A6A6F1'u32, 0x73B4B4C7'u32, 0x97C6C651'u32,
0xCBE8E823'u32, 0xA1DDDD7C'u32, 0xE874749C'u32, 0x3E1F1F21'u32,
0x964B4BDD'u32, 0x61BDBDDC'u32, 0x0D8B8B86'u32, 0x0F8A8A85'u32,
0xE0707090'u32, 0x7C3E3E42'u32, 0x71B5B5C4'u32, 0xCC6666AA'u32,
0x904848D8'u32, 0x06030305'u32, 0xF7F6F601'u32, 0x1C0E0E12'u32,
0xC26161A3'u32, 0x6A35355F'u32, 0xAE5757F9'u32, 0x69B9B9D0'u32,
0x17868691'u32, 0x99C1C158'u32, 0x3A1D1D27'u32, 0x279E9EB9'u32,
0xD9E1E138'u32, 0xEBF8F813'u32, 0x2B9898B3'u32, 0x22111133'u32,
0xD26969BB'u32, 0xA9D9D970'u32, 0x078E8E89'u32, 0x339494A7'u32,
0x2D9B9BB6'u32, 0x3C1E1E22'u32, 0x15878792'u32, 0xC9E9E920'u32,
0x87CECE49'u32, 0xAA5555FF'u32, 0x50282878'u32, 0xA5DFDF7A'u32,
0x038C8C8F'u32, 0x59A1A1F8'u32, 0x09898980'u32, 0x1A0D0D17'u32,
0x65BFBFDA'u32, 0xD7E6E631'u32, 0x844242C6'u32, 0xD06868B8'u32,
0x824141C3'u32, 0x299999B0'u32, 0x5A2D2D77'u32, 0x1E0F0F11'u32,
0x7BB0B0CB'u32, 0xA85454FC'u32, 0x6DBBBBD6'u32, 0x2C16163A'u32
]
Te1 = [
0xA5C66363'u32, 0x84F87C7C'u32, 0x99EE7777'u32, 0x8DF67B7B'u32,
0x0DFFF2F2'u32, 0xBDD66B6B'u32, 0xB1DE6F6F'u32, 0x5491C5C5'u32,
0x50603030'u32, 0x03020101'u32, 0xA9CE6767'u32, 0x7D562B2B'u32,
0x19E7FEFE'u32, 0x62B5D7D7'u32, 0xE64DABAB'u32, 0x9AEC7676'u32,
0x458FCACA'u32, 0x9D1F8282'u32, 0x4089C9C9'u32, 0x87FA7D7D'u32,
0x15EFFAFA'u32, 0xEBB25959'u32, 0xC98E4747'u32, 0x0BFBF0F0'u32,
0xEC41ADAD'u32, 0x67B3D4D4'u32, 0xFD5FA2A2'u32, 0xEA45AFAF'u32,
0xBF239C9C'u32, 0xF753A4A4'u32, 0x96E47272'u32, 0x5B9BC0C0'u32,
0xC275B7B7'u32, 0x1CE1FDFD'u32, 0xAE3D9393'u32, 0x6A4C2626'u32,
0x5A6C3636'u32, 0x417E3F3F'u32, 0x02F5F7F7'u32, 0x4F83CCCC'u32,
0x5C683434'u32, 0xF451A5A5'u32, 0x34D1E5E5'u32, 0x08F9F1F1'u32,
0x93E27171'u32, 0x73ABD8D8'u32, 0x53623131'u32, 0x3F2A1515'u32,
0x0C080404'u32, 0x5295C7C7'u32, 0x65462323'u32, 0x5E9DC3C3'u32,
0x28301818'u32, 0xA1379696'u32, 0x0F0A0505'u32, 0xB52F9A9A'u32,
0x090E0707'u32, 0x36241212'u32, 0x9B1B8080'u32, 0x3DDFE2E2'u32,
0x26CDEBEB'u32, 0x694E2727'u32, 0xCD7FB2B2'u32, 0x9FEA7575'u32,
0x1B120909'u32, 0x9E1D8383'u32, 0x74582C2C'u32, 0x2E341A1A'u32,
0x2D361B1B'u32, 0xB2DC6E6E'u32, 0xEEB45A5A'u32, 0xFB5BA0A0'u32,
0xF6A45252'u32, 0x4D763B3B'u32, 0x61B7D6D6'u32, 0xCE7DB3B3'u32,
0x7B522929'u32, 0x3EDDE3E3'u32, 0x715E2F2F'u32, 0x97138484'u32,
0xF5A65353'u32, 0x68B9D1D1'u32, 0x00000000'u32, 0x2CC1EDED'u32,
0x60402020'u32, 0x1FE3FCFC'u32, 0xC879B1B1'u32, 0xEDB65B5B'u32,
0xBED46A6A'u32, 0x468DCBCB'u32, 0xD967BEBE'u32, 0x4B723939'u32,
0xDE944A4A'u32, 0xD4984C4C'u32, 0xE8B05858'u32, 0x4A85CFCF'u32,
0x6BBBD0D0'u32, 0x2AC5EFEF'u32, 0xE54FAAAA'u32, 0x16EDFBFB'u32,
0xC5864343'u32, 0xD79A4D4D'u32, 0x55663333'u32, 0x94118585'u32,
0xCF8A4545'u32, 0x10E9F9F9'u32, 0x06040202'u32, 0x81FE7F7F'u32,
0xF0A05050'u32, 0x44783C3C'u32, 0xBA259F9F'u32, 0xE34BA8A8'u32,
0xF3A25151'u32, 0xFE5DA3A3'u32, 0xC0804040'u32, 0x8A058F8F'u32,
0xAD3F9292'u32, 0xBC219D9D'u32, 0x48703838'u32, 0x04F1F5F5'u32,
0xDF63BCBC'u32, 0xC177B6B6'u32, 0x75AFDADA'u32, 0x63422121'u32,
0x30201010'u32, 0x1AE5FFFF'u32, 0x0EFDF3F3'u32, 0x6DBFD2D2'u32,
0x4C81CDCD'u32, 0x14180C0C'u32, 0x35261313'u32, 0x2FC3ECEC'u32,
0xE1BE5F5F'u32, 0xA2359797'u32, 0xCC884444'u32, 0x392E1717'u32,
0x5793C4C4'u32, 0xF255A7A7'u32, 0x82FC7E7E'u32, 0x477A3D3D'u32,
0xACC86464'u32, 0xE7BA5D5D'u32, 0x2B321919'u32, 0x95E67373'u32,
0xA0C06060'u32, 0x98198181'u32, 0xD19E4F4F'u32, 0x7FA3DCDC'u32,
0x66442222'u32, 0x7E542A2A'u32, 0xAB3B9090'u32, 0x830B8888'u32,
0xCA8C4646'u32, 0x29C7EEEE'u32, 0xD36BB8B8'u32, 0x3C281414'u32,
0x79A7DEDE'u32, 0xE2BC5E5E'u32, 0x1D160B0B'u32, 0x76ADDBDB'u32,
0x3BDBE0E0'u32, 0x56643232'u32, 0x4E743A3A'u32, 0x1E140A0A'u32,
0xDB924949'u32, 0x0A0C0606'u32, 0x6C482424'u32, 0xE4B85C5C'u32,
0x5D9FC2C2'u32, 0x6EBDD3D3'u32, 0xEF43ACAC'u32, 0xA6C46262'u32,
0xA8399191'u32, 0xA4319595'u32, 0x37D3E4E4'u32, 0x8BF27979'u32,
0x32D5E7E7'u32, 0x438BC8C8'u32, 0x596E3737'u32, 0xB7DA6D6D'u32,
0x8C018D8D'u32, 0x64B1D5D5'u32, 0xD29C4E4E'u32, 0xE049A9A9'u32,
0xB4D86C6C'u32, 0xFAAC5656'u32, 0x07F3F4F4'u32, 0x25CFEAEA'u32,
0xAFCA6565'u32, 0x8EF47A7A'u32, 0xE947AEAE'u32, 0x18100808'u32,
0xD56FBABA'u32, 0x88F07878'u32, 0x6F4A2525'u32, 0x725C2E2E'u32,
0x24381C1C'u32, 0xF157A6A6'u32, 0xC773B4B4'u32, 0x5197C6C6'u32,
0x23CBE8E8'u32, 0x7CA1DDDD'u32, 0x9CE87474'u32, 0x213E1F1F'u32,
0xDD964B4B'u32, 0xDC61BDBD'u32, 0x860D8B8B'u32, 0x850F8A8A'u32,
0x90E07070'u32, 0x427C3E3E'u32, 0xC471B5B5'u32, 0xAACC6666'u32,
0xD8904848'u32, 0x05060303'u32, 0x01F7F6F6'u32, 0x121C0E0E'u32,
0xA3C26161'u32, 0x5F6A3535'u32, 0xF9AE5757'u32, 0xD069B9B9'u32,
0x91178686'u32, 0x5899C1C1'u32, 0x273A1D1D'u32, 0xB9279E9E'u32,
0x38D9E1E1'u32, 0x13EBF8F8'u32, 0xB32B9898'u32, 0x33221111'u32,
0xBBD26969'u32, 0x70A9D9D9'u32, 0x89078E8E'u32, 0xA7339494'u32,
0xB62D9B9B'u32, 0x223C1E1E'u32, 0x92158787'u32, 0x20C9E9E9'u32,
0x4987CECE'u32, 0xFFAA5555'u32, 0x78502828'u32, 0x7AA5DFDF'u32,
0x8F038C8C'u32, 0xF859A1A1'u32, 0x80098989'u32, 0x171A0D0D'u32,
0xDA65BFBF'u32, 0x31D7E6E6'u32, 0xC6844242'u32, 0xB8D06868'u32,
0xC3824141'u32, 0xB0299999'u32, 0x775A2D2D'u32, 0x111E0F0F'u32,
0xCB7BB0B0'u32, 0xFCA85454'u32, 0xD66DBBBB'u32, 0x3A2C1616'u32
]
Te2 = [
0x63A5C663'u32, 0x7C84F87C'u32, 0x7799EE77'u32, 0x7B8DF67B'u32,
0xF20DFFF2'u32, 0x6BBDD66B'u32, 0x6FB1DE6F'u32, 0xC55491C5'u32,
0x30506030'u32, 0x01030201'u32, 0x67A9CE67'u32, 0x2B7D562B'u32,
0xFE19E7FE'u32, 0xD762B5D7'u32, 0xABE64DAB'u32, 0x769AEC76'u32,
0xCA458FCA'u32, 0x829D1F82'u32, 0xC94089C9'u32, 0x7D87FA7D'u32,
0xFA15EFFA'u32, 0x59EBB259'u32, 0x47C98E47'u32, 0xF00BFBF0'u32,
0xADEC41AD'u32, 0xD467B3D4'u32, 0xA2FD5FA2'u32, 0xAFEA45AF'u32,
0x9CBF239C'u32, 0xA4F753A4'u32, 0x7296E472'u32, 0xC05B9BC0'u32,
0xB7C275B7'u32, 0xFD1CE1FD'u32, 0x93AE3D93'u32, 0x266A4C26'u32,
0x365A6C36'u32, 0x3F417E3F'u32, 0xF702F5F7'u32, 0xCC4F83CC'u32,
0x345C6834'u32, 0xA5F451A5'u32, 0xE534D1E5'u32, 0xF108F9F1'u32,
0x7193E271'u32, 0xD873ABD8'u32, 0x31536231'u32, 0x153F2A15'u32,
0x040C0804'u32, 0xC75295C7'u32, 0x23654623'u32, 0xC35E9DC3'u32,
0x18283018'u32, 0x96A13796'u32, 0x050F0A05'u32, 0x9AB52F9A'u32,
0x07090E07'u32, 0x12362412'u32, 0x809B1B80'u32, 0xE23DDFE2'u32,
0xEB26CDEB'u32, 0x27694E27'u32, 0xB2CD7FB2'u32, 0x759FEA75'u32,
0x091B1209'u32, 0x839E1D83'u32, 0x2C74582C'u32, 0x1A2E341A'u32,
0x1B2D361B'u32, 0x6EB2DC6E'u32, 0x5AEEB45A'u32, 0xA0FB5BA0'u32,
0x52F6A452'u32, 0x3B4D763B'u32, 0xD661B7D6'u32, 0xB3CE7DB3'u32,
0x297B5229'u32, 0xE33EDDE3'u32, 0x2F715E2F'u32, 0x84971384'u32,
0x53F5A653'u32, 0xD168B9D1'u32, 0x00000000'u32, 0xED2CC1ED'u32,
0x20604020'u32, 0xFC1FE3FC'u32, 0xB1C879B1'u32, 0x5BEDB65B'u32,
0x6ABED46A'u32, 0xCB468DCB'u32, 0xBED967BE'u32, 0x394B7239'u32,
0x4ADE944A'u32, 0x4CD4984C'u32, 0x58E8B058'u32, 0xCF4A85CF'u32,
0xD06BBBD0'u32, 0xEF2AC5EF'u32, 0xAAE54FAA'u32, 0xFB16EDFB'u32,
0x43C58643'u32, 0x4DD79A4D'u32, 0x33556633'u32, 0x85941185'u32,
0x45CF8A45'u32, 0xF910E9F9'u32, 0x02060402'u32, 0x7F81FE7F'u32,
0x50F0A050'u32, 0x3C44783C'u32, 0x9FBA259F'u32, 0xA8E34BA8'u32,
0x51F3A251'u32, 0xA3FE5DA3'u32, 0x40C08040'u32, 0x8F8A058F'u32,
0x92AD3F92'u32, 0x9DBC219D'u32, 0x38487038'u32, 0xF504F1F5'u32,
0xBCDF63BC'u32, 0xB6C177B6'u32, 0xDA75AFDA'u32, 0x21634221'u32,
0x10302010'u32, 0xFF1AE5FF'u32, 0xF30EFDF3'u32, 0xD26DBFD2'u32,
0xCD4C81CD'u32, 0x0C14180C'u32, 0x13352613'u32, 0xEC2FC3EC'u32,
0x5FE1BE5F'u32, 0x97A23597'u32, 0x44CC8844'u32, 0x17392E17'u32,
0xC45793C4'u32, 0xA7F255A7'u32, 0x7E82FC7E'u32, 0x3D477A3D'u32,
0x64ACC864'u32, 0x5DE7BA5D'u32, 0x192B3219'u32, 0x7395E673'u32,
0x60A0C060'u32, 0x81981981'u32, 0x4FD19E4F'u32, 0xDC7FA3DC'u32,
0x22664422'u32, 0x2A7E542A'u32, 0x90AB3B90'u32, 0x88830B88'u32,
0x46CA8C46'u32, 0xEE29C7EE'u32, 0xB8D36BB8'u32, 0x143C2814'u32,
0xDE79A7DE'u32, 0x5EE2BC5E'u32, 0x0B1D160B'u32, 0xDB76ADDB'u32,
0xE03BDBE0'u32, 0x32566432'u32, 0x3A4E743A'u32, 0x0A1E140A'u32,
0x49DB9249'u32, 0x060A0C06'u32, 0x246C4824'u32, 0x5CE4B85C'u32,
0xC25D9FC2'u32, 0xD36EBDD3'u32, 0xACEF43AC'u32, 0x62A6C462'u32,
0x91A83991'u32, 0x95A43195'u32, 0xE437D3E4'u32, 0x798BF279'u32,
0xE732D5E7'u32, 0xC8438BC8'u32, 0x37596E37'u32, 0x6DB7DA6D'u32,
0x8D8C018D'u32, 0xD564B1D5'u32, 0x4ED29C4E'u32, 0xA9E049A9'u32,
0x6CB4D86C'u32, 0x56FAAC56'u32, 0xF407F3F4'u32, 0xEA25CFEA'u32,
0x65AFCA65'u32, 0x7A8EF47A'u32, 0xAEE947AE'u32, 0x08181008'u32,
0xBAD56FBA'u32, 0x7888F078'u32, 0x256F4A25'u32, 0x2E725C2E'u32,
0x1C24381C'u32, 0xA6F157A6'u32, 0xB4C773B4'u32, 0xC65197C6'u32,
0xE823CBE8'u32, 0xDD7CA1DD'u32, 0x749CE874'u32, 0x1F213E1F'u32,
0x4BDD964B'u32, 0xBDDC61BD'u32, 0x8B860D8B'u32, 0x8A850F8A'u32,
0x7090E070'u32, 0x3E427C3E'u32, 0xB5C471B5'u32, 0x66AACC66'u32,
0x48D89048'u32, 0x03050603'u32, 0xF601F7F6'u32, 0x0E121C0E'u32,
0x61A3C261'u32, 0x355F6A35'u32, 0x57F9AE57'u32, 0xB9D069B9'u32,
0x86911786'u32, 0xC15899C1'u32, 0x1D273A1D'u32, 0x9EB9279E'u32,
0xE138D9E1'u32, 0xF813EBF8'u32, 0x98B32B98'u32, 0x11332211'u32,
0x69BBD269'u32, 0xD970A9D9'u32, 0x8E89078E'u32, 0x94A73394'u32,
0x9BB62D9B'u32, 0x1E223C1E'u32, 0x87921587'u32, 0xE920C9E9'u32,
0xCE4987CE'u32, 0x55FFAA55'u32, 0x28785028'u32, 0xDF7AA5DF'u32,
0x8C8F038C'u32, 0xA1F859A1'u32, 0x89800989'u32, 0x0D171A0D'u32,
0xBFDA65BF'u32, 0xE631D7E6'u32, 0x42C68442'u32, 0x68B8D068'u32,
0x41C38241'u32, 0x99B02999'u32, 0x2D775A2D'u32, 0x0F111E0F'u32,
0xB0CB7BB0'u32, 0x54FCA854'u32, 0xBBD66DBB'u32, 0x163A2C16'u32
]
Te3 = [
0x6363A5C6'u32, 0x7C7C84F8'u32, 0x777799EE'u32, 0x7B7B8DF6'u32,
0xF2F20DFF'u32, 0x6B6BBDD6'u32, 0x6F6FB1DE'u32, 0xC5C55491'u32,
0x30305060'u32, 0x01010302'u32, 0x6767A9CE'u32, 0x2B2B7D56'u32,
0xFEFE19E7'u32, 0xD7D762B5'u32, 0xABABE64D'u32, 0x76769AEC'u32,
0xCACA458F'u32, 0x82829D1F'u32, 0xC9C94089'u32, 0x7D7D87FA'u32,
0xFAFA15EF'u32, 0x5959EBB2'u32, 0x4747C98E'u32, 0xF0F00BFB'u32,
0xADADEC41'u32, 0xD4D467B3'u32, 0xA2A2FD5F'u32, 0xAFAFEA45'u32,
0x9C9CBF23'u32, 0xA4A4F753'u32, 0x727296E4'u32, 0xC0C05B9B'u32,
0xB7B7C275'u32, 0xFDFD1CE1'u32, 0x9393AE3D'u32, 0x26266A4C'u32,
0x36365A6C'u32, 0x3F3F417E'u32, 0xF7F702F5'u32, 0xCCCC4F83'u32,
0x34345C68'u32, 0xA5A5F451'u32, 0xE5E534D1'u32, 0xF1F108F9'u32,
0x717193E2'u32, 0xD8D873AB'u32, 0x31315362'u32, 0x15153F2A'u32,
0x04040C08'u32, 0xC7C75295'u32, 0x23236546'u32, 0xC3C35E9D'u32,
0x18182830'u32, 0x9696A137'u32, 0x05050F0A'u32, 0x9A9AB52F'u32,
0x0707090E'u32, 0x12123624'u32, 0x80809B1B'u32, 0xE2E23DDF'u32,
0xEBEB26CD'u32, 0x2727694E'u32, 0xB2B2CD7F'u32, 0x75759FEA'u32,
0x09091B12'u32, 0x83839E1D'u32, 0x2C2C7458'u32, 0x1A1A2E34'u32,
0x1B1B2D36'u32, 0x6E6EB2DC'u32, 0x5A5AEEB4'u32, 0xA0A0FB5B'u32,
0x5252F6A4'u32, 0x3B3B4D76'u32, 0xD6D661B7'u32, 0xB3B3CE7D'u32,
0x29297B52'u32, 0xE3E33EDD'u32, 0x2F2F715E'u32, 0x84849713'u32,
0x5353F5A6'u32, 0xD1D168B9'u32, 0x00000000'u32, 0xEDED2CC1'u32,
0x20206040'u32, 0xFCFC1FE3'u32, 0xB1B1C879'u32, 0x5B5BEDB6'u32,
0x6A6ABED4'u32, 0xCBCB468D'u32, 0xBEBED967'u32, 0x39394B72'u32,
0x4A4ADE94'u32, 0x4C4CD498'u32, 0x5858E8B0'u32, 0xCFCF4A85'u32,
0xD0D06BBB'u32, 0xEFEF2AC5'u32, 0xAAAAE54F'u32, 0xFBFB16ED'u32,
0x4343C586'u32, 0x4D4DD79A'u32, 0x33335566'u32, 0x85859411'u32,
0x4545CF8A'u32, 0xF9F910E9'u32, 0x02020604'u32, 0x7F7F81FE'u32,
0x5050F0A0'u32, 0x3C3C4478'u32, 0x9F9FBA25'u32, 0xA8A8E34B'u32,
0x5151F3A2'u32, 0xA3A3FE5D'u32, 0x4040C080'u32, 0x8F8F8A05'u32,
0x9292AD3F'u32, 0x9D9DBC21'u32, 0x38384870'u32, 0xF5F504F1'u32,
0xBCBCDF63'u32, 0xB6B6C177'u32, 0xDADA75AF'u32, 0x21216342'u32,
0x10103020'u32, 0xFFFF1AE5'u32, 0xF3F30EFD'u32, 0xD2D26DBF'u32,
0xCDCD4C81'u32, 0x0C0C1418'u32, 0x13133526'u32, 0xECEC2FC3'u32,
0x5F5FE1BE'u32, 0x9797A235'u32, 0x4444CC88'u32, 0x1717392E'u32,
0xC4C45793'u32, 0xA7A7F255'u32, 0x7E7E82FC'u32, 0x3D3D477A'u32,
0x6464ACC8'u32, 0x5D5DE7BA'u32, 0x19192B32'u32, 0x737395E6'u32,
0x6060A0C0'u32, 0x81819819'u32, 0x4F4FD19E'u32, 0xDCDC7FA3'u32,
0x22226644'u32, 0x2A2A7E54'u32, 0x9090AB3B'u32, 0x8888830B'u32,
0x4646CA8C'u32, 0xEEEE29C7'u32, 0xB8B8D36B'u32, 0x14143C28'u32,
0xDEDE79A7'u32, 0x5E5EE2BC'u32, 0x0B0B1D16'u32, 0xDBDB76AD'u32,
0xE0E03BDB'u32, 0x32325664'u32, 0x3A3A4E74'u32, 0x0A0A1E14'u32,
0x4949DB92'u32, 0x06060A0C'u32, 0x24246C48'u32, 0x5C5CE4B8'u32,
0xC2C25D9F'u32, 0xD3D36EBD'u32, 0xACACEF43'u32, 0x6262A6C4'u32,
0x9191A839'u32, 0x9595A431'u32, 0xE4E437D3'u32, 0x79798BF2'u32,
0xE7E732D5'u32, 0xC8C8438B'u32, 0x3737596E'u32, 0x6D6DB7DA'u32,
0x8D8D8C01'u32, 0xD5D564B1'u32, 0x4E4ED29C'u32, 0xA9A9E049'u32,
0x6C6CB4D8'u32, 0x5656FAAC'u32, 0xF4F407F3'u32, 0xEAEA25CF'u32,
0x6565AFCA'u32, 0x7A7A8EF4'u32, 0xAEAEE947'u32, 0x08081810'u32,
0xBABAD56F'u32, 0x787888F0'u32, 0x25256F4A'u32, 0x2E2E725C'u32,
0x1C1C2438'u32, 0xA6A6F157'u32, 0xB4B4C773'u32, 0xC6C65197'u32,
0xE8E823CB'u32, 0xDDDD7CA1'u32, 0x74749CE8'u32, 0x1F1F213E'u32,
0x4B4BDD96'u32, 0xBDBDDC61'u32, 0x8B8B860D'u32, 0x8A8A850F'u32,
0x707090E0'u32, 0x3E3E427C'u32, 0xB5B5C471'u32, 0x6666AACC'u32,
0x4848D890'u32, 0x03030506'u32, 0xF6F601F7'u32, 0x0E0E121C'u32,
0x6161A3C2'u32, 0x35355F6A'u32, 0x5757F9AE'u32, 0xB9B9D069'u32,
0x86869117'u32, 0xC1C15899'u32, 0x1D1D273A'u32, 0x9E9EB927'u32,
0xE1E138D9'u32, 0xF8F813EB'u32, 0x9898B32B'u32, 0x11113322'u32,
0x6969BBD2'u32, 0xD9D970A9'u32, 0x8E8E8907'u32, 0x9494A733'u32,
0x9B9BB62D'u32, 0x1E1E223C'u32, 0x87879215'u32, 0xE9E920C9'u32,
0xCECE4987'u32, 0x5555FFAA'u32, 0x28287850'u32, 0xDFDF7AA5'u32,
0x8C8C8F03'u32, 0xA1A1F859'u32, 0x89898009'u32, 0x0D0D171A'u32,
0xBFBFDA65'u32, 0xE6E631D7'u32, 0x4242C684'u32, 0x6868B8D0'u32,
0x4141C382'u32, 0x9999B029'u32, 0x2D2D775A'u32, 0x0F0F111E'u32,
0xB0B0CB7B'u32, 0x5454FCA8'u32, 0xBBBBD66D'u32, 0x16163A2C'u32
]
Te4 = [
0x63636363'u32, 0x7C7C7C7C'u32, 0x77777777'u32, 0x7B7B7B7B'u32,
0xF2F2F2F2'u32, 0x6B6B6B6B'u32, 0x6F6F6F6F'u32, 0xC5C5C5C5'u32,
0x30303030'u32, 0x01010101'u32, 0x67676767'u32, 0x2B2B2B2B'u32,
0xFEFEFEFE'u32, 0xD7D7D7D7'u32, 0xABABABAB'u32, 0x76767676'u32,
0xCACACACA'u32, 0x82828282'u32, 0xC9C9C9C9'u32, 0x7D7D7D7D'u32,
0xFAFAFAFA'u32, 0x59595959'u32, 0x47474747'u32, 0xF0F0F0F0'u32,
0xADADADAD'u32, 0xD4D4D4D4'u32, 0xA2A2A2A2'u32, 0xAFAFAFAF'u32,
0x9C9C9C9C'u32, 0xA4A4A4A4'u32, 0x72727272'u32, 0xC0C0C0C0'u32,
0xB7B7B7B7'u32, 0xFDFDFDFD'u32, 0x93939393'u32, 0x26262626'u32,
0x36363636'u32, 0x3F3F3F3F'u32, 0xF7F7F7F7'u32, 0xCCCCCCCC'u32,
0x34343434'u32, 0xA5A5A5A5'u32, 0xE5E5E5E5'u32, 0xF1F1F1F1'u32,
0x71717171'u32, 0xD8D8D8D8'u32, 0x31313131'u32, 0x15151515'u32,
0x04040404'u32, 0xC7C7C7C7'u32, 0x23232323'u32, 0xC3C3C3C3'u32,
0x18181818'u32, 0x96969696'u32, 0x05050505'u32, 0x9A9A9A9A'u32,
0x07070707'u32, 0x12121212'u32, 0x80808080'u32, 0xE2E2E2E2'u32,
0xEBEBEBEB'u32, 0x27272727'u32, 0xB2B2B2B2'u32, 0x75757575'u32,
0x09090909'u32, 0x83838383'u32, 0x2C2C2C2C'u32, 0x1A1A1A1A'u32,
0x1B1B1B1B'u32, 0x6E6E6E6E'u32, 0x5A5A5A5A'u32, 0xA0A0A0A0'u32,
0x52525252'u32, 0x3B3B3B3B'u32, 0xD6D6D6D6'u32, 0xB3B3B3B3'u32,
0x29292929'u32, 0xE3E3E3E3'u32, 0x2F2F2F2F'u32, 0x84848484'u32,
0x53535353'u32, 0xD1D1D1D1'u32, 0x00000000'u32, 0xEDEDEDED'u32,
0x20202020'u32, 0xFCFCFCFC'u32, 0xB1B1B1B1'u32, 0x5B5B5B5B'u32,
0x6A6A6A6A'u32, 0xCBCBCBCB'u32, 0xBEBEBEBE'u32, 0x39393939'u32,
0x4A4A4A4A'u32, 0x4C4C4C4C'u32, 0x58585858'u32, 0xCFCFCFCF'u32,
0xD0D0D0D0'u32, 0xEFEFEFEF'u32, 0xAAAAAAAA'u32, 0xFBFBFBFB'u32,
0x43434343'u32, 0x4D4D4D4D'u32, 0x33333333'u32, 0x85858585'u32,
0x45454545'u32, 0xF9F9F9F9'u32, 0x02020202'u32, 0x7F7F7F7F'u32,
0x50505050'u32, 0x3C3C3C3C'u32, 0x9F9F9F9F'u32, 0xA8A8A8A8'u32,
0x51515151'u32, 0xA3A3A3A3'u32, 0x40404040'u32, 0x8F8F8F8F'u32,
0x92929292'u32, 0x9D9D9D9D'u32, 0x38383838'u32, 0xF5F5F5F5'u32,
0xBCBCBCBC'u32, 0xB6B6B6B6'u32, 0xDADADADA'u32, 0x21212121'u32,
0x10101010'u32, 0xFFFFFFFF'u32, 0xF3F3F3F3'u32, 0xD2D2D2D2'u32,
0xCDCDCDCD'u32, 0x0C0C0C0C'u32, 0x13131313'u32, 0xECECECEC'u32,
0x5F5F5F5F'u32, 0x97979797'u32, 0x44444444'u32, 0x17171717'u32,
0xC4C4C4C4'u32, 0xA7A7A7A7'u32, 0x7E7E7E7E'u32, 0x3D3D3D3D'u32,
0x64646464'u32, 0x5D5D5D5D'u32, 0x19191919'u32, 0x73737373'u32,
0x60606060'u32, 0x81818181'u32, 0x4F4F4F4F'u32, 0xDCDCDCDC'u32,
0x22222222'u32, 0x2A2A2A2A'u32, 0x90909090'u32, 0x88888888'u32,
0x46464646'u32, 0xEEEEEEEE'u32, 0xB8B8B8B8'u32, 0x14141414'u32,
0xDEDEDEDE'u32, 0x5E5E5E5E'u32, 0x0B0B0B0B'u32, 0xDBDBDBDB'u32,
0xE0E0E0E0'u32, 0x32323232'u32, 0x3A3A3A3A'u32, 0x0A0A0A0A'u32,
0x49494949'u32, 0x06060606'u32, 0x24242424'u32, 0x5C5C5C5C'u32,
0xC2C2C2C2'u32, 0xD3D3D3D3'u32, 0xACACACAC'u32, 0x62626262'u32,
0x91919191'u32, 0x95959595'u32, 0xE4E4E4E4'u32, 0x79797979'u32,
0xE7E7E7E7'u32, 0xC8C8C8C8'u32, 0x37373737'u32, 0x6D6D6D6D'u32,
0x8D8D8D8D'u32, 0xD5D5D5D5'u32, 0x4E4E4E4E'u32, 0xA9A9A9A9'u32,
0x6C6C6C6C'u32, 0x56565656'u32, 0xF4F4F4F4'u32, 0xEAEAEAEA'u32,
0x65656565'u32, 0x7A7A7A7A'u32, 0xAEAEAEAE'u32, 0x08080808'u32,
0xBABABABA'u32, 0x78787878'u32, 0x25252525'u32, 0x2E2E2E2E'u32,
0x1C1C1C1C'u32, 0xA6A6A6A6'u32, 0xB4B4B4B4'u32, 0xC6C6C6C6'u32,
0xE8E8E8E8'u32, 0xDDDDDDDD'u32, 0x74747474'u32, 0x1F1F1F1F'u32,
0x4B4B4B4B'u32, 0xBDBDBDBD'u32, 0x8B8B8B8B'u32, 0x8A8A8A8A'u32,
0x70707070'u32, 0x3E3E3E3E'u32, 0xB5B5B5B5'u32, 0x66666666'u32,
0x48484848'u32, 0x03030303'u32, 0xF6F6F6F6'u32, 0x0E0E0E0E'u32,
0x61616161'u32, 0x35353535'u32, 0x57575757'u32, 0xB9B9B9B9'u32,
0x86868686'u32, 0xC1C1C1C1'u32, 0x1D1D1D1D'u32, 0x9E9E9E9E'u32,
0xE1E1E1E1'u32, 0xF8F8F8F8'u32, 0x98989898'u32, 0x11111111'u32,
0x69696969'u32, 0xD9D9D9D9'u32, 0x8E8E8E8E'u32, 0x94949494'u32,
0x9B9B9B9B'u32, 0x1E1E1E1E'u32, 0x87878787'u32, 0xE9E9E9E9'u32,
0xCECECECE'u32, 0x55555555'u32, 0x28282828'u32, 0xDFDFDFDF'u32,
0x8C8C8C8C'u32, 0xA1A1A1A1'u32, 0x89898989'u32, 0x0D0D0D0D'u32,
0xBFBFBFBF'u32, 0xE6E6E6E6'u32, 0x42424242'u32, 0x68686868'u32,
0x41414141'u32, 0x99999999'u32, 0x2D2D2D2D'u32, 0x0F0F0F0F'u32,
0xB0B0B0B0'u32, 0x54545454'u32, 0xBBBBBBBB'u32, 0x16161616'u32
]
Td0 = [
0x51F4A750'u32, 0x7E416553'u32, 0x1A17A4C3'u32, 0x3A275E96'u32,
0x3BAB6BCB'u32, 0x1F9D45F1'u32, 0xACFA58AB'u32, 0x4BE30393'u32,
0x2030FA55'u32, 0xAD766DF6'u32, 0x88CC7691'u32, 0xF5024C25'u32,
0x4FE5D7FC'u32, 0xC52ACBD7'u32, 0x26354480'u32, 0xB562A38F'u32,
0xDEB15A49'u32, 0x25BA1B67'u32, 0x45EA0E98'u32, 0x5DFEC0E1'u32,
0xC32F7502'u32, 0x814CF012'u32, 0x8D4697A3'u32, 0x6BD3F9C6'u32,
0x038F5FE7'u32, 0x15929C95'u32, 0xBF6D7AEB'u32, 0x955259DA'u32,
0xD4BE832D'u32, 0x587421D3'u32, 0x49E06929'u32, 0x8EC9C844'u32,
0x75C2896A'u32, 0xF48E7978'u32, 0x99583E6B'u32, 0x27B971DD'u32,
0xBEE14FB6'u32, 0xF088AD17'u32, 0xC920AC66'u32, 0x7DCE3AB4'u32,
0x63DF4A18'u32, 0xE51A3182'u32, 0x97513360'u32, 0x62537F45'u32,
0xB16477E0'u32, 0xBB6BAE84'u32, 0xFE81A01C'u32, 0xF9082B94'u32,
0x70486858'u32, 0x8F45FD19'u32, 0x94DE6C87'u32, 0x527BF8B7'u32,
0xAB73D323'u32, 0x724B02E2'u32, 0xE31F8F57'u32, 0x6655AB2A'u32,
0xB2EB2807'u32, 0x2FB5C203'u32, 0x86C57B9A'u32, 0xD33708A5'u32,
0x302887F2'u32, 0x23BFA5B2'u32, 0x02036ABA'u32, 0xED16825C'u32,
0x8ACF1C2B'u32, 0xA779B492'u32, 0xF307F2F0'u32, 0x4E69E2A1'u32,
0x65DAF4CD'u32, 0x0605BED5'u32, 0xD134621F'u32, 0xC4A6FE8A'u32,
0x342E539D'u32, 0xA2F355A0'u32, 0x058AE132'u32, 0xA4F6EB75'u32,
0x0B83EC39'u32, 0x4060EFAA'u32, 0x5E719F06'u32, 0xBD6E1051'u32,
0x3E218AF9'u32, 0x96DD063D'u32, 0xDD3E05AE'u32, 0x4DE6BD46'u32,
0x91548DB5'u32, 0x71C45D05'u32, 0x0406D46F'u32, 0x605015FF'u32,
0x1998FB24'u32, 0xD6BDE997'u32, 0x894043CC'u32, 0x67D99E77'u32,
0xB0E842BD'u32, 0x07898B88'u32, 0xE7195B38'u32, 0x79C8EEDB'u32,
0xA17C0A47'u32, 0x7C420FE9'u32, 0xF8841EC9'u32, 0x00000000'u32,
0x09808683'u32, 0x322BED48'u32, 0x1E1170AC'u32, 0x6C5A724E'u32,
0xFD0EFFFB'u32, 0x0F853856'u32, 0x3DAED51E'u32, 0x362D3927'u32,
0x0A0FD964'u32, 0x685CA621'u32, 0x9B5B54D1'u32, 0x24362E3A'u32,
0x0C0A67B1'u32, 0x9357E70F'u32, 0xB4EE96D2'u32, 0x1B9B919E'u32,
0x80C0C54F'u32, 0x61DC20A2'u32, 0x5A774B69'u32, 0x1C121A16'u32,
0xE293BA0A'u32, 0xC0A02AE5'u32, 0x3C22E043'u32, 0x121B171D'u32,
0x0E090D0B'u32, 0xF28BC7AD'u32, 0x2DB6A8B9'u32, 0x141EA9C8'u32,
0x57F11985'u32, 0xAF75074C'u32, 0xEE99DDBB'u32, 0xA37F60FD'u32,
0xF701269F'u32, 0x5C72F5BC'u32, 0x44663BC5'u32, 0x5BFB7E34'u32,
0x8B432976'u32, 0xCB23C6DC'u32, 0xB6EDFC68'u32, 0xB8E4F163'u32,
0xD731DCCA'u32, 0x42638510'u32, 0x13972240'u32, 0x84C61120'u32,
0x854A247D'u32, 0xD2BB3DF8'u32, 0xAEF93211'u32, 0xC729A16D'u32,
0x1D9E2F4B'u32, 0xDCB230F3'u32, 0x0D8652EC'u32, 0x77C1E3D0'u32,
0x2BB3166C'u32, 0xA970B999'u32, 0x119448FA'u32, 0x47E96422'u32,
0xA8FC8CC4'u32, 0xA0F03F1A'u32, 0x567D2CD8'u32, 0x223390EF'u32,
0x87494EC7'u32, 0xD938D1C1'u32, 0x8CCAA2FE'u32, 0x98D40B36'u32,
0xA6F581CF'u32, 0xA57ADE28'u32, 0xDAB78E26'u32, 0x3FADBFA4'u32,
0x2C3A9DE4'u32, 0x5078920D'u32, 0x6A5FCC9B'u32, 0x547E4662'u32,
0xF68D13C2'u32, 0x90D8B8E8'u32, 0x2E39F75E'u32, 0x82C3AFF5'u32,
0x9F5D80BE'u32, 0x69D0937C'u32, 0x6FD52DA9'u32, 0xCF2512B3'u32,
0xC8AC993B'u32, 0x10187DA7'u32, 0xE89C636E'u32, 0xDB3BBB7B'u32,
0xCD267809'u32, 0x6E5918F4'u32, 0xEC9AB701'u32, 0x834F9AA8'u32,
0xE6956E65'u32, 0xAAFFE67E'u32, 0x21BCCF08'u32, 0xEF15E8E6'u32,
0xBAE79BD9'u32, 0x4A6F36CE'u32, 0xEA9F09D4'u32, 0x29B07CD6'u32,
0x31A4B2AF'u32, 0x2A3F2331'u32, 0xC6A59430'u32, 0x35A266C0'u32,
0x744EBC37'u32, 0xFC82CAA6'u32, 0xE090D0B0'u32, 0x33A7D815'u32,
0xF104984A'u32, 0x41ECDAF7'u32, 0x7FCD500E'u32, 0x1791F62F'u32,
0x764DD68D'u32, 0x43EFB04D'u32, 0xCCAA4D54'u32, 0xE49604DF'u32,
0x9ED1B5E3'u32, 0x4C6A881B'u32, 0xC12C1FB8'u32, 0x4665517F'u32,
0x9D5EEA04'u32, 0x018C355D'u32, 0xFA877473'u32, 0xFB0B412E'u32,
0xB3671D5A'u32, 0x92DBD252'u32, 0xE9105633'u32, 0x6DD64713'u32,
0x9AD7618C'u32, 0x37A10C7A'u32, 0x59F8148E'u32, 0xEB133C89'u32,
0xCEA927EE'u32, 0xB761C935'u32, 0xE11CE5ED'u32, 0x7A47B13C'u32,
0x9CD2DF59'u32, 0x55F2733F'u32, 0x1814CE79'u32, 0x73C737BF'u32,
0x53F7CDEA'u32, 0x5FFDAA5B'u32, 0xDF3D6F14'u32, 0x7844DB86'u32,
0xCAAFF381'u32, 0xB968C43E'u32, 0x3824342C'u32, 0xC2A3405F'u32,
0x161DC372'u32, 0xBCE2250C'u32, 0x283C498B'u32, 0xFF0D9541'u32,
0x39A80171'u32, 0x080CB3DE'u32, 0xD8B4E49C'u32, 0x6456C190'u32,
0x7BCB8461'u32, 0xD532B670'u32, 0x486C5C74'u32, 0xD0B85742'u32
]
Td1 = [
0x5051F4A7'u32, 0x537E4165'u32, 0xC31A17A4'u32, 0x963A275E'u32,
0xCB3BAB6B'u32, 0xF11F9D45'u32, 0xABACFA58'u32, 0x934BE303'u32,
0x552030FA'u32, 0xF6AD766D'u32, 0x9188CC76'u32, 0x25F5024C'u32,
0xFC4FE5D7'u32, 0xD7C52ACB'u32, 0x80263544'u32, 0x8FB562A3'u32,
0x49DEB15A'u32, 0x6725BA1B'u32, 0x9845EA0E'u32, 0xE15DFEC0'u32,
0x02C32F75'u32, 0x12814CF0'u32, 0xA38D4697'u32, 0xC66BD3F9'u32,
0xE7038F5F'u32, 0x9515929C'u32, 0xEBBF6D7A'u32, 0xDA955259'u32,
0x2DD4BE83'u32, 0xD3587421'u32, 0x2949E069'u32, 0x448EC9C8'u32,
0x6A75C289'u32, 0x78F48E79'u32, 0x6B99583E'u32, 0xDD27B971'u32,
0xB6BEE14F'u32, 0x17F088AD'u32, 0x66C920AC'u32, 0xB47DCE3A'u32,
0x1863DF4A'u32, 0x82E51A31'u32, 0x60975133'u32, 0x4562537F'u32,
0xE0B16477'u32, 0x84BB6BAE'u32, 0x1CFE81A0'u32, 0x94F9082B'u32,
0x58704868'u32, 0x198F45FD'u32, 0x8794DE6C'u32, 0xB7527BF8'u32,
0x23AB73D3'u32, 0xE2724B02'u32, 0x57E31F8F'u32, 0x2A6655AB'u32,
0x07B2EB28'u32, 0x032FB5C2'u32, 0x9A86C57B'u32, 0xA5D33708'u32,
0xF2302887'u32, 0xB223BFA5'u32, 0xBA02036A'u32, 0x5CED1682'u32,
0x2B8ACF1C'u32, 0x92A779B4'u32, 0xF0F307F2'u32, 0xA14E69E2'u32,
0xCD65DAF4'u32, 0xD50605BE'u32, 0x1FD13462'u32, 0x8AC4A6FE'u32,
0x9D342E53'u32, 0xA0A2F355'u32, 0x32058AE1'u32, 0x75A4F6EB'u32,
0x390B83EC'u32, 0xAA4060EF'u32, 0x065E719F'u32, 0x51BD6E10'u32,
0xF93E218A'u32, 0x3D96DD06'u32, 0xAEDD3E05'u32, 0x464DE6BD'u32,
0xB591548D'u32, 0x0571C45D'u32, 0x6F0406D4'u32, 0xFF605015'u32,
0x241998FB'u32, 0x97D6BDE9'u32, 0xCC894043'u32, 0x7767D99E'u32,
0xBDB0E842'u32, 0x8807898B'u32, 0x38E7195B'u32, 0xDB79C8EE'u32,
0x47A17C0A'u32, 0xE97C420F'u32, 0xC9F8841E'u32, 0x00000000'u32,
0x83098086'u32, 0x48322BED'u32, 0xAC1E1170'u32, 0x4E6C5A72'u32,
0xFBFD0EFF'u32, 0x560F8538'u32, 0x1E3DAED5'u32, 0x27362D39'u32,
0x640A0FD9'u32, 0x21685CA6'u32, 0xD19B5B54'u32, 0x3A24362E'u32,
0xB10C0A67'u32, 0x0F9357E7'u32, 0xD2B4EE96'u32, 0x9E1B9B91'u32,
0x4F80C0C5'u32, 0xA261DC20'u32, 0x695A774B'u32, 0x161C121A'u32,
0x0AE293BA'u32, 0xE5C0A02A'u32, 0x433C22E0'u32, 0x1D121B17'u32,
0x0B0E090D'u32, 0xADF28BC7'u32, 0xB92DB6A8'u32, 0xC8141EA9'u32,
0x8557F119'u32, 0x4CAF7507'u32, 0xBBEE99DD'u32, 0xFDA37F60'u32,
0x9FF70126'u32, 0xBC5C72F5'u32, 0xC544663B'u32, 0x345BFB7E'u32,
0x768B4329'u32, 0xDCCB23C6'u32, 0x68B6EDFC'u32, 0x63B8E4F1'u32,
0xCAD731DC'u32, 0x10426385'u32, 0x40139722'u32, 0x2084C611'u32,
0x7D854A24'u32, 0xF8D2BB3D'u32, 0x11AEF932'u32, 0x6DC729A1'u32,
0x4B1D9E2F'u32, 0xF3DCB230'u32, 0xEC0D8652'u32, 0xD077C1E3'u32,
0x6C2BB316'u32, 0x99A970B9'u32, 0xFA119448'u32, 0x2247E964'u32,
0xC4A8FC8C'u32, 0x1AA0F03F'u32, 0xD8567D2C'u32, 0xEF223390'u32,
0xC787494E'u32, 0xC1D938D1'u32, 0xFE8CCAA2'u32, 0x3698D40B'u32,
0xCFA6F581'u32, 0x28A57ADE'u32, 0x26DAB78E'u32, 0xA43FADBF'u32,
0xE42C3A9D'u32, 0x0D507892'u32, 0x9B6A5FCC'u32, 0x62547E46'u32,
0xC2F68D13'u32, 0xE890D8B8'u32, 0x5E2E39F7'u32, 0xF582C3AF'u32,
0xBE9F5D80'u32, 0x7C69D093'u32, 0xA96FD52D'u32, 0xB3CF2512'u32,
0x3BC8AC99'u32, 0xA710187D'u32, 0x6EE89C63'u32, 0x7BDB3BBB'u32,
0x09CD2678'u32, 0xF46E5918'u32, 0x01EC9AB7'u32, 0xA8834F9A'u32,
0x65E6956E'u32, 0x7EAAFFE6'u32, 0x0821BCCF'u32, 0xE6EF15E8'u32,
0xD9BAE79B'u32, 0xCE4A6F36'u32, 0xD4EA9F09'u32, 0xD629B07C'u32,
0xAF31A4B2'u32, 0x312A3F23'u32, 0x30C6A594'u32, 0xC035A266'u32,
0x37744EBC'u32, 0xA6FC82CA'u32, 0xB0E090D0'u32, 0x1533A7D8'u32,
0x4AF10498'u32, 0xF741ECDA'u32, 0x0E7FCD50'u32, 0x2F1791F6'u32,
0x8D764DD6'u32, 0x4D43EFB0'u32, 0x54CCAA4D'u32, 0xDFE49604'u32,
0xE39ED1B5'u32, 0x1B4C6A88'u32, 0xB8C12C1F'u32, 0x7F466551'u32,
0x049D5EEA'u32, 0x5D018C35'u32, 0x73FA8774'u32, 0x2EFB0B41'u32,
0x5AB3671D'u32, 0x5292DBD2'u32, 0x33E91056'u32, 0x136DD647'u32,
0x8C9AD761'u32, 0x7A37A10C'u32, 0x8E59F814'u32, 0x89EB133C'u32,
0xEECEA927'u32, 0x35B761C9'u32, 0xEDE11CE5'u32, 0x3C7A47B1'u32,
0x599CD2DF'u32, 0x3F55F273'u32, 0x791814CE'u32, 0xBF73C737'u32,
0xEA53F7CD'u32, 0x5B5FFDAA'u32, 0x14DF3D6F'u32, 0x867844DB'u32,
0x81CAAFF3'u32, 0x3EB968C4'u32, 0x2C382434'u32, 0x5FC2A340'u32,
0x72161DC3'u32, 0x0CBCE225'u32, 0x8B283C49'u32, 0x41FF0D95'u32,
0x7139A801'u32, 0xDE080CB3'u32, 0x9CD8B4E4'u32, 0x906456C1'u32,
0x617BCB84'u32, 0x70D532B6'u32, 0x74486C5C'u32, 0x42D0B857'u32
]
Td2 = [
0xA75051F4'u32, 0x65537E41'u32, 0xA4C31A17'u32, 0x5E963A27'u32,
0x6BCB3BAB'u32, 0x45F11F9D'u32, 0x58ABACFA'u32, 0x03934BE3'u32,
0xFA552030'u32, 0x6DF6AD76'u32, 0x769188CC'u32, 0x4C25F502'u32,
0xD7FC4FE5'u32, 0xCBD7C52A'u32, 0x44802635'u32, 0xA38FB562'u32,
0x5A49DEB1'u32, 0x1B6725BA'u32, 0x0E9845EA'u32, 0xC0E15DFE'u32,
0x7502C32F'u32, 0xF012814C'u32, 0x97A38D46'u32, 0xF9C66BD3'u32,
0x5FE7038F'u32, 0x9C951592'u32, 0x7AEBBF6D'u32, 0x59DA9552'u32,
0x832DD4BE'u32, 0x21D35874'u32, 0x692949E0'u32, 0xC8448EC9'u32,
0x896A75C2'u32, 0x7978F48E'u32, 0x3E6B9958'u32, 0x71DD27B9'u32,
0x4FB6BEE1'u32, 0xAD17F088'u32, 0xAC66C920'u32, 0x3AB47DCE'u32,
0x4A1863DF'u32, 0x3182E51A'u32, 0x33609751'u32, 0x7F456253'u32,
0x77E0B164'u32, 0xAE84BB6B'u32, 0xA01CFE81'u32, 0x2B94F908'u32,
0x68587048'u32, 0xFD198F45'u32, 0x6C8794DE'u32, 0xF8B7527B'u32,
0xD323AB73'u32, 0x02E2724B'u32, 0x8F57E31F'u32, 0xAB2A6655'u32,
0x2807B2EB'u32, 0xC2032FB5'u32, 0x7B9A86C5'u32, 0x08A5D337'u32,
0x87F23028'u32, 0xA5B223BF'u32, 0x6ABA0203'u32, 0x825CED16'u32,
0x1C2B8ACF'u32, 0xB492A779'u32, 0xF2F0F307'u32, 0xE2A14E69'u32,
0xF4CD65DA'u32, 0xBED50605'u32, 0x621FD134'u32, 0xFE8AC4A6'u32,
0x539D342E'u32, 0x55A0A2F3'u32, 0xE132058A'u32, 0xEB75A4F6'u32,
0xEC390B83'u32, 0xEFAA4060'u32, 0x9F065E71'u32, 0x1051BD6E'u32,
0x8AF93E21'u32, 0x063D96DD'u32, 0x05AEDD3E'u32, 0xBD464DE6'u32,
0x8DB59154'u32, 0x5D0571C4'u32, 0xD46F0406'u32, 0x15FF6050'u32,
0xFB241998'u32, 0xE997D6BD'u32, 0x43CC8940'u32, 0x9E7767D9'u32,
0x42BDB0E8'u32, 0x8B880789'u32, 0x5B38E719'u32, 0xEEDB79C8'u32,
0x0A47A17C'u32, 0x0FE97C42'u32, 0x1EC9F884'u32, 0x00000000'u32,
0x86830980'u32, 0xED48322B'u32, 0x70AC1E11'u32, 0x724E6C5A'u32,
0xFFFBFD0E'u32, 0x38560F85'u32, 0xD51E3DAE'u32, 0x3927362D'u32,
0xD9640A0F'u32, 0xA621685C'u32, 0x54D19B5B'u32, 0x2E3A2436'u32,
0x67B10C0A'u32, 0xE70F9357'u32, 0x96D2B4EE'u32, 0x919E1B9B'u32,
0xC54F80C0'u32, 0x20A261DC'u32, 0x4B695A77'u32, 0x1A161C12'u32,
0xBA0AE293'u32, 0x2AE5C0A0'u32, 0xE0433C22'u32, 0x171D121B'u32,
0x0D0B0E09'u32, 0xC7ADF28B'u32, 0xA8B92DB6'u32, 0xA9C8141E'u32,
0x198557F1'u32, 0x074CAF75'u32, 0xDDBBEE99'u32, 0x60FDA37F'u32,
0x269FF701'u32, 0xF5BC5C72'u32, 0x3BC54466'u32, 0x7E345BFB'u32,
0x29768B43'u32, 0xC6DCCB23'u32, 0xFC68B6ED'u32, 0xF163B8E4'u32,
0xDCCAD731'u32, 0x85104263'u32, 0x22401397'u32, 0x112084C6'u32,
0x247D854A'u32, 0x3DF8D2BB'u32, 0x3211AEF9'u32, 0xA16DC729'u32,
0x2F4B1D9E'u32, 0x30F3DCB2'u32, 0x52EC0D86'u32, 0xE3D077C1'u32,
0x166C2BB3'u32, 0xB999A970'u32, 0x48FA1194'u32, 0x642247E9'u32,
0x8CC4A8FC'u32, 0x3F1AA0F0'u32, 0x2CD8567D'u32, 0x90EF2233'u32,
0x4EC78749'u32, 0xD1C1D938'u32, 0xA2FE8CCA'u32, 0x0B3698D4'u32,
0x81CFA6F5'u32, 0xDE28A57A'u32, 0x8E26DAB7'u32, 0xBFA43FAD'u32,
0x9DE42C3A'u32, 0x920D5078'u32, 0xCC9B6A5F'u32, 0x4662547E'u32,
0x13C2F68D'u32, 0xB8E890D8'u32, 0xF75E2E39'u32, 0xAFF582C3'u32,
0x80BE9F5D'u32, 0x937C69D0'u32, 0x2DA96FD5'u32, 0x12B3CF25'u32,
0x993BC8AC'u32, 0x7DA71018'u32, 0x636EE89C'u32, 0xBB7BDB3B'u32,
0x7809CD26'u32, 0x18F46E59'u32, 0xB701EC9A'u32, 0x9AA8834F'u32,
0x6E65E695'u32, 0xE67EAAFF'u32, 0xCF0821BC'u32, 0xE8E6EF15'u32,
0x9BD9BAE7'u32, 0x36CE4A6F'u32, 0x09D4EA9F'u32, 0x7CD629B0'u32,
0xB2AF31A4'u32, 0x23312A3F'u32, 0x9430C6A5'u32, 0x66C035A2'u32,
0xBC37744E'u32, 0xCAA6FC82'u32, 0xD0B0E090'u32, 0xD81533A7'u32,
0x984AF104'u32, 0xDAF741EC'u32, 0x500E7FCD'u32, 0xF62F1791'u32,
0xD68D764D'u32, 0xB04D43EF'u32, 0x4D54CCAA'u32, 0x04DFE496'u32,
0xB5E39ED1'u32, 0x881B4C6A'u32, 0x1FB8C12C'u32, 0x517F4665'u32,
0xEA049D5E'u32, 0x355D018C'u32, 0x7473FA87'u32, 0x412EFB0B'u32,
0x1D5AB367'u32, 0xD25292DB'u32, 0x5633E910'u32, 0x47136DD6'u32,
0x618C9AD7'u32, 0x0C7A37A1'u32, 0x148E59F8'u32, 0x3C89EB13'u32,
0x27EECEA9'u32, 0xC935B761'u32, 0xE5EDE11C'u32, 0xB13C7A47'u32,
0xDF599CD2'u32, 0x733F55F2'u32, 0xCE791814'u32, 0x37BF73C7'u32,
0xCDEA53F7'u32, 0xAA5B5FFD'u32, 0x6F14DF3D'u32, 0xDB867844'u32,
0xF381CAAF'u32, 0xC43EB968'u32, 0x342C3824'u32, 0x405FC2A3'u32,
0xC372161D'u32, 0x250CBCE2'u32, 0x498B283C'u32, 0x9541FF0D'u32,
0x017139A8'u32, 0xB3DE080C'u32, 0xE49CD8B4'u32, 0xC1906456'u32,
0x84617BCB'u32, 0xB670D532'u32, 0x5C74486C'u32, 0x5742D0B8'u32
]
Td3 = [
0xF4A75051'u32, 0x4165537E'u32, 0x17A4C31A'u32, 0x275E963A'u32,
0xAB6BCB3B'u32, 0x9D45F11F'u32, 0xFA58ABAC'u32, 0xE303934B'u32,
0x30FA5520'u32, 0x766DF6AD'u32, 0xCC769188'u32, 0x024C25F5'u32,
0xE5D7FC4F'u32, 0x2ACBD7C5'u32, 0x35448026'u32, 0x62A38FB5'u32,
0xB15A49DE'u32, 0xBA1B6725'u32, 0xEA0E9845'u32, 0xFEC0E15D'u32,
0x2F7502C3'u32, 0x4CF01281'u32, 0x4697A38D'u32, 0xD3F9C66B'u32,
0x8F5FE703'u32, 0x929C9515'u32, 0x6D7AEBBF'u32, 0x5259DA95'u32,
0xBE832DD4'u32, 0x7421D358'u32, 0xE0692949'u32, 0xC9C8448E'u32,
0xC2896A75'u32, 0x8E7978F4'u32, 0x583E6B99'u32, 0xB971DD27'u32,
0xE14FB6BE'u32, 0x88AD17F0'u32, 0x20AC66C9'u32, 0xCE3AB47D'u32,
0xDF4A1863'u32, 0x1A3182E5'u32, 0x51336097'u32, 0x537F4562'u32,
0x6477E0B1'u32, 0x6BAE84BB'u32, 0x81A01CFE'u32, 0x082B94F9'u32,
0x48685870'u32, 0x45FD198F'u32, 0xDE6C8794'u32, 0x7BF8B752'u32,
0x73D323AB'u32, 0x4B02E272'u32, 0x1F8F57E3'u32, 0x55AB2A66'u32,
0xEB2807B2'u32, 0xB5C2032F'u32, 0xC57B9A86'u32, 0x3708A5D3'u32,
0x2887F230'u32, 0xBFA5B223'u32, 0x036ABA02'u32, 0x16825CED'u32,
0xCF1C2B8A'u32, 0x79B492A7'u32, 0x07F2F0F3'u32, 0x69E2A14E'u32,
0xDAF4CD65'u32, 0x05BED506'u32, 0x34621FD1'u32, 0xA6FE8AC4'u32,
0x2E539D34'u32, 0xF355A0A2'u32, 0x8AE13205'u32, 0xF6EB75A4'u32,
0x83EC390B'u32, 0x60EFAA40'u32, 0x719F065E'u32, 0x6E1051BD'u32,
0x218AF93E'u32, 0xDD063D96'u32, 0x3E05AEDD'u32, 0xE6BD464D'u32,
0x548DB591'u32, 0xC45D0571'u32, 0x06D46F04'u32, 0x5015FF60'u32,
0x98FB2419'u32, 0xBDE997D6'u32, 0x4043CC89'u32, 0xD99E7767'u32,
0xE842BDB0'u32, 0x898B8807'u32, 0x195B38E7'u32, 0xC8EEDB79'u32,
0x7C0A47A1'u32, 0x420FE97C'u32, 0x841EC9F8'u32, 0x00000000'u32,
0x80868309'u32, 0x2BED4832'u32, 0x1170AC1E'u32, 0x5A724E6C'u32,
0x0EFFFBFD'u32, 0x8538560F'u32, 0xAED51E3D'u32, 0x2D392736'u32,
0x0FD9640A'u32, 0x5CA62168'u32, 0x5B54D19B'u32, 0x362E3A24'u32,
0x0A67B10C'u32, 0x57E70F93'u32, 0xEE96D2B4'u32, 0x9B919E1B'u32,
0xC0C54F80'u32, 0xDC20A261'u32, 0x774B695A'u32, 0x121A161C'u32,
0x93BA0AE2'u32, 0xA02AE5C0'u32, 0x22E0433C'u32, 0x1B171D12'u32,
0x090D0B0E'u32, 0x8BC7ADF2'u32, 0xB6A8B92D'u32, 0x1EA9C814'u32,
0xF1198557'u32, 0x75074CAF'u32, 0x99DDBBEE'u32, 0x7F60FDA3'u32,
0x01269FF7'u32, 0x72F5BC5C'u32, 0x663BC544'u32, 0xFB7E345B'u32,
0x4329768B'u32, 0x23C6DCCB'u32, 0xEDFC68B6'u32, 0xE4F163B8'u32,
0x31DCCAD7'u32, 0x63851042'u32, 0x97224013'u32, 0xC6112084'u32,
0x4A247D85'u32, 0xBB3DF8D2'u32, 0xF93211AE'u32, 0x29A16DC7'u32,
0x9E2F4B1D'u32, 0xB230F3DC'u32, 0x8652EC0D'u32, 0xC1E3D077'u32,
0xB3166C2B'u32, 0x70B999A9'u32, 0x9448FA11'u32, 0xE9642247'u32,
0xFC8CC4A8'u32, 0xF03F1AA0'u32, 0x7D2CD856'u32, 0x3390EF22'u32,
0x494EC787'u32, 0x38D1C1D9'u32, 0xCAA2FE8C'u32, 0xD40B3698'u32,
0xF581CFA6'u32, 0x7ADE28A5'u32, 0xB78E26DA'u32, 0xADBFA43F'u32,
0x3A9DE42C'u32, 0x78920D50'u32, 0x5FCC9B6A'u32, 0x7E466254'u32,
0x8D13C2F6'u32, 0xD8B8E890'u32, 0x39F75E2E'u32, 0xC3AFF582'u32,
0x5D80BE9F'u32, 0xD0937C69'u32, 0xD52DA96F'u32, 0x2512B3CF'u32,
0xAC993BC8'u32, 0x187DA710'u32, 0x9C636EE8'u32, 0x3BBB7BDB'u32,
0x267809CD'u32, 0x5918F46E'u32, 0x9AB701EC'u32, 0x4F9AA883'u32,
0x956E65E6'u32, 0xFFE67EAA'u32, 0xBCCF0821'u32, 0x15E8E6EF'u32,
0xE79BD9BA'u32, 0x6F36CE4A'u32, 0x9F09D4EA'u32, 0xB07CD629'u32,
0xA4B2AF31'u32, 0x3F23312A'u32, 0xA59430C6'u32, 0xA266C035'u32,
0x4EBC3774'u32, 0x82CAA6FC'u32, 0x90D0B0E0'u32, 0xA7D81533'u32,
0x04984AF1'u32, 0xECDAF741'u32, 0xCD500E7F'u32, 0x91F62F17'u32,
0x4DD68D76'u32, 0xEFB04D43'u32, 0xAA4D54CC'u32, 0x9604DFE4'u32,
0xD1B5E39E'u32, 0x6A881B4C'u32, 0x2C1FB8C1'u32, 0x65517F46'u32,
0x5EEA049D'u32, 0x8C355D01'u32, 0x877473FA'u32, 0x0B412EFB'u32,
0x671D5AB3'u32, 0xDBD25292'u32, 0x105633E9'u32, 0xD647136D'u32,
0xD7618C9A'u32, 0xA10C7A37'u32, 0xF8148E59'u32, 0x133C89EB'u32,
0xA927EECE'u32, 0x61C935B7'u32, 0x1CE5EDE1'u32, 0x47B13C7A'u32,
0xD2DF599C'u32, 0xF2733F55'u32, 0x14CE7918'u32, 0xC737BF73'u32,
0xF7CDEA53'u32, 0xFDAA5B5F'u32, 0x3D6F14DF'u32, 0x44DB8678'u32,
0xAFF381CA'u32, 0x68C43EB9'u32, 0x24342C38'u32, 0xA3405FC2'u32,
0x1DC37216'u32, 0xE2250CBC'u32, 0x3C498B28'u32, 0x0D9541FF'u32,
0xA8017139'u32, 0x0CB3DE08'u32, 0xB4E49CD8'u32, 0x56C19064'u32,
0xCB84617B'u32, 0x32B670D5'u32, 0x6C5C7448'u32, 0xB85742D0'u32
]
Td4 = [
0x52525252'u32, 0x09090909'u32, 0x6A6A6A6A'u32, 0xD5D5D5D5'u32,
0x30303030'u32, 0x36363636'u32, 0xA5A5A5A5'u32, 0x38383838'u32,
0xBFBFBFBF'u32, 0x40404040'u32, 0xA3A3A3A3'u32, 0x9E9E9E9E'u32,
0x81818181'u32, 0xF3F3F3F3'u32, 0xD7D7D7D7'u32, 0xFBFBFBFB'u32,
0x7C7C7C7C'u32, 0xE3E3E3E3'u32, 0x39393939'u32, 0x82828282'u32,
0x9B9B9B9B'u32, 0x2F2F2F2F'u32, 0xFFFFFFFF'u32, 0x87878787'u32,
0x34343434'u32, 0x8E8E8E8E'u32, 0x43434343'u32, 0x44444444'u32,
0xC4C4C4C4'u32, 0xDEDEDEDE'u32, 0xE9E9E9E9'u32, 0xCBCBCBCB'u32,
0x54545454'u32, 0x7B7B7B7B'u32, 0x94949494'u32, 0x32323232'u32,
0xA6A6A6A6'u32, 0xC2C2C2C2'u32, 0x23232323'u32, 0x3D3D3D3D'u32,
0xEEEEEEEE'u32, 0x4C4C4C4C'u32, 0x95959595'u32, 0x0B0B0B0B'u32,
0x42424242'u32, 0xFAFAFAFA'u32, 0xC3C3C3C3'u32, 0x4E4E4E4E'u32,
0x08080808'u32, 0x2E2E2E2E'u32, 0xA1A1A1A1'u32, 0x66666666'u32,
0x28282828'u32, 0xD9D9D9D9'u32, 0x24242424'u32, 0xB2B2B2B2'u32,
0x76767676'u32, 0x5B5B5B5B'u32, 0xA2A2A2A2'u32, 0x49494949'u32,
0x6D6D6D6D'u32, 0x8B8B8B8B'u32, 0xD1D1D1D1'u32, 0x25252525'u32,
0x72727272'u32, 0xF8F8F8F8'u32, 0xF6F6F6F6'u32, 0x64646464'u32,
0x86868686'u32, 0x68686868'u32, 0x98989898'u32, 0x16161616'u32,
0xD4D4D4D4'u32, 0xA4A4A4A4'u32, 0x5C5C5C5C'u32, 0xCCCCCCCC'u32,
0x5D5D5D5D'u32, 0x65656565'u32, 0xB6B6B6B6'u32, 0x92929292'u32,
0x6C6C6C6C'u32, 0x70707070'u32, 0x48484848'u32, 0x50505050'u32,
0xFDFDFDFD'u32, 0xEDEDEDED'u32, 0xB9B9B9B9'u32, 0xDADADADA'u32,
0x5E5E5E5E'u32, 0x15151515'u32, 0x46464646'u32, 0x57575757'u32,
0xA7A7A7A7'u32, 0x8D8D8D8D'u32, 0x9D9D9D9D'u32, 0x84848484'u32,
0x90909090'u32, 0xD8D8D8D8'u32, 0xABABABAB'u32, 0x00000000'u32,
0x8C8C8C8C'u32, 0xBCBCBCBC'u32, 0xD3D3D3D3'u32, 0x0A0A0A0A'u32,
0xF7F7F7F7'u32, 0xE4E4E4E4'u32, 0x58585858'u32, 0x05050505'u32,
0xB8B8B8B8'u32, 0xB3B3B3B3'u32, 0x45454545'u32, 0x06060606'u32,
0xD0D0D0D0'u32, 0x2C2C2C2C'u32, 0x1E1E1E1E'u32, 0x8F8F8F8F'u32,
0xCACACACA'u32, 0x3F3F3F3F'u32, 0x0F0F0F0F'u32, 0x02020202'u32,
0xC1C1C1C1'u32, 0xAFAFAFAF'u32, 0xBDBDBDBD'u32, 0x03030303'u32,
0x01010101'u32, 0x13131313'u32, 0x8A8A8A8A'u32, 0x6B6B6B6B'u32,
0x3A3A3A3A'u32, 0x91919191'u32, 0x11111111'u32, 0x41414141'u32,
0x4F4F4F4F'u32, 0x67676767'u32, 0xDCDCDCDC'u32, 0xEAEAEAEA'u32,
0x97979797'u32, 0xF2F2F2F2'u32, 0xCFCFCFCF'u32, 0xCECECECE'u32,
0xF0F0F0F0'u32, 0xB4B4B4B4'u32, 0xE6E6E6E6'u32, 0x73737373'u32,
0x96969696'u32, 0xACACACAC'u32, 0x74747474'u32, 0x22222222'u32,
0xE7E7E7E7'u32, 0xADADADAD'u32, 0x35353535'u32, 0x85858585'u32,
0xE2E2E2E2'u32, 0xF9F9F9F9'u32, 0x37373737'u32, 0xE8E8E8E8'u32,
0x1C1C1C1C'u32, 0x75757575'u32, 0xDFDFDFDF'u32, 0x6E6E6E6E'u32,
0x47474747'u32, 0xF1F1F1F1'u32, 0x1A1A1A1A'u32, 0x71717171'u32,
0x1D1D1D1D'u32, 0x29292929'u32, 0xC5C5C5C5'u32, 0x89898989'u32,
0x6F6F6F6F'u32, 0xB7B7B7B7'u32, 0x62626262'u32, 0x0E0E0E0E'u32,
0xAAAAAAAA'u32, 0x18181818'u32, 0xBEBEBEBE'u32, 0x1B1B1B1B'u32,
0xFCFCFCFC'u32, 0x56565656'u32, 0x3E3E3E3E'u32, 0x4B4B4B4B'u32,
0xC6C6C6C6'u32, 0xD2D2D2D2'u32, 0x79797979'u32, 0x20202020'u32,
0x9A9A9A9A'u32, 0xDBDBDBDB'u32, 0xC0C0C0C0'u32, 0xFEFEFEFE'u32,
0x78787878'u32, 0xCDCDCDCD'u32, 0x5A5A5A5A'u32, 0xF4F4F4F4'u32,
0x1F1F1F1F'u32, 0xDDDDDDDD'u32, 0xA8A8A8A8'u32, 0x33333333'u32,
0x88888888'u32, 0x07070707'u32, 0xC7C7C7C7'u32, 0x31313131'u32,
0xB1B1B1B1'u32, 0x12121212'u32, 0x10101010'u32, 0x59595959'u32,
0x27272727'u32, 0x80808080'u32, 0xECECECEC'u32, 0x5F5F5F5F'u32,
0x60606060'u32, 0x51515151'u32, 0x7F7F7F7F'u32, 0xA9A9A9A9'u32,
0x19191919'u32, 0xB5B5B5B5'u32, 0x4A4A4A4A'u32, 0x0D0D0D0D'u32,
0x2D2D2D2D'u32, 0xE5E5E5E5'u32, 0x7A7A7A7A'u32, 0x9F9F9F9F'u32,
0x93939393'u32, 0xC9C9C9C9'u32, 0x9C9C9C9C'u32, 0xEFEFEFEF'u32,
0xA0A0A0A0'u32, 0xE0E0E0E0'u32, 0x3B3B3B3B'u32, 0x4D4D4D4D'u32,
0xAEAEAEAE'u32, 0x2A2A2A2A'u32, 0xF5F5F5F5'u32, 0xB0B0B0B0'u32,
0xC8C8C8C8'u32, 0xEBEBEBEB'u32, 0xBBBBBBBB'u32, 0x3C3C3C3C'u32,
0x83838383'u32, 0x53535353'u32, 0x99999999'u32, 0x61616161'u32,
0x17171717'u32, 0x2B2B2B2B'u32, 0x04040404'u32, 0x7E7E7E7E'u32,
0xBABABABA'u32, 0x77777777'u32, 0xD6D6D6D6'u32, 0x26262626'u32,
0xE1E1E1E1'u32, 0x69696969'u32, 0x14141414'u32, 0x63636363'u32,
0x55555555'u32, 0x21212121'u32, 0x0C0C0C0C'u32, 0x7D7D7D7D'u32
]
rcon = [
0x01000000'u32, 0x02000000'u32, 0x04000000'u32, 0x08000000'u32,
0x10000000'u32, 0x20000000'u32, 0x40000000'u32, 0x80000000'u32,
0x1B000000'u32, 0x36000000'u32
]
template VSWAP(a, b) =
temp = a
a = b
b = temp
type
RijndaelContext[bits: static[uint]] = object
RKe: array[4 * (MaxNr + 1), uint32]
RKd: array[4 * (MaxNr + 1), uint32]
Nr: int
rijndael128* = RijndaelContext[128]
rijndael192* = RijndaelContext[192]
rijndael256* = RijndaelContext[256]
aes128* = rijndael128
aes192* = rijndael192
aes256* = rijndael256
rijndael* = rijndael128 | rijndael192 | rijndael256 | aes128 | aes192 | aes256
proc rijndaelKeySetupEnc(ctx: var RijndaelContext,
N: int, key: ptr byte): int =
ctx.RKe[0] = GETU32(key, 0)
ctx.RKe[1] = GETU32(key, 4)
ctx.RKe[2] = GETU32(key, 8)
ctx.RKe[3] = GETU32(key, 12)
var offset = 0
var i = 0
if N == 128:
while true:
var temp = ctx.RKe[offset + 3]
ctx.RKe[offset + 4] = ctx.RKe[offset] xor
(Te4[(temp shr 16) and 0xFF] and 0xFF000000'u32) xor
(Te4[(temp shr 8) and 0xFF] and 0x00FF0000'u32) xor
(Te4[temp and 0xFF] and 0x0000FF00'u32) xor
(Te4[temp shr 24] and 0x000000FF'u32) xor
rcon[i]
ctx.RKe[offset + 5] = ctx.RKe[offset + 1] xor ctx.RKe[offset + 4]
ctx.RKe[offset + 6] = ctx.RKe[offset + 2] xor ctx.RKe[offset + 5]
ctx.RKe[offset + 7] = ctx.RKe[offset + 3] xor ctx.RKe[offset + 6]
inc(i)
if i == 10:
result = 10
break
inc(offset, 4)
else:
ctx.RKe[offset + 4] = GETU32(key, 16)
ctx.RKe[offset + 5] = GETU32(key, 20)
if N == 192:
while true:
var temp = ctx.RKe[offset + 5]
ctx.RKe[offset + 6] = ctx.RKe[offset] xor
(Te4[(temp shr 16) and 0xFF] and 0xFF000000'u32) xor
(Te4[(temp shr 8) and 0xFF] and 0x00FF0000'u32) xor
(Te4[temp and 0xFF] and 0x0000FF00'u32) xor
(Te4[temp shr 24] and 0x000000FF'u32) xor
rcon[i]
ctx.RKe[offset + 7] = ctx.RKe[offset + 1] xor ctx.RKe[offset + 6]
ctx.RKe[offset + 8] = ctx.RKe[offset + 2] xor ctx.RKe[offset + 7]
ctx.RKe[offset + 9] = ctx.RKe[offset + 3] xor ctx.RKe[offset + 8]
inc(i)
if i == 8:
result = 12
break
ctx.RKe[offset + 10] = ctx.RKe[offset + 4] xor ctx.RKe[offset + 9]
ctx.RKe[offset + 11] = ctx.RKe[offset + 5] xor ctx.RKe[offset + 10]
inc(offset, 6)
else:
ctx.RKe[offset + 6] = GETU32(key, 24)
ctx.RKe[offset + 7] = GETU32(key, 28)
if N == 256:
while true:
var temp = ctx.RKe[offset + 7]
ctx.RKe[offset + 8] = ctx.RKe[offset] xor
(Te4[(temp shr 16) and 0xFF] and 0xFF000000'u32) xor
(Te4[(temp shr 8) and 0xFF] and 0x00FF0000'u32) xor
(Te4[temp and 0xFF] and 0x0000FF00'u32) xor
(Te4[temp shr 24] and 0x000000FF'u32) xor
rcon[i]
ctx.RKe[offset + 9] = ctx.RKe[offset + 1] xor ctx.RKe[offset + 8]
ctx.RKe[offset + 10] = ctx.RKe[offset + 2] xor ctx.RKe[offset + 9]
ctx.RKe[offset + 11] = ctx.RKe[offset + 3] xor ctx.RKe[offset + 10]
inc(i)
if i == 7:
result = 14
break
temp = ctx.RKe[offset + 11]
ctx.RKe[offset + 12] = ctx.RKe[offset + 4] xor
(Te4[(temp shr 24)] and 0xFF000000'u32) xor
(Te4[(temp shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Te4[(temp shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Te4[(temp) and 0xFF] and 0x000000FF'u32)
ctx.RKe[offset + 13] = ctx.RKe[offset + 5] xor ctx.RKe[offset + 12]
ctx.RKe[offset + 14] = ctx.RKe[offset + 6] xor ctx.RKe[offset + 13]
ctx.RKe[offset + 15] = ctx.RKe[offset + 7] xor ctx.RKe[offset + 14]
inc(offset, 8)
proc rijndaelKeySetupDec(ctx: var RijndaelContext, N: int,
key: ptr byte): int =
result = rijndaelKeySetupEnc(ctx, N, key)
ctx.RKd = ctx.RKe
var temp = 0'u32
var i = 0
var j = 4 * result
var offset = 0
while i < j:
VSWAP(ctx.RKd[i], ctx.RKd[j])
VSWAP(ctx.RKd[i + 1], ctx.RKd[j + 1])
VSWAP(ctx.RKd[i + 2], ctx.RKd[j + 2])
VSWAP(ctx.RKd[i + 3], ctx.RKd[j + 3])
inc(i, 4)
dec(j, 4)
i = 1
while i < result:
inc(offset, 4)
ctx.RKd[offset] =
Td0[Te4[(ctx.RKd[offset] shr 24)] and 0xFF] xor
Td1[Te4[(ctx.RKd[offset] shr 16) and 0xFF] and 0xFF] xor
Td2[Te4[(ctx.RKd[offset] shr 8) and 0xFF] and 0xFF] xor
Td3[Te4[(ctx.RKd[offset]) and 0xFF] and 0xFF]
ctx.RKd[offset + 1] =
Td0[Te4[(ctx.RKd[offset + 1] shr 24)] and 0xFF] xor
Td1[Te4[(ctx.RKd[offset + 1] shr 16) and 0xFF] and 0xFF] xor
Td2[Te4[(ctx.RKd[offset + 1] shr 8) and 0xFF] and 0xFF] xor
Td3[Te4[(ctx.RKd[offset + 1]) and 0xFF] and 0xFF]
ctx.RKd[offset + 2] =
Td0[Te4[(ctx.RKd[offset + 2] shr 24)] and 0xFF] xor
Td1[Te4[(ctx.RKd[offset + 2] shr 16) and 0xFF] and 0xFF] xor
Td2[Te4[(ctx.RKd[offset + 2] shr 8) and 0xFF] and 0xFF] xor
Td3[Te4[(ctx.RKd[offset + 2]) and 0xFF] and 0xFF]
ctx.RKd[offset + 3] =
Td0[Te4[(ctx.RKd[offset + 3] shr 24)] and 0xFF] xor
Td1[Te4[(ctx.RKd[offset + 3] shr 16) and 0xFF] and 0xFF] xor
Td2[Te4[(ctx.RKd[offset + 3] shr 8) and 0xFF] and 0xFF] xor
Td3[Te4[(ctx.RKd[offset + 3]) and 0xFF] and 0xFF]
inc(i)
template ENC_ROUND(D0, D1, D2, D3, S0, S1, S2, S3, RK, ROUND) =
D0 = Te0[S0 shr 24] xor
Te1[(S1 shr 16) and 0xFF] xor
Te2[(S2 shr 8) and 0xFF] xor
Te3[S3 and 0xFF] xor
RK[ROUND * 4]
D1 = Te0[S1 shr 24] xor
Te1[(S2 shr 16) and 0xFF] xor
Te2[(S3 shr 8) and 0xFF] xor
Te3[S0 and 0xFF] xor
RK[ROUND * 4 + 1]
D2 = Te0[S2 shr 24] xor
Te1[(S3 shr 16) and 0xFF] xor
Te2[(S0 shr 8) and 0xFF] xor
Te3[S1 and 0xFF] xor
RK[ROUND * 4 + 2]
D3 = Te0[S3 shr 24] xor
Te1[(S0 shr 16) and 0xFF] xor
Te2[(S1 shr 8) and 0xFF] xor
Te3[S2 and 0xFF] xor
RK[ROUND * 4 + 3]
template DEC_ROUND(D0, D1, D2, D3, S0, S1, S2, S3, RK, ROUND) =
D0 = Td0[S0 shr 24] xor
Td1[(S3 shr 16) and 0xFF] xor
Td2[(S2 shr 8) and 0xFF] xor
Td3[S1 and 0xFF] xor
RK[ROUND * 4]
D1 = Td0[S1 shr 24] xor
Td1[(S0 shr 16) and 0xFF] xor
Td2[(S3 shr 8) and 0xFF] xor
Td3[S2 and 0xFF] xor
RK[ROUND * 4 + 1]
D2 = Td0[S2 shr 24] xor
Td1[(S1 shr 16) and 0xFF] xor
Td2[(S0 shr 8) and 0xFF] xor
Td3[S3 and 0xFF] xor
RK[ROUND * 4 + 2]
D3 = Td0[S3 shr 24] xor
Td1[(S2 shr 16) and 0xFF] xor
Td2[(S1 shr 8) and 0xFF] xor
Td3[S0 and 0xFF] xor
RK[ROUND * 4 + 3]
proc rijndaelEncrypt*(ctx: var RijndaelContext, inp: ptr byte,
oup: ptr byte) =
var t0, t1, t2, t3: uint32
var s0 = GETU32(inp, 0) xor ctx.RKe[0]
var s1 = GETU32(inp, 4) xor ctx.RKe[1]
var s2 = GETU32(inp, 8) xor ctx.RKe[2]
var s3 = GETU32(inp, 12) xor ctx.RKe[3]
ENC_ROUND(t0, t1, t2 ,t3, s0, s1, s2, s3, ctx.RKe, 1)
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 2)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 3)
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 4)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 5)
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 6)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 7)
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 8)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 9)
if ctx.Nr > 10:
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 10)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 11)
if ctx.Nr > 12:
ENC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKe, 12)
ENC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKe, 13)
let offset = (ctx.Nr shl 2).uint32
s0 = (Te4[(t0 shr 24)] and 0xFF000000'u32) xor
(Te4[(t1 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Te4[(t2 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Te4[t3 and 0xFF] and 0x000000FF'u32) xor
ctx.RKe[offset]
s1 = (Te4[(t1 shr 24)] and 0xFF000000'u32) xor
(Te4[(t2 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Te4[(t3 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Te4[t0 and 0xFF] and 0x000000FF'u32) xor
ctx.RKe[offset + 1]
s2 = (Te4[(t2 shr 24)] and 0xFF000000'u32) xor
(Te4[(t3 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Te4[(t0 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Te4[t1 and 0xFF] and 0x000000FF'u32) xor
ctx.RKe[offset + 2]
s3 = (Te4[(t3 shr 24)] and 0xFF000000'u32) xor
(Te4[(t0 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Te4[(t1 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Te4[t2 and 0xFF] and 0x000000FF'u32) xor
ctx.RKe[offset + 3]
PUTU32(oup, 0, s0)
PUTU32(oup, 4, s1)
PUTU32(oup, 8, s2)
PUTU32(oup, 12, s3)
proc rijndaelDecrypt*(ctx: var RijndaelContext, inp: ptr byte,
oup: ptr byte) =
var t0, t1, t2, t3: uint32
var s0 = GETU32(inp, 0) xor ctx.RKd[0]
var s1 = GETU32(inp, 4) xor ctx.RKd[1]
var s2 = GETU32(inp, 8) xor ctx.RKd[2]
var s3 = GETU32(inp, 12) xor ctx.RKd[3]
DEC_ROUND(t0, t1, t2 ,t3, s0, s1, s2, s3, ctx.RKd, 1)
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 2)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 3)
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 4)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 5)
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 6)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 7)
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 8)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 9)
if ctx.Nr > 10:
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 10)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 11)
if ctx.Nr > 12:
DEC_ROUND(s0, s1, s2, s3, t0, t1, t2, t3, ctx.RKd, 12)
DEC_ROUND(t0, t1, t2, t3, s0, s1, s2, s3, ctx.RKd, 13)
let offset = (ctx.Nr shl 2).uint32
s0 = (Td4[(t0 shr 24)] and 0xFF000000'u32) xor
(Td4[(t3 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Td4[(t2 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Td4[t1 and 0xFF] and 0x000000FF'u32) xor
ctx.RKd[offset]
s1 = (Td4[(t1 shr 24)] and 0xFF000000'u32) xor
(Td4[(t0 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Td4[(t3 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Td4[t2 and 0xFF] and 0x000000FF'u32) xor
ctx.RKd[offset + 1]
s2 = (Td4[(t2 shr 24)] and 0xFF000000'u32) xor
(Td4[(t1 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Td4[(t0 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Td4[t3 and 0xFF] and 0x000000FF'u32) xor
ctx.RKd[offset + 2]
s3 = (Td4[(t3 shr 24)] and 0xFF000000'u32) xor
(Td4[(t2 shr 16) and 0xFF] and 0x00FF0000'u32) xor
(Td4[(t1 shr 8) and 0xFF] and 0x0000FF00'u32) xor
(Td4[t0 and 0xFF] and 0x000000FF'u32) xor
ctx.RKd[offset + 3]
PUTU32(oup, 0, s0)
PUTU32(oup, 4, s1)
PUTU32(oup, 8, s2)
PUTU32(oup, 12, s3)
proc initRijndaelContext*(ctx: var RijndaelContext, N: int, key: ptr byte) =
ctx.Nr = rijndaelKeySetupDec(ctx, N, key)
template sizeKey*(ctx: RijndaelContext): int =
(ctx.bits div 8)
template sizeBlock*(ctx: RijndaelContext): int =
(16)
template sizeKey*(r: typedesc[rijndael]): int =
when r is aes128 or r is rijndael128:
(16)
elif r is aes192 or r is rijndael192:
(24)
elif r is aes256 or r is rijndael256:
(32)
template sizeBlock*(r: typedesc[rijndael]): int =
(16)
proc init*(ctx: var RijndaelContext, key: ptr byte, nkey: int = 0) {.inline.} =
ctx.Nr = rijndaelKeySetupDec(ctx, ctx.bits, key)
proc init*(ctx: var RijndaelContext, key: openarray[byte]) {.inline.} =
assert(len(key) >= ctx.sizeKey)
ctx.Nr = rijndaelKeySetupDec(ctx, ctx.bits, unsafeAddr key[0])
proc clear*(ctx: var RijndaelContext) {.inline.} =
burnMem(ctx)
proc encrypt*(ctx: var RijndaelContext, inbytes: ptr byte,
outbytes: ptr byte) {.inline.} =
rijndaelEncrypt(ctx, inbytes, outbytes)
proc decrypt*(ctx: var RijndaelContext, inbytes: ptr byte,
outbytes: ptr byte) {.inline.} =
rijndaelDecrypt(ctx, inbytes, outbytes)
proc encrypt*(ctx: var RijndaelContext, input: openarray[byte],
output: var openarray[byte]) {.inline.} =
assert(len(input) == ctx.sizeBlock)
assert(len(input) <= len(output))
rijndaelEncrypt(ctx, unsafeAddr input[0], addr output[0])
proc decrypt*(ctx: var RijndaelContext, input: openarray[byte],
output: var openarray[byte]) {.inline.} =
assert(len(input) == ctx.sizeBlock)
assert(len(input) <= len(output))
rijndaelDecrypt(ctx, unsafeAddr input[0], addr output[0])