Cipher.cpp 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. // AES requires 16-byte alignment due to _mm_* operations
  4. #define AES_SMALL_CODE 1 // 1=faster (0=0.211s, 1=0.207s)
  5. #if ((defined _M_IX86 || defined __i386__) || (defined _M_X64 || defined __x86_64__)) && !ANDROID && !IOS_SIMULATOR
  6. #define AES_CPU 1
  7. #else
  8. #define AES_CPU 0
  9. #endif
  10. #if MAC
  11. #define AES_ATTR __attribute__((target("aes")))
  12. #elif LINUX
  13. #define AES_ATTR __attribute__((target("aes,sse4.1")))
  14. #else
  15. #define AES_ATTR
  16. #endif
  17. /******************************************************************************/
  18. namespace EE{
  19. #if 0
  20. /******************************************************************************/
  21. // CIPHER 0
  22. /******************************************************************************/
  23. struct Cipher0 : Cipher // Memory De/Encryption Implementation
  24. {
  25. Byte key[32]; // key
  26. virtual void encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)override; // encrypt 'src' data into 'dest' of 'size' bytes, 'offset'=offset of source data in the stream
  27. virtual void decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)override; // decrypt 'src' data into 'dest' of 'size' bytes, 'offset'=offset of source data in the stream
  28. virtual void randomizeKey( ) override;
  29. virtual Bool saveKey(File &f)C override; // save key into 'f' file, return false on fail
  30. virtual Bool loadKey(File &f) override; // load key from 'f' file, return false on fail
  31. virtual Bool mixKey(File &f) override; // mix current key with the key stored in 'f' file, operation should be symmetrical (it should provide the same results as if the keys were swapped - key from file was mixed with current key), return false on fail
  32. Cipher0();
  33. Cipher0(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09,
  34. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19,
  35. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29,
  36. Byte k30, Byte k31);
  37. };
  38. Cipher0::Cipher0()
  39. {
  40. Zero(key);
  41. }
  42. Cipher0::Cipher0(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09,
  43. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19,
  44. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29,
  45. Byte k30, Byte k31)
  46. {
  47. key[ 0]=k00; key[ 1]=k01; key[ 2]=k02; key[ 3]=k03; key[ 4]=k04; key[ 5]=k05; key[ 6]=k06; key[ 7]=k07; key[ 8]=k08; key[ 9]=k09;
  48. key[10]=k10; key[11]=k11; key[12]=k12; key[13]=k13; key[14]=k14; key[15]=k15; key[16]=k16; key[17]=k17; key[18]=k18; key[19]=k19;
  49. key[20]=k20; key[21]=k21; key[22]=k22; key[23]=k23; key[24]=k24; key[25]=k25; key[26]=k26; key[27]=k27; key[28]=k28; key[29]=k29;
  50. key[30]=k30; key[31]=k31;
  51. }
  52. /******************************************************************************/
  53. void Cipher0::randomizeKey()
  54. {
  55. UID uid[SIZE(key)/SIZE(UID)]; REPAO(uid).randomize(); // 'UID.randomize' uses a more secure version than 'Random'
  56. ASSERT(SIZE(uid)==SIZE(key)); CopyFast(key, uid, SIZE(key));
  57. }
  58. Bool Cipher0::saveKey(File &f)C {f<<key; return f.ok();}
  59. Bool Cipher0::loadKey(File &f) {f>>key; return f.ok();}
  60. Bool Cipher0:: mixKey(File &f) {Byte temp[SIZE(key)]; f>>temp; REPAO(key)^=temp[i]; return f.ok();}
  61. /******************************************************************************/
  62. #pragma runtime_checks("", off)
  63. void Cipher0::encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  64. {
  65. if(Byte *d=(Byte*)dest)
  66. {
  67. if(Byte *s=(Byte*)src)
  68. {
  69. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  70. {
  71. offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++;
  72. offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++;
  73. offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++;
  74. offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++;
  75. }
  76. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  77. {
  78. case 3: offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++; // !! no break on purpose !!
  79. case 2: offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; offset++; // !! no break on purpose !!
  80. case 1: offset&=15; *d++=((*s++)+key[offset])^key[offset+16]; //offset++; // !! no break on purpose !!
  81. }
  82. }else
  83. {
  84. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  85. {
  86. offset&=15; *d++=key[offset]^key[offset+16]; offset++;
  87. offset&=15; *d++=key[offset]^key[offset+16]; offset++;
  88. offset&=15; *d++=key[offset]^key[offset+16]; offset++;
  89. offset&=15; *d++=key[offset]^key[offset+16]; offset++;
  90. }
  91. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  92. {
  93. case 3: offset&=15; *d++=key[offset]^key[offset+16]; offset++; // !! no break on purpose !!
  94. case 2: offset&=15; *d++=key[offset]^key[offset+16]; offset++; // !! no break on purpose !!
  95. case 1: offset&=15; *d++=key[offset]^key[offset+16]; //offset++; // !! no break on purpose !!
  96. }
  97. }
  98. }
  99. }
  100. void Cipher0::decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  101. {
  102. if(Byte *d=(Byte*)dest)
  103. {
  104. if(Byte *s=(Byte*)src)
  105. {
  106. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  107. {
  108. offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++;
  109. offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++;
  110. offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++;
  111. offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++;
  112. }
  113. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  114. {
  115. case 3: offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++; // !! no break on purpose !!
  116. case 2: offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; offset++; // !! no break on purpose !!
  117. case 1: offset&=15; *d++=((*s++)^key[offset+16])-key[offset]; //offset++; // !! no break on purpose !!
  118. }
  119. }else
  120. {
  121. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  122. {
  123. offset&=15; *d++=key[offset+16]-key[offset]; offset++;
  124. offset&=15; *d++=key[offset+16]-key[offset]; offset++;
  125. offset&=15; *d++=key[offset+16]-key[offset]; offset++;
  126. offset&=15; *d++=key[offset+16]-key[offset]; offset++;
  127. }
  128. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  129. {
  130. case 3: offset&=15; *d++=key[offset+16]-key[offset]; offset++; // !! no break on purpose !!
  131. case 2: offset&=15; *d++=key[offset+16]-key[offset]; offset++; // !! no break on purpose !!
  132. case 1: offset&=15; *d++=key[offset+16]-key[offset]; //offset++; // !! no break on purpose !!
  133. }
  134. }
  135. }
  136. }
  137. #pragma runtime_checks("", restore)
  138. /******************************************************************************/
  139. // CIPHER 0A
  140. /******************************************************************************/
  141. struct Cipher0A : Cipher
  142. {
  143. void setKey(C Byte *key, Int key_size); // set key from 'key' array of 'key_size' bytes ('key_size' can be any size, but only up to first 256 bytes will be used)
  144. #if EE_PRIVATE
  145. void wrapKey();
  146. #endif
  147. virtual void encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)override; // encrypt 'src' data into 'dest' of 'size' bytes, 'offset'=offset of source data in the stream
  148. virtual void decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)override; // decrypt 'src' data into 'dest' of 'size' bytes, 'offset'=offset of source data in the stream
  149. virtual void randomizeKey( ) override;
  150. virtual Bool saveKey(File &f)C override; // save key into 'f' file, return false on fail
  151. virtual Bool loadKey(File &f) override; // load key from 'f' file, return false on fail
  152. virtual Bool mixKey(File &f) override; // mix current key with the key stored in 'f' file, operation should be symmetrical (it should provide the same results as if the keys were swapped - key from file was mixed with current key), return false on fail
  153. Cipher0A();
  154. Cipher0A(C Byte *key, Int key_size) {setKey(key, key_size);}
  155. Cipher0A(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09, Byte k0A, Byte k0B, Byte k0C, Byte k0D, Byte k0E, Byte k0F,
  156. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19, Byte k1A, Byte k1B, Byte k1C, Byte k1D, Byte k1E, Byte k1F,
  157. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29, Byte k2A, Byte k2B, Byte k2C, Byte k2D, Byte k2E, Byte k2F,
  158. Byte k30, Byte k31, Byte k32, Byte k33, Byte k34, Byte k35, Byte k36, Byte k37, Byte k38, Byte k39, Byte k3A, Byte k3B, Byte k3C, Byte k3D, Byte k3E, Byte k3F,
  159. Byte k40, Byte k41, Byte k42, Byte k43, Byte k44, Byte k45, Byte k46, Byte k47, Byte k48, Byte k49, Byte k4A, Byte k4B, Byte k4C, Byte k4D, Byte k4E, Byte k4F,
  160. Byte k50, Byte k51, Byte k52, Byte k53, Byte k54, Byte k55, Byte k56, Byte k57, Byte k58, Byte k59, Byte k5A, Byte k5B, Byte k5C, Byte k5D, Byte k5E, Byte k5F,
  161. Byte k60, Byte k61, Byte k62, Byte k63, Byte k64, Byte k65, Byte k66, Byte k67, Byte k68, Byte k69, Byte k6A, Byte k6B, Byte k6C, Byte k6D, Byte k6E, Byte k6F,
  162. Byte k70, Byte k71, Byte k72, Byte k73, Byte k74, Byte k75, Byte k76, Byte k77, Byte k78, Byte k79, Byte k7A, Byte k7B, Byte k7C, Byte k7D, Byte k7E, Byte k7F,
  163. Byte k80, Byte k81, Byte k82, Byte k83, Byte k84, Byte k85, Byte k86, Byte k87, Byte k88, Byte k89, Byte k8A, Byte k8B, Byte k8C, Byte k8D, Byte k8E, Byte k8F,
  164. Byte k90, Byte k91, Byte k92, Byte k93, Byte k94, Byte k95, Byte k96, Byte k97, Byte k98, Byte k99, Byte k9A, Byte k9B, Byte k9C, Byte k9D, Byte k9E, Byte k9F,
  165. Byte kA0, Byte kA1, Byte kA2, Byte kA3, Byte kA4, Byte kA5, Byte kA6, Byte kA7, Byte kA8, Byte kA9, Byte kAA, Byte kAB, Byte kAC, Byte kAD, Byte kAE, Byte kAF,
  166. Byte kB0, Byte kB1, Byte kB2, Byte kB3, Byte kB4, Byte kB5, Byte kB6, Byte kB7, Byte kB8, Byte kB9, Byte kBA, Byte kBB, Byte kBC, Byte kBD, Byte kBE, Byte kBF,
  167. Byte kC0, Byte kC1, Byte kC2, Byte kC3, Byte kC4, Byte kC5, Byte kC6, Byte kC7, Byte kC8, Byte kC9, Byte kCA, Byte kCB, Byte kCC, Byte kCD, Byte kCE, Byte kCF,
  168. Byte kD0, Byte kD1, Byte kD2, Byte kD3, Byte kD4, Byte kD5, Byte kD6, Byte kD7, Byte kD8, Byte kD9, Byte kDA, Byte kDB, Byte kDC, Byte kDD, Byte kDE, Byte kDF,
  169. Byte kE0, Byte kE1, Byte kE2, Byte kE3, Byte kE4, Byte kE5, Byte kE6, Byte kE7, Byte kE8, Byte kE9, Byte kEA, Byte kEB, Byte kEC, Byte kED, Byte kEE, Byte kEF,
  170. Byte kF0, Byte kF1, Byte kF2, Byte kF3, Byte kF4, Byte kF5, Byte kF6, Byte kF7, Byte kF8, Byte kF9, Byte kFA, Byte kFB, Byte kFC, Byte kFD, Byte kFE, Byte kFF);
  171. private:
  172. Byte _key[256+4];
  173. };
  174. Cipher0A::Cipher0A()
  175. {
  176. Zero(_key);
  177. }
  178. Cipher0A::Cipher0A(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09, Byte k0A, Byte k0B, Byte k0C, Byte k0D, Byte k0E, Byte k0F,
  179. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19, Byte k1A, Byte k1B, Byte k1C, Byte k1D, Byte k1E, Byte k1F,
  180. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29, Byte k2A, Byte k2B, Byte k2C, Byte k2D, Byte k2E, Byte k2F,
  181. Byte k30, Byte k31, Byte k32, Byte k33, Byte k34, Byte k35, Byte k36, Byte k37, Byte k38, Byte k39, Byte k3A, Byte k3B, Byte k3C, Byte k3D, Byte k3E, Byte k3F,
  182. Byte k40, Byte k41, Byte k42, Byte k43, Byte k44, Byte k45, Byte k46, Byte k47, Byte k48, Byte k49, Byte k4A, Byte k4B, Byte k4C, Byte k4D, Byte k4E, Byte k4F,
  183. Byte k50, Byte k51, Byte k52, Byte k53, Byte k54, Byte k55, Byte k56, Byte k57, Byte k58, Byte k59, Byte k5A, Byte k5B, Byte k5C, Byte k5D, Byte k5E, Byte k5F,
  184. Byte k60, Byte k61, Byte k62, Byte k63, Byte k64, Byte k65, Byte k66, Byte k67, Byte k68, Byte k69, Byte k6A, Byte k6B, Byte k6C, Byte k6D, Byte k6E, Byte k6F,
  185. Byte k70, Byte k71, Byte k72, Byte k73, Byte k74, Byte k75, Byte k76, Byte k77, Byte k78, Byte k79, Byte k7A, Byte k7B, Byte k7C, Byte k7D, Byte k7E, Byte k7F,
  186. Byte k80, Byte k81, Byte k82, Byte k83, Byte k84, Byte k85, Byte k86, Byte k87, Byte k88, Byte k89, Byte k8A, Byte k8B, Byte k8C, Byte k8D, Byte k8E, Byte k8F,
  187. Byte k90, Byte k91, Byte k92, Byte k93, Byte k94, Byte k95, Byte k96, Byte k97, Byte k98, Byte k99, Byte k9A, Byte k9B, Byte k9C, Byte k9D, Byte k9E, Byte k9F,
  188. Byte kA0, Byte kA1, Byte kA2, Byte kA3, Byte kA4, Byte kA5, Byte kA6, Byte kA7, Byte kA8, Byte kA9, Byte kAA, Byte kAB, Byte kAC, Byte kAD, Byte kAE, Byte kAF,
  189. Byte kB0, Byte kB1, Byte kB2, Byte kB3, Byte kB4, Byte kB5, Byte kB6, Byte kB7, Byte kB8, Byte kB9, Byte kBA, Byte kBB, Byte kBC, Byte kBD, Byte kBE, Byte kBF,
  190. Byte kC0, Byte kC1, Byte kC2, Byte kC3, Byte kC4, Byte kC5, Byte kC6, Byte kC7, Byte kC8, Byte kC9, Byte kCA, Byte kCB, Byte kCC, Byte kCD, Byte kCE, Byte kCF,
  191. Byte kD0, Byte kD1, Byte kD2, Byte kD3, Byte kD4, Byte kD5, Byte kD6, Byte kD7, Byte kD8, Byte kD9, Byte kDA, Byte kDB, Byte kDC, Byte kDD, Byte kDE, Byte kDF,
  192. Byte kE0, Byte kE1, Byte kE2, Byte kE3, Byte kE4, Byte kE5, Byte kE6, Byte kE7, Byte kE8, Byte kE9, Byte kEA, Byte kEB, Byte kEC, Byte kED, Byte kEE, Byte kEF,
  193. Byte kF0, Byte kF1, Byte kF2, Byte kF3, Byte kF4, Byte kF5, Byte kF6, Byte kF7, Byte kF8, Byte kF9, Byte kFA, Byte kFB, Byte kFC, Byte kFD, Byte kFE, Byte kFF)
  194. {
  195. Byte k[]={
  196. k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F,
  197. k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F,
  198. k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F,
  199. k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F,
  200. k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F,
  201. k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k5A, k5B, k5C, k5D, k5E, k5F,
  202. k60, k61, k62, k63, k64, k65, k66, k67, k68, k69, k6A, k6B, k6C, k6D, k6E, k6F,
  203. k70, k71, k72, k73, k74, k75, k76, k77, k78, k79, k7A, k7B, k7C, k7D, k7E, k7F,
  204. k80, k81, k82, k83, k84, k85, k86, k87, k88, k89, k8A, k8B, k8C, k8D, k8E, k8F,
  205. k90, k91, k92, k93, k94, k95, k96, k97, k98, k99, k9A, k9B, k9C, k9D, k9E, k9F,
  206. kA0, kA1, kA2, kA3, kA4, kA5, kA6, kA7, kA8, kA9, kAA, kAB, kAC, kAD, kAE, kAF,
  207. kB0, kB1, kB2, kB3, kB4, kB5, kB6, kB7, kB8, kB9, kBA, kBB, kBC, kBD, kBE, kBF,
  208. kC0, kC1, kC2, kC3, kC4, kC5, kC6, kC7, kC8, kC9, kCA, kCB, kCC, kCD, kCE, kCF,
  209. kD0, kD1, kD2, kD3, kD4, kD5, kD6, kD7, kD8, kD9, kDA, kDB, kDC, kDD, kDE, kDF,
  210. kE0, kE1, kE2, kE3, kE4, kE5, kE6, kE7, kE8, kE9, kEA, kEB, kEC, kED, kEE, kEF,
  211. kF0, kF1, kF2, kF3, kF4, kF5, kF6, kF7, kF8, kF9, kFA, kFB, kFC, kFD, kFE, kFF,
  212. };
  213. setKey((Byte*)k, SIZE(k));
  214. }
  215. void Cipher0A::setKey(C Byte *key, Int key_size)
  216. {
  217. if(key && key_size>0)
  218. {
  219. for(Int pos=0; pos<256; )
  220. {
  221. Int copy=Min(256-pos, key_size);
  222. CopyFast(_key+pos, key, copy);
  223. pos+=copy;
  224. }
  225. wrapKey();
  226. }else Zero(_key);
  227. }
  228. void Cipher0A::wrapKey()
  229. {
  230. _key[256+0]=_key[0];
  231. _key[256+1]=_key[1];
  232. _key[256+2]=_key[2];
  233. _key[256+3]=_key[3];
  234. }
  235. /******************************************************************************/
  236. void Cipher0A::randomizeKey()
  237. {
  238. UID uid[256/SIZE(UID)]; REPAO(uid).randomize(); // 'UID.randomize' uses a more secure version than 'Random'
  239. setKey(uid[0].b, SIZE(uid));
  240. }
  241. Bool Cipher0A::saveKey(File &f)C {return f.put(_key, 256);}
  242. Bool Cipher0A::loadKey(File &f) {Bool ok=f.get(_key, 256); wrapKey(); return ok;}
  243. Bool Cipher0A:: mixKey(File &f) {Byte temp[256]; f>>temp; REP(256)_key[i]^=temp[i]; wrapKey(); return f.ok();}
  244. /******************************************************************************/
  245. #pragma runtime_checks("", off)
  246. void Cipher0A::encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  247. {
  248. if(Byte *d=(Byte*)dest)
  249. {
  250. if(Byte *s=(Byte*)src)
  251. {
  252. offset&=255;
  253. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  254. {
  255. *d++=((*s++)+_key[offset+0])^_key[offset+1];
  256. *d++=((*s++)+_key[offset+1])^_key[offset+2];
  257. *d++=((*s++)+_key[offset+2])^_key[offset+3];
  258. *d++=((*s++)+_key[offset+3])^_key[offset+4];
  259. offset+=4; offset&=255;
  260. }
  261. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  262. {
  263. case 3: *d++=((*s++)+_key[offset+0])^_key[offset+1]; offset++; // !! no break on purpose !!
  264. case 2: *d++=((*s++)+_key[offset+0])^_key[offset+1]; offset++; // !! no break on purpose !!
  265. case 1: *d++=((*s++)+_key[offset+0])^_key[offset+1]; //offset++; // !! no break on purpose !!
  266. }
  267. }else
  268. {
  269. offset&=255;
  270. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  271. {
  272. *d++=_key[offset+0]^_key[offset+1];
  273. *d++=_key[offset+1]^_key[offset+2];
  274. *d++=_key[offset+2]^_key[offset+3];
  275. *d++=_key[offset+3]^_key[offset+4];
  276. offset+=4; offset&=255;
  277. }
  278. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  279. {
  280. case 3: *d++=_key[offset+0]^_key[offset+1]; offset++; // !! no break on purpose !!
  281. case 2: *d++=_key[offset+0]^_key[offset+1]; offset++; // !! no break on purpose !!
  282. case 1: *d++=_key[offset+0]^_key[offset+1]; //offset++; // !! no break on purpose !!
  283. }
  284. }
  285. }
  286. }
  287. void Cipher0A::decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  288. {
  289. if(Byte *d=(Byte*)dest)
  290. {
  291. if(Byte *s=(Byte*)src)
  292. {
  293. offset&=255;
  294. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  295. {
  296. *d++=((*s++)^_key[offset+1])-_key[offset+0];
  297. *d++=((*s++)^_key[offset+2])-_key[offset+1];
  298. *d++=((*s++)^_key[offset+3])-_key[offset+2];
  299. *d++=((*s++)^_key[offset+4])-_key[offset+3];
  300. offset+=4; offset&=255;
  301. }
  302. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  303. {
  304. case 3: *d++=((*s++)^_key[offset+1])-_key[offset+0]; offset++; // !! no break on purpose !!
  305. case 2: *d++=((*s++)^_key[offset+1])-_key[offset+0]; offset++; // !! no break on purpose !!
  306. case 1: *d++=((*s++)^_key[offset+1])-_key[offset+0]; //offset++; // !! no break on purpose !!
  307. }
  308. }else
  309. {
  310. offset&=255;
  311. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  312. {
  313. *d++=_key[offset+1]-_key[offset+0];
  314. *d++=_key[offset+2]-_key[offset+1];
  315. *d++=_key[offset+3]-_key[offset+2];
  316. *d++=_key[offset+4]-_key[offset+3];
  317. offset+=4; offset&=255;
  318. }
  319. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  320. {
  321. case 3: *d++=_key[offset+1]-_key[offset+0]; offset++; // !! no break on purpose !!
  322. case 2: *d++=_key[offset+1]-_key[offset+0]; offset++; // !! no break on purpose !!
  323. case 1: *d++=_key[offset+1]-_key[offset+0]; //offset++; // !! no break on purpose !!
  324. }
  325. }
  326. }
  327. }
  328. #pragma runtime_checks("", restore)
  329. #endif
  330. /******************************************************************************/
  331. // CIPHER 1
  332. /******************************************************************************/
  333. Cipher1::Cipher1() {setKey(null, 0);}
  334. Cipher1& Cipher1::setKey(C Byte *key, Int key_size)
  335. {
  336. if(key && key_size>0)
  337. {
  338. REP(256)_enc[i]=i;
  339. FREP(255) // RandomizeOrder based on 'key'
  340. {
  341. Byte k=key[UInt(i)%UInt(key_size)]; // unsigned div is slightly faster
  342. UInt left=256-i;
  343. Swap(_enc[i], _enc[i+k%left]);
  344. }
  345. setDec();
  346. }else
  347. {
  348. REP(256)_enc[i]=i;
  349. REP(256)_dec[i]=i;
  350. }
  351. wrapKey();
  352. return T;
  353. }
  354. void Cipher1::wrapKey()
  355. {
  356. _enc[256+0]=_enc[0];
  357. _enc[256+1]=_enc[1];
  358. _enc[256+2]=_enc[2];
  359. _enc[256+3]=_enc[3];
  360. _dec[256+0]=_dec[0];
  361. _dec[256+1]=_dec[1];
  362. _dec[256+2]=_dec[2];
  363. _dec[256+3]=_dec[3];
  364. }
  365. Cipher1::Cipher1(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09, Byte k0A, Byte k0B, Byte k0C, Byte k0D, Byte k0E, Byte k0F,
  366. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19, Byte k1A, Byte k1B, Byte k1C, Byte k1D, Byte k1E, Byte k1F,
  367. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29, Byte k2A, Byte k2B, Byte k2C, Byte k2D, Byte k2E, Byte k2F,
  368. Byte k30, Byte k31, Byte k32, Byte k33, Byte k34, Byte k35, Byte k36, Byte k37, Byte k38, Byte k39, Byte k3A, Byte k3B, Byte k3C, Byte k3D, Byte k3E, Byte k3F,
  369. Byte k40, Byte k41, Byte k42, Byte k43, Byte k44, Byte k45, Byte k46, Byte k47, Byte k48, Byte k49, Byte k4A, Byte k4B, Byte k4C, Byte k4D, Byte k4E, Byte k4F,
  370. Byte k50, Byte k51, Byte k52, Byte k53, Byte k54, Byte k55, Byte k56, Byte k57, Byte k58, Byte k59, Byte k5A, Byte k5B, Byte k5C, Byte k5D, Byte k5E, Byte k5F,
  371. Byte k60, Byte k61, Byte k62, Byte k63, Byte k64, Byte k65, Byte k66, Byte k67, Byte k68, Byte k69, Byte k6A, Byte k6B, Byte k6C, Byte k6D, Byte k6E, Byte k6F,
  372. Byte k70, Byte k71, Byte k72, Byte k73, Byte k74, Byte k75, Byte k76, Byte k77, Byte k78, Byte k79, Byte k7A, Byte k7B, Byte k7C, Byte k7D, Byte k7E, Byte k7F,
  373. Byte k80, Byte k81, Byte k82, Byte k83, Byte k84, Byte k85, Byte k86, Byte k87, Byte k88, Byte k89, Byte k8A, Byte k8B, Byte k8C, Byte k8D, Byte k8E, Byte k8F,
  374. Byte k90, Byte k91, Byte k92, Byte k93, Byte k94, Byte k95, Byte k96, Byte k97, Byte k98, Byte k99, Byte k9A, Byte k9B, Byte k9C, Byte k9D, Byte k9E, Byte k9F,
  375. Byte kA0, Byte kA1, Byte kA2, Byte kA3, Byte kA4, Byte kA5, Byte kA6, Byte kA7, Byte kA8, Byte kA9, Byte kAA, Byte kAB, Byte kAC, Byte kAD, Byte kAE, Byte kAF,
  376. Byte kB0, Byte kB1, Byte kB2, Byte kB3, Byte kB4, Byte kB5, Byte kB6, Byte kB7, Byte kB8, Byte kB9, Byte kBA, Byte kBB, Byte kBC, Byte kBD, Byte kBE, Byte kBF,
  377. Byte kC0, Byte kC1, Byte kC2, Byte kC3, Byte kC4, Byte kC5, Byte kC6, Byte kC7, Byte kC8, Byte kC9, Byte kCA, Byte kCB, Byte kCC, Byte kCD, Byte kCE, Byte kCF,
  378. Byte kD0, Byte kD1, Byte kD2, Byte kD3, Byte kD4, Byte kD5, Byte kD6, Byte kD7, Byte kD8, Byte kD9, Byte kDA, Byte kDB, Byte kDC, Byte kDD, Byte kDE, Byte kDF,
  379. Byte kE0, Byte kE1, Byte kE2, Byte kE3, Byte kE4, Byte kE5, Byte kE6, Byte kE7, Byte kE8, Byte kE9, Byte kEA, Byte kEB, Byte kEC, Byte kED, Byte kEE, Byte kEF,
  380. Byte kF0, Byte kF1, Byte kF2, Byte kF3, Byte kF4, Byte kF5, Byte kF6, Byte kF7, Byte kF8, Byte kF9, Byte kFA, Byte kFB, Byte kFC, Byte kFD, Byte kFE, Byte kFF)
  381. {
  382. Byte k[]={
  383. k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F,
  384. k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F,
  385. k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F,
  386. k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F,
  387. k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F,
  388. k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k5A, k5B, k5C, k5D, k5E, k5F,
  389. k60, k61, k62, k63, k64, k65, k66, k67, k68, k69, k6A, k6B, k6C, k6D, k6E, k6F,
  390. k70, k71, k72, k73, k74, k75, k76, k77, k78, k79, k7A, k7B, k7C, k7D, k7E, k7F,
  391. k80, k81, k82, k83, k84, k85, k86, k87, k88, k89, k8A, k8B, k8C, k8D, k8E, k8F,
  392. k90, k91, k92, k93, k94, k95, k96, k97, k98, k99, k9A, k9B, k9C, k9D, k9E, k9F,
  393. kA0, kA1, kA2, kA3, kA4, kA5, kA6, kA7, kA8, kA9, kAA, kAB, kAC, kAD, kAE, kAF,
  394. kB0, kB1, kB2, kB3, kB4, kB5, kB6, kB7, kB8, kB9, kBA, kBB, kBC, kBD, kBE, kBF,
  395. kC0, kC1, kC2, kC3, kC4, kC5, kC6, kC7, kC8, kC9, kCA, kCB, kCC, kCD, kCE, kCF,
  396. kD0, kD1, kD2, kD3, kD4, kD5, kD6, kD7, kD8, kD9, kDA, kDB, kDC, kDD, kDE, kDF,
  397. kE0, kE1, kE2, kE3, kE4, kE5, kE6, kE7, kE8, kE9, kEA, kEB, kEC, kED, kEE, kEF,
  398. kF0, kF1, kF2, kF3, kF4, kF5, kF6, kF7, kF8, kF9, kFA, kFB, kFC, kFD, kFE, kFF,
  399. };
  400. setKey((Byte*)k, SIZE(k));
  401. }
  402. void Cipher1::setDec()
  403. {
  404. REP(256)_dec[_enc[i]]=i;
  405. }
  406. /******************************************************************************/
  407. void Cipher1::randomizeKey()
  408. {
  409. UID uid[256/SIZE(UID)]; REPAO(uid).randomize(); // 'UID.randomize' uses a more secure version than 'Random'
  410. setKey(uid[0].b, SIZE(uid));
  411. }
  412. Bool Cipher1::saveKey(File &f)C {return f.put(_enc, 256);}
  413. Bool Cipher1::loadKey(File &f) {Bool ok=f.get(_enc, 256); setDec(); wrapKey(); return ok;}
  414. Bool Cipher1:: mixKey(File &f) {Byte temp[256]; f>>temp; REPAO(temp)^=_enc[i]; setKey(temp, Elms(temp)); return f.ok();}
  415. /******************************************************************************/
  416. #pragma runtime_checks("", off)
  417. void Cipher1::encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  418. {
  419. if(Byte *d=(Byte*)dest)
  420. {
  421. if(Byte *s=(Byte*)src)
  422. {
  423. offset&=255;
  424. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  425. {
  426. *d++=_enc[(*s++)^_enc[offset+0]];
  427. *d++=_enc[(*s++)^_enc[offset+1]];
  428. *d++=_enc[(*s++)^_enc[offset+2]];
  429. *d++=_enc[(*s++)^_enc[offset+3]];
  430. offset+=4; offset&=255;
  431. }
  432. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  433. {
  434. case 3: *d++=_enc[(*s++)^_enc[offset]]; offset++; // !! no break on purpose !!
  435. case 2: *d++=_enc[(*s++)^_enc[offset]]; offset++; // !! no break on purpose !!
  436. case 1: *d++=_enc[(*s++)^_enc[offset]]; //offset++; // !! no break on purpose !!
  437. }
  438. }else
  439. {
  440. offset&=255;
  441. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  442. {
  443. *d++=_enc[_enc[offset+0]];
  444. *d++=_enc[_enc[offset+1]];
  445. *d++=_enc[_enc[offset+2]];
  446. *d++=_enc[_enc[offset+3]];
  447. offset+=4; offset&=255;
  448. }
  449. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  450. {
  451. case 3: *d++=_enc[_enc[offset]]; offset++; // !! no break on purpose !!
  452. case 2: *d++=_enc[_enc[offset]]; offset++; // !! no break on purpose !!
  453. case 1: *d++=_enc[_enc[offset]]; //offset++; // !! no break on purpose !!
  454. }
  455. }
  456. }
  457. }
  458. void Cipher1::decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  459. {
  460. if(Byte *d=(Byte*)dest)
  461. {
  462. if(Byte *s=(Byte*)src)
  463. {
  464. offset&=255;
  465. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  466. {
  467. *d++=_dec[(*s++)]^_enc[offset+0];
  468. *d++=_dec[(*s++)]^_enc[offset+1];
  469. *d++=_dec[(*s++)]^_enc[offset+2];
  470. *d++=_dec[(*s++)]^_enc[offset+3];
  471. offset+=4; offset&=255;
  472. }
  473. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  474. {
  475. case 3: *d++=_dec[(*s++)]^_enc[offset]; offset++; // !! no break on purpose !!
  476. case 2: *d++=_dec[(*s++)]^_enc[offset]; offset++; // !! no break on purpose !!
  477. case 1: *d++=_dec[(*s++)]^_enc[offset]; //offset++; // !! no break on purpose !!
  478. }
  479. }else
  480. {
  481. Byte dec0=_dec[0];
  482. offset&=255;
  483. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  484. {
  485. *d++=dec0^_enc[offset+0];
  486. *d++=dec0^_enc[offset+1];
  487. *d++=dec0^_enc[offset+2];
  488. *d++=dec0^_enc[offset+3];
  489. offset+=4; offset&=255;
  490. }
  491. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  492. {
  493. case 3: *d++=dec0^_enc[offset]; offset++; // !! no break on purpose !!
  494. case 2: *d++=dec0^_enc[offset]; offset++; // !! no break on purpose !!
  495. case 1: *d++=dec0^_enc[offset]; //offset++; // !! no break on purpose !!
  496. }
  497. }
  498. }
  499. }
  500. #pragma runtime_checks("", restore)
  501. /******************************************************************************/
  502. // CIPHER 2
  503. /******************************************************************************/
  504. Cipher2::Cipher2() {setKey(null, 0);}
  505. Cipher2& Cipher2::setKey(C Byte *key, Int key_size)
  506. {
  507. if(key && key_size>0)
  508. {
  509. REPAO(_enc)=i;
  510. FREP(255) // RandomizeOrder based on 'key'
  511. {
  512. Byte k=key[UInt(i)%UInt(key_size)]; // unsigned div is slightly faster
  513. UInt left=256-i;
  514. Swap(_enc[i], _enc[i+k%left]);
  515. }
  516. setDec();
  517. }else
  518. {
  519. REPAO(_enc)=i;
  520. REPAO(_dec)=i;
  521. }
  522. return T;
  523. }
  524. Cipher2::Cipher2(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09, Byte k0A, Byte k0B, Byte k0C, Byte k0D, Byte k0E, Byte k0F,
  525. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19, Byte k1A, Byte k1B, Byte k1C, Byte k1D, Byte k1E, Byte k1F,
  526. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29, Byte k2A, Byte k2B, Byte k2C, Byte k2D, Byte k2E, Byte k2F,
  527. Byte k30, Byte k31, Byte k32, Byte k33, Byte k34, Byte k35, Byte k36, Byte k37, Byte k38, Byte k39, Byte k3A, Byte k3B, Byte k3C, Byte k3D, Byte k3E, Byte k3F,
  528. Byte k40, Byte k41, Byte k42, Byte k43, Byte k44, Byte k45, Byte k46, Byte k47, Byte k48, Byte k49, Byte k4A, Byte k4B, Byte k4C, Byte k4D, Byte k4E, Byte k4F,
  529. Byte k50, Byte k51, Byte k52, Byte k53, Byte k54, Byte k55, Byte k56, Byte k57, Byte k58, Byte k59, Byte k5A, Byte k5B, Byte k5C, Byte k5D, Byte k5E, Byte k5F,
  530. Byte k60, Byte k61, Byte k62, Byte k63, Byte k64, Byte k65, Byte k66, Byte k67, Byte k68, Byte k69, Byte k6A, Byte k6B, Byte k6C, Byte k6D, Byte k6E, Byte k6F,
  531. Byte k70, Byte k71, Byte k72, Byte k73, Byte k74, Byte k75, Byte k76, Byte k77, Byte k78, Byte k79, Byte k7A, Byte k7B, Byte k7C, Byte k7D, Byte k7E, Byte k7F,
  532. Byte k80, Byte k81, Byte k82, Byte k83, Byte k84, Byte k85, Byte k86, Byte k87, Byte k88, Byte k89, Byte k8A, Byte k8B, Byte k8C, Byte k8D, Byte k8E, Byte k8F,
  533. Byte k90, Byte k91, Byte k92, Byte k93, Byte k94, Byte k95, Byte k96, Byte k97, Byte k98, Byte k99, Byte k9A, Byte k9B, Byte k9C, Byte k9D, Byte k9E, Byte k9F,
  534. Byte kA0, Byte kA1, Byte kA2, Byte kA3, Byte kA4, Byte kA5, Byte kA6, Byte kA7, Byte kA8, Byte kA9, Byte kAA, Byte kAB, Byte kAC, Byte kAD, Byte kAE, Byte kAF,
  535. Byte kB0, Byte kB1, Byte kB2, Byte kB3, Byte kB4, Byte kB5, Byte kB6, Byte kB7, Byte kB8, Byte kB9, Byte kBA, Byte kBB, Byte kBC, Byte kBD, Byte kBE, Byte kBF,
  536. Byte kC0, Byte kC1, Byte kC2, Byte kC3, Byte kC4, Byte kC5, Byte kC6, Byte kC7, Byte kC8, Byte kC9, Byte kCA, Byte kCB, Byte kCC, Byte kCD, Byte kCE, Byte kCF,
  537. Byte kD0, Byte kD1, Byte kD2, Byte kD3, Byte kD4, Byte kD5, Byte kD6, Byte kD7, Byte kD8, Byte kD9, Byte kDA, Byte kDB, Byte kDC, Byte kDD, Byte kDE, Byte kDF,
  538. Byte kE0, Byte kE1, Byte kE2, Byte kE3, Byte kE4, Byte kE5, Byte kE6, Byte kE7, Byte kE8, Byte kE9, Byte kEA, Byte kEB, Byte kEC, Byte kED, Byte kEE, Byte kEF,
  539. Byte kF0, Byte kF1, Byte kF2, Byte kF3, Byte kF4, Byte kF5, Byte kF6, Byte kF7, Byte kF8, Byte kF9, Byte kFA, Byte kFB, Byte kFC, Byte kFD, Byte kFE, Byte kFF)
  540. {
  541. Byte k[]={
  542. k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F,
  543. k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F,
  544. k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F,
  545. k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F,
  546. k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F,
  547. k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k5A, k5B, k5C, k5D, k5E, k5F,
  548. k60, k61, k62, k63, k64, k65, k66, k67, k68, k69, k6A, k6B, k6C, k6D, k6E, k6F,
  549. k70, k71, k72, k73, k74, k75, k76, k77, k78, k79, k7A, k7B, k7C, k7D, k7E, k7F,
  550. k80, k81, k82, k83, k84, k85, k86, k87, k88, k89, k8A, k8B, k8C, k8D, k8E, k8F,
  551. k90, k91, k92, k93, k94, k95, k96, k97, k98, k99, k9A, k9B, k9C, k9D, k9E, k9F,
  552. kA0, kA1, kA2, kA3, kA4, kA5, kA6, kA7, kA8, kA9, kAA, kAB, kAC, kAD, kAE, kAF,
  553. kB0, kB1, kB2, kB3, kB4, kB5, kB6, kB7, kB8, kB9, kBA, kBB, kBC, kBD, kBE, kBF,
  554. kC0, kC1, kC2, kC3, kC4, kC5, kC6, kC7, kC8, kC9, kCA, kCB, kCC, kCD, kCE, kCF,
  555. kD0, kD1, kD2, kD3, kD4, kD5, kD6, kD7, kD8, kD9, kDA, kDB, kDC, kDD, kDE, kDF,
  556. kE0, kE1, kE2, kE3, kE4, kE5, kE6, kE7, kE8, kE9, kEA, kEB, kEC, kED, kEE, kEF,
  557. kF0, kF1, kF2, kF3, kF4, kF5, kF6, kF7, kF8, kF9, kFA, kFB, kFC, kFD, kFE, kFF,
  558. };
  559. setKey((Byte*)k, SIZE(k));
  560. }
  561. void Cipher2::setDec()
  562. {
  563. REPA(_dec)_dec[_enc[i]]=i;
  564. }
  565. /******************************************************************************/
  566. void Cipher2::randomizeKey()
  567. {
  568. UID uid[256/SIZE(UID)]; REPAO(uid).randomize(); // 'UID.randomize' uses a more secure version than 'Random'
  569. setKey(uid[0].b, SIZE(uid));
  570. }
  571. Bool Cipher2::saveKey(File &f)C {return f.put(_enc, 256);}
  572. Bool Cipher2::loadKey(File &f) {Bool ok=f.get(_enc, 256); setDec(); return ok;}
  573. Bool Cipher2:: mixKey(File &f) {Byte temp[256]; f>>temp; REPAO(temp)^=_enc[i]; setKey(temp, Elms(temp)); return f.ok();}
  574. /******************************************************************************/
  575. #pragma runtime_checks("", off)
  576. void Cipher2::encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  577. {
  578. if(Byte *d=(Byte*)dest)
  579. {
  580. if(Byte *s=(Byte*)src)
  581. {
  582. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  583. {
  584. *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++;
  585. *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++;
  586. *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++;
  587. *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++;
  588. }
  589. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  590. {
  591. case 3: *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++; // !! no break on purpose !!
  592. case 2: *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; offset++; // !! no break on purpose !!
  593. case 1: *d++=_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]; //offset++; // !! no break on purpose !!
  594. }
  595. }else
  596. {
  597. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  598. {
  599. *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++;
  600. *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++;
  601. *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++;
  602. *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++;
  603. }
  604. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  605. {
  606. case 3: *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++; // !! no break on purpose !!
  607. case 2: *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; offset++; // !! no break on purpose !!
  608. case 1: *d++=_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]; //offset++; // !! no break on purpose !!
  609. }
  610. }
  611. }
  612. }
  613. void Cipher2::decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  614. {
  615. if(Byte *d=(Byte*)dest)
  616. {
  617. if(Byte *s=(Byte*)src)
  618. {
  619. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  620. {
  621. *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++;
  622. *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++;
  623. *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++;
  624. *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++;
  625. }
  626. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  627. {
  628. case 3: *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  629. case 2: *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  630. case 1: *d++=_dec[_dec[*s++]^((offset>>8)&0xFF)]^offset; //offset++; // !! no break on purpose !!
  631. }
  632. }else
  633. {
  634. Byte dec0=_dec[0];
  635. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  636. {
  637. *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++;
  638. *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++;
  639. *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++;
  640. *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++;
  641. }
  642. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  643. {
  644. case 3: *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  645. case 2: *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  646. case 1: *d++=_dec[dec0^((offset>>8)&0xFF)]^offset; //offset++; // !! no break on purpose !!
  647. }
  648. }
  649. }
  650. }
  651. #pragma runtime_checks("", restore)
  652. /******************************************************************************/
  653. // CIPHER 3
  654. /******************************************************************************/
  655. Cipher3::Cipher3() {setKey(null, 0);}
  656. Cipher3& Cipher3::setKey(C Byte *key, Int key_size)
  657. {
  658. if(key && key_size>0)
  659. {
  660. REPAO(_enc)=i;
  661. FREP(255) // RandomizeOrder based on 'key'
  662. {
  663. Byte k=key[UInt(i)%UInt(key_size)]; // unsigned div is slightly faster
  664. UInt left=256-i;
  665. Swap(_enc[i], _enc[i+k%left]);
  666. }
  667. setDec();
  668. }else
  669. {
  670. REPAO(_enc)=i;
  671. REPAO(_dec)=i;
  672. }
  673. return T;
  674. }
  675. Cipher3::Cipher3(Byte k00, Byte k01, Byte k02, Byte k03, Byte k04, Byte k05, Byte k06, Byte k07, Byte k08, Byte k09, Byte k0A, Byte k0B, Byte k0C, Byte k0D, Byte k0E, Byte k0F,
  676. Byte k10, Byte k11, Byte k12, Byte k13, Byte k14, Byte k15, Byte k16, Byte k17, Byte k18, Byte k19, Byte k1A, Byte k1B, Byte k1C, Byte k1D, Byte k1E, Byte k1F,
  677. Byte k20, Byte k21, Byte k22, Byte k23, Byte k24, Byte k25, Byte k26, Byte k27, Byte k28, Byte k29, Byte k2A, Byte k2B, Byte k2C, Byte k2D, Byte k2E, Byte k2F,
  678. Byte k30, Byte k31, Byte k32, Byte k33, Byte k34, Byte k35, Byte k36, Byte k37, Byte k38, Byte k39, Byte k3A, Byte k3B, Byte k3C, Byte k3D, Byte k3E, Byte k3F,
  679. Byte k40, Byte k41, Byte k42, Byte k43, Byte k44, Byte k45, Byte k46, Byte k47, Byte k48, Byte k49, Byte k4A, Byte k4B, Byte k4C, Byte k4D, Byte k4E, Byte k4F,
  680. Byte k50, Byte k51, Byte k52, Byte k53, Byte k54, Byte k55, Byte k56, Byte k57, Byte k58, Byte k59, Byte k5A, Byte k5B, Byte k5C, Byte k5D, Byte k5E, Byte k5F,
  681. Byte k60, Byte k61, Byte k62, Byte k63, Byte k64, Byte k65, Byte k66, Byte k67, Byte k68, Byte k69, Byte k6A, Byte k6B, Byte k6C, Byte k6D, Byte k6E, Byte k6F,
  682. Byte k70, Byte k71, Byte k72, Byte k73, Byte k74, Byte k75, Byte k76, Byte k77, Byte k78, Byte k79, Byte k7A, Byte k7B, Byte k7C, Byte k7D, Byte k7E, Byte k7F,
  683. Byte k80, Byte k81, Byte k82, Byte k83, Byte k84, Byte k85, Byte k86, Byte k87, Byte k88, Byte k89, Byte k8A, Byte k8B, Byte k8C, Byte k8D, Byte k8E, Byte k8F,
  684. Byte k90, Byte k91, Byte k92, Byte k93, Byte k94, Byte k95, Byte k96, Byte k97, Byte k98, Byte k99, Byte k9A, Byte k9B, Byte k9C, Byte k9D, Byte k9E, Byte k9F,
  685. Byte kA0, Byte kA1, Byte kA2, Byte kA3, Byte kA4, Byte kA5, Byte kA6, Byte kA7, Byte kA8, Byte kA9, Byte kAA, Byte kAB, Byte kAC, Byte kAD, Byte kAE, Byte kAF,
  686. Byte kB0, Byte kB1, Byte kB2, Byte kB3, Byte kB4, Byte kB5, Byte kB6, Byte kB7, Byte kB8, Byte kB9, Byte kBA, Byte kBB, Byte kBC, Byte kBD, Byte kBE, Byte kBF,
  687. Byte kC0, Byte kC1, Byte kC2, Byte kC3, Byte kC4, Byte kC5, Byte kC6, Byte kC7, Byte kC8, Byte kC9, Byte kCA, Byte kCB, Byte kCC, Byte kCD, Byte kCE, Byte kCF,
  688. Byte kD0, Byte kD1, Byte kD2, Byte kD3, Byte kD4, Byte kD5, Byte kD6, Byte kD7, Byte kD8, Byte kD9, Byte kDA, Byte kDB, Byte kDC, Byte kDD, Byte kDE, Byte kDF,
  689. Byte kE0, Byte kE1, Byte kE2, Byte kE3, Byte kE4, Byte kE5, Byte kE6, Byte kE7, Byte kE8, Byte kE9, Byte kEA, Byte kEB, Byte kEC, Byte kED, Byte kEE, Byte kEF,
  690. Byte kF0, Byte kF1, Byte kF2, Byte kF3, Byte kF4, Byte kF5, Byte kF6, Byte kF7, Byte kF8, Byte kF9, Byte kFA, Byte kFB, Byte kFC, Byte kFD, Byte kFE, Byte kFF)
  691. {
  692. Byte k[]={
  693. k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F,
  694. k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F,
  695. k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F,
  696. k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F,
  697. k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F,
  698. k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k5A, k5B, k5C, k5D, k5E, k5F,
  699. k60, k61, k62, k63, k64, k65, k66, k67, k68, k69, k6A, k6B, k6C, k6D, k6E, k6F,
  700. k70, k71, k72, k73, k74, k75, k76, k77, k78, k79, k7A, k7B, k7C, k7D, k7E, k7F,
  701. k80, k81, k82, k83, k84, k85, k86, k87, k88, k89, k8A, k8B, k8C, k8D, k8E, k8F,
  702. k90, k91, k92, k93, k94, k95, k96, k97, k98, k99, k9A, k9B, k9C, k9D, k9E, k9F,
  703. kA0, kA1, kA2, kA3, kA4, kA5, kA6, kA7, kA8, kA9, kAA, kAB, kAC, kAD, kAE, kAF,
  704. kB0, kB1, kB2, kB3, kB4, kB5, kB6, kB7, kB8, kB9, kBA, kBB, kBC, kBD, kBE, kBF,
  705. kC0, kC1, kC2, kC3, kC4, kC5, kC6, kC7, kC8, kC9, kCA, kCB, kCC, kCD, kCE, kCF,
  706. kD0, kD1, kD2, kD3, kD4, kD5, kD6, kD7, kD8, kD9, kDA, kDB, kDC, kDD, kDE, kDF,
  707. kE0, kE1, kE2, kE3, kE4, kE5, kE6, kE7, kE8, kE9, kEA, kEB, kEC, kED, kEE, kEF,
  708. kF0, kF1, kF2, kF3, kF4, kF5, kF6, kF7, kF8, kF9, kFA, kFB, kFC, kFD, kFE, kFF,
  709. };
  710. setKey((Byte*)k, SIZE(k));
  711. }
  712. void Cipher3::setDec()
  713. {
  714. REPA(_dec)_dec[_enc[i]]=i;
  715. }
  716. /******************************************************************************/
  717. void Cipher3::randomizeKey()
  718. {
  719. UID uid[256/SIZE(UID)]; REPAO(uid).randomize(); // 'UID.randomize' uses a more secure version than 'Random'
  720. setKey(uid[0].b, SIZE(uid));
  721. }
  722. Bool Cipher3::saveKey(File &f)C {return f.put(_enc, 256);}
  723. Bool Cipher3::loadKey(File &f) {Bool ok=f.get(_enc, 256); setDec(); return ok;}
  724. Bool Cipher3:: mixKey(File &f) {Byte temp[256]; f>>temp; REPAO(temp)^=_enc[i]; setKey(temp, Elms(temp)); return f.ok();}
  725. /******************************************************************************/
  726. #pragma runtime_checks("", off)
  727. void Cipher3::encrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  728. {
  729. if(Byte *d=(Byte*)dest)
  730. {
  731. if(Byte *s=(Byte*)src)
  732. {
  733. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  734. {
  735. *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  736. *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  737. *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  738. *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  739. }
  740. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  741. {
  742. case 3: *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++; // !! no break on purpose !!
  743. case 2: *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++; // !! no break on purpose !!
  744. case 1: *d++=_enc[_enc[_enc[(*s++)^(offset&0xFF)]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; //offset++; // !! no break on purpose !!
  745. }
  746. }else
  747. {
  748. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  749. {
  750. *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  751. *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  752. *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  753. *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++;
  754. }
  755. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  756. {
  757. case 3: *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++; // !! no break on purpose !!
  758. case 2: *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; offset++; // !! no break on purpose !!
  759. case 1: *d++=_enc[_enc[_enc[offset&0xFF]^((offset>>8)&0xFF)]^((offset>>16)&0xFF)]; //offset++; // !! no break on purpose !!
  760. }
  761. }
  762. }
  763. }
  764. void Cipher3::decrypt(Ptr dest, CPtr src, IntPtr size, Int offset)
  765. {
  766. if(Byte *d=(Byte*)dest)
  767. {
  768. if(Byte *s=(Byte*)src)
  769. {
  770. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  771. {
  772. *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  773. *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  774. *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  775. *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  776. }
  777. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  778. {
  779. case 3: *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  780. case 2: *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  781. case 1: *d++=_dec[_dec[_dec[*s++]^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; //offset++; // !! no break on purpose !!
  782. }
  783. }else
  784. {
  785. Byte dec0=_dec[0];
  786. REPP(size/4) // doing 'VecB4' reads/writes made things slower, so process each 'Byte' separately, "for(; size>=4; size-=4)" was slower for size>=1024
  787. {
  788. *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  789. *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  790. *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  791. *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++;
  792. }
  793. switch(size%4) // this is faster than REP(size%4), can't use "size&3" due to negative numbers
  794. {
  795. case 3: *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  796. case 2: *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; offset++; // !! no break on purpose !!
  797. case 1: *d++=_dec[_dec[dec0^((offset>>16)&0xFF)]^((offset>>8)&0xFF)]^offset; //offset++; // !! no break on purpose !!
  798. }
  799. }
  800. }
  801. }
  802. #pragma runtime_checks("", restore)
  803. /******************************************************************************/
  804. // AES
  805. /******************************************************************************/
  806. #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
  807. #define SWAP( x ) (_lrotl(x, 8)&0x00ff00ff | _lrotr(x, 8)&0xff00ff00)
  808. #define GETU32(p ) SWAP(*((U32*)(p)))
  809. #define PUTU32(ct, st) {*((U32*)(ct))=SWAP((st));}
  810. #else
  811. #define GETU32(pt) (((U32)(pt)[0] << 24) ^ ((U32)(pt)[1] << 16) ^ ((U32)(pt)[2] << 8) ^ ((U32)(pt)[3]))
  812. #define PUTU32(ct, st) \
  813. { \
  814. (ct)[0]=(Byte)((st)>>24);\
  815. (ct)[1]=(Byte)((st)>>16);\
  816. (ct)[2]=(Byte)((st)>> 8);\
  817. (ct)[3]=(Byte) (st) ;\
  818. }
  819. #endif
  820. static const U32 Te0[256]=
  821. {
  822. 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU,
  823. 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U,
  824. 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U,
  825. 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
  826. 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU,
  827. 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U,
  828. 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU,
  829. 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
  830. 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U,
  831. 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U,
  832. 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU,
  833. 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
  834. 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU,
  835. 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U,
  836. 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U,
  837. 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
  838. 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U,
  839. 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U,
  840. 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U,
  841. 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
  842. 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU,
  843. 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U,
  844. 0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U,
  845. 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
  846. 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U,
  847. 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U,
  848. 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU,
  849. 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
  850. 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U,
  851. 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU,
  852. 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U,
  853. 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
  854. 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU,
  855. 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU,
  856. 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U,
  857. 0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
  858. 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U,
  859. 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU,
  860. 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU,
  861. 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
  862. 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU,
  863. 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U,
  864. 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U,
  865. 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
  866. 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U,
  867. 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U,
  868. 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U,
  869. 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
  870. 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU,
  871. 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U,
  872. 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U,
  873. 0x2c16163aU
  874. };
  875. static const U32 Te1[256]=
  876. {
  877. 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U,
  878. 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U,
  879. 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU,
  880. 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
  881. 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU,
  882. 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U,
  883. 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U,
  884. 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
  885. 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U,
  886. 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U,
  887. 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U,
  888. 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
  889. 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U,
  890. 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU,
  891. 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U,
  892. 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
  893. 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U,
  894. 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU,
  895. 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U,
  896. 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
  897. 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U,
  898. 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU,
  899. 0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U,
  900. 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
  901. 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U,
  902. 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU,
  903. 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U,
  904. 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
  905. 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U,
  906. 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU,
  907. 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U,
  908. 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
  909. 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U,
  910. 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U,
  911. 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U,
  912. 0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
  913. 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU,
  914. 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU,
  915. 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U,
  916. 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
  917. 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU,
  918. 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU,
  919. 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U,
  920. 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
  921. 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U,
  922. 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U,
  923. 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U,
  924. 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
  925. 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU,
  926. 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U,
  927. 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU,
  928. 0x3a2c1616U
  929. };
  930. static const U32 Te2[256]=
  931. {
  932. 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U,
  933. 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U,
  934. 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU,
  935. 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
  936. 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU,
  937. 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U,
  938. 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U,
  939. 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
  940. 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U,
  941. 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U,
  942. 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U,
  943. 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
  944. 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U,
  945. 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU,
  946. 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U,
  947. 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
  948. 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U,
  949. 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU,
  950. 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U,
  951. 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
  952. 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U,
  953. 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU,
  954. 0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U,
  955. 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
  956. 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U,
  957. 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU,
  958. 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U,
  959. 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
  960. 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U,
  961. 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU,
  962. 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U,
  963. 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
  964. 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U,
  965. 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U,
  966. 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U,
  967. 0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
  968. 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU,
  969. 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU,
  970. 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U,
  971. 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
  972. 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU,
  973. 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU,
  974. 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U,
  975. 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
  976. 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U,
  977. 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U,
  978. 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U,
  979. 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
  980. 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU,
  981. 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U,
  982. 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU,
  983. 0x163a2c16U
  984. };
  985. static const U32 Te3[256]=
  986. {
  987. 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU,
  988. 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U,
  989. 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU,
  990. 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
  991. 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U,
  992. 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U,
  993. 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU,
  994. 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
  995. 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U,
  996. 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U,
  997. 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU,
  998. 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
  999. 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U,
  1000. 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU,
  1001. 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U,
  1002. 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
  1003. 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U,
  1004. 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU,
  1005. 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U,
  1006. 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
  1007. 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU,
  1008. 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U,
  1009. 0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U,
  1010. 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
  1011. 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U,
  1012. 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U,
  1013. 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U,
  1014. 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
  1015. 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U,
  1016. 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U,
  1017. 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU,
  1018. 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
  1019. 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U,
  1020. 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU,
  1021. 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U,
  1022. 0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
  1023. 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U,
  1024. 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U,
  1025. 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU,
  1026. 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
  1027. 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U,
  1028. 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU,
  1029. 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U,
  1030. 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
  1031. 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U,
  1032. 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U,
  1033. 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U,
  1034. 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
  1035. 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U,
  1036. 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U,
  1037. 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU,
  1038. 0x16163a2cU
  1039. };
  1040. static const U32 Td0[256]=
  1041. {
  1042. 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU,
  1043. 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U,
  1044. 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U,
  1045. 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
  1046. 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U,
  1047. 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U,
  1048. 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU,
  1049. 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
  1050. 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U,
  1051. 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U,
  1052. 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U,
  1053. 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
  1054. 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU,
  1055. 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U,
  1056. 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U,
  1057. 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
  1058. 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U,
  1059. 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U,
  1060. 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U,
  1061. 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
  1062. 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU,
  1063. 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U,
  1064. 0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U,
  1065. 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
  1066. 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU,
  1067. 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU,
  1068. 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U,
  1069. 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
  1070. 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU,
  1071. 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U,
  1072. 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU,
  1073. 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
  1074. 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU,
  1075. 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU,
  1076. 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU,
  1077. 0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
  1078. 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U,
  1079. 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU,
  1080. 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U,
  1081. 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
  1082. 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU,
  1083. 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU,
  1084. 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U,
  1085. 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
  1086. 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU,
  1087. 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U,
  1088. 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U,
  1089. 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
  1090. 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U,
  1091. 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU,
  1092. 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U,
  1093. 0xd0b85742U
  1094. };
  1095. static const U32 Td1[256]=
  1096. {
  1097. 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU,
  1098. 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU,
  1099. 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U,
  1100. 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
  1101. 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU,
  1102. 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U,
  1103. 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU,
  1104. 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
  1105. 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U,
  1106. 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU,
  1107. 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU,
  1108. 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
  1109. 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU,
  1110. 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU,
  1111. 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U,
  1112. 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
  1113. 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU,
  1114. 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U,
  1115. 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU,
  1116. 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
  1117. 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU,
  1118. 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U,
  1119. 0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U,
  1120. 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
  1121. 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU,
  1122. 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U,
  1123. 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU,
  1124. 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
  1125. 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U,
  1126. 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U,
  1127. 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U,
  1128. 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
  1129. 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U,
  1130. 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U,
  1131. 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U,
  1132. 0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
  1133. 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U,
  1134. 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U,
  1135. 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U,
  1136. 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
  1137. 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U,
  1138. 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U,
  1139. 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU,
  1140. 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
  1141. 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U,
  1142. 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U,
  1143. 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU,
  1144. 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
  1145. 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U,
  1146. 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U,
  1147. 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU,
  1148. 0x42d0b857U
  1149. };
  1150. static const U32 Td2[256]=
  1151. {
  1152. 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU,
  1153. 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U,
  1154. 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U,
  1155. 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
  1156. 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU,
  1157. 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U,
  1158. 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U,
  1159. 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
  1160. 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U,
  1161. 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U,
  1162. 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU,
  1163. 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
  1164. 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU,
  1165. 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U,
  1166. 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU,
  1167. 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
  1168. 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U,
  1169. 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU,
  1170. 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U,
  1171. 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
  1172. 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU,
  1173. 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU,
  1174. 0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU,
  1175. 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
  1176. 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U,
  1177. 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U,
  1178. 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U,
  1179. 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
  1180. 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU,
  1181. 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U,
  1182. 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U,
  1183. 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
  1184. 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U,
  1185. 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U,
  1186. 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U,
  1187. 0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
  1188. 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U,
  1189. 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU,
  1190. 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU,
  1191. 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
  1192. 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U,
  1193. 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU,
  1194. 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU,
  1195. 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
  1196. 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U,
  1197. 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U,
  1198. 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U,
  1199. 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
  1200. 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU,
  1201. 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU,
  1202. 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU,
  1203. 0x5742d0b8U
  1204. };
  1205. static const U32 Td3[256]=
  1206. {
  1207. 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU,
  1208. 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU,
  1209. 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U,
  1210. 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
  1211. 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U,
  1212. 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U,
  1213. 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U,
  1214. 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
  1215. 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U,
  1216. 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU,
  1217. 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U,
  1218. 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
  1219. 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU,
  1220. 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U,
  1221. 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U,
  1222. 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
  1223. 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U,
  1224. 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U,
  1225. 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U,
  1226. 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
  1227. 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU,
  1228. 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U,
  1229. 0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U,
  1230. 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
  1231. 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU,
  1232. 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU,
  1233. 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U,
  1234. 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
  1235. 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U,
  1236. 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU,
  1237. 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U,
  1238. 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
  1239. 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U,
  1240. 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U,
  1241. 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU,
  1242. 0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
  1243. 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU,
  1244. 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU,
  1245. 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU,
  1246. 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
  1247. 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U,
  1248. 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U,
  1249. 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U,
  1250. 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
  1251. 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU,
  1252. 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U,
  1253. 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U,
  1254. 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
  1255. 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U,
  1256. 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U,
  1257. 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U,
  1258. 0xb85742d0U
  1259. };
  1260. static const Byte Td4[256]=
  1261. {
  1262. 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U,
  1263. 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU,
  1264. 0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 0x54U,
  1265. 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU,
  1266. 0x42U, 0xfaU, 0xc3U, 0x4eU, 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U,
  1267. 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 0x72U, 0xf8U,
  1268. 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU,
  1269. 0x65U, 0xb6U, 0x92U, 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
  1270. 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 0x90U, 0xd8U, 0xabU,
  1271. 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U,
  1272. 0x45U, 0x06U, 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U,
  1273. 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 0x3aU, 0x91U, 0x11U, 0x41U,
  1274. 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U,
  1275. 0x73U, 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U,
  1276. 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU,
  1277. 0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
  1278. 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U,
  1279. 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U,
  1280. 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 0x60U,
  1281. 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU,
  1282. 0x93U, 0xc9U, 0x9cU, 0xefU, 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U,
  1283. 0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 0x17U, 0x2bU,
  1284. 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U,
  1285. 0x21U, 0x0cU, 0x7dU
  1286. };
  1287. static const U32 rcon[]=
  1288. {
  1289. 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, // for 128-bit blocks, Rijndael never uses more than 10 rcon values
  1290. };
  1291. static const U32 rcLE[]=
  1292. {
  1293. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36, // for 128-bit blocks, Rijndael never uses more than 10 rcon values
  1294. };
  1295. AES::AES() {Zero(T);}
  1296. AES_ATTR Bool AES::create(CPtr key_data, Int key_size)
  1297. {
  1298. if(C Byte *key=(Byte*)key_data)
  1299. {
  1300. #if AES_CPU
  1301. if(Cpu.flag()&CPU_AES)
  1302. {
  1303. if(key_size!=16 && key_size!=24 && key_size!=32)return false;
  1304. _rounds=6+key_size/4;
  1305. const U32 *rc=rcLE;
  1306. U32 *rk=_encrypt_key;
  1307. memcpy(rk, key, key_size);
  1308. __m128i temp=_mm_loadu_si128((__m128i*)(key+key_size-16));
  1309. for(;;)
  1310. {
  1311. rk[key_size/4 ] = rk[0] ^ _mm_extract_epi32(_mm_aeskeygenassist_si128(temp, 0), 3) ^ *(rc++);
  1312. rk[key_size/4+1] = rk[1] ^ rk[key_size/4 ];
  1313. rk[key_size/4+2] = rk[2] ^ rk[key_size/4+1];
  1314. rk[key_size/4+3] = rk[3] ^ rk[key_size/4+2];
  1315. if(rk + key_size/4 + 4 >= _encrypt_key+ELMS(_encrypt_key))break;
  1316. if(key_size==24)
  1317. {
  1318. rk[10]=rk[4]^rk[ 9];
  1319. rk[11]=rk[5]^rk[10];
  1320. temp=_mm_insert_epi32(temp, rk[11], 3);
  1321. }else
  1322. if(key_size==32)
  1323. {
  1324. temp=_mm_insert_epi32(temp, rk[11], 3);
  1325. rk[12]=rk[4]^_mm_extract_epi32(_mm_aeskeygenassist_si128(temp, 0), 2);
  1326. rk[13]=rk[5]^rk[12];
  1327. rk[14]=rk[6]^rk[13];
  1328. rk[15]=rk[7]^rk[14];
  1329. temp=_mm_insert_epi32(temp, rk[15], 3);
  1330. }else
  1331. temp=_mm_insert_epi32(temp, rk[7], 3);
  1332. rk+=key_size/4;
  1333. }
  1334. Copy(_decrypt_key, _encrypt_key);
  1335. rk=_decrypt_key;
  1336. Swap(*(__m128i*)(rk), *(__m128i*)(rk+4*_rounds));
  1337. Int i, j; for(i=4, j=4*_rounds-4; i<j; i+=4, j-=4)
  1338. {
  1339. temp=_mm_aesimc_si128(*(__m128i*)(rk+i));
  1340. *(__m128i*)(rk+i)=_mm_aesimc_si128(*(__m128i*)(rk+j));
  1341. *(__m128i*)(rk+j)=temp;
  1342. }
  1343. *(__m128i*)(rk+i)=_mm_aesimc_si128(*(__m128i*)(rk+i));
  1344. return true;
  1345. }
  1346. #endif
  1347. Int i=0;
  1348. U32 temp, *rk=_encrypt_key;
  1349. rk[0]=GETU32(key);
  1350. rk[1]=GETU32(key + 4);
  1351. rk[2]=GETU32(key + 8);
  1352. rk[3]=GETU32(key + 12);
  1353. switch(key_size)
  1354. {
  1355. case 16:
  1356. {
  1357. _rounds=10;
  1358. for(;;)
  1359. {
  1360. temp=rk[3];
  1361. rk[4] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
  1362. rk[5] = rk[1] ^ rk[4];
  1363. rk[6] = rk[2] ^ rk[5];
  1364. rk[7] = rk[3] ^ rk[6];
  1365. if(++i==10)break;
  1366. rk+=4;
  1367. }
  1368. }break;
  1369. case 24:
  1370. {
  1371. _rounds=12;
  1372. rk[4]=GETU32(key + 16);
  1373. rk[5]=GETU32(key + 20);
  1374. for(;;)
  1375. {
  1376. temp=rk[5];
  1377. rk[6] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
  1378. rk[7] = rk[1] ^ rk[6];
  1379. rk[8] = rk[2] ^ rk[7];
  1380. rk[9] = rk[3] ^ rk[8];
  1381. if(++i==8)break;
  1382. rk[10] = rk[4] ^ rk[9];
  1383. rk[11] = rk[5] ^ rk[10];
  1384. rk+=6;
  1385. }
  1386. }break;
  1387. case 32:
  1388. {
  1389. _rounds=14;
  1390. rk[4]=GETU32(key + 16);
  1391. rk[5]=GETU32(key + 20);
  1392. rk[6]=GETU32(key + 24);
  1393. rk[7]=GETU32(key + 28);
  1394. for(;;)
  1395. {
  1396. temp=rk[7];
  1397. rk[8] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
  1398. rk[9] = rk[1] ^ rk[8];
  1399. rk[10] = rk[2] ^ rk[9];
  1400. rk[11] = rk[3] ^ rk[10];
  1401. if(++i==7)break;
  1402. temp = rk[11];
  1403. rk[12] = rk[4] ^ (Te2[(temp >> 24)] & 0xff000000) ^ (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(temp) & 0xff] & 0x000000ff);
  1404. rk[13] = rk[5] ^ rk[12];
  1405. rk[14] = rk[6] ^ rk[13];
  1406. rk[15] = rk[7] ^ rk[14];
  1407. rk+=8;
  1408. }
  1409. }break;
  1410. default: return false;
  1411. }
  1412. // first, start with an encryption schedule invert the order of the round keys
  1413. for(Int i=0, j=4*_rounds; j>=0; i+=4, j-=4)
  1414. {
  1415. _decrypt_key[j ]=_encrypt_key[i ];
  1416. _decrypt_key[j+1]=_encrypt_key[i+1];
  1417. _decrypt_key[j+2]=_encrypt_key[i+2];
  1418. _decrypt_key[j+3]=_encrypt_key[i+3];
  1419. }
  1420. // apply the inverse MixColumn transform to all round keys but the first and * the last
  1421. rk=_decrypt_key;
  1422. for(i=1; i<_rounds; i++)
  1423. {
  1424. rk+=4;
  1425. rk[0] = Td0[Te1[(rk[0] >> 24)] & 0xff] ^ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[0]) & 0xff] & 0xff];
  1426. rk[1] = Td0[Te1[(rk[1] >> 24)] & 0xff] ^ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[1]) & 0xff] & 0xff];
  1427. rk[2] = Td0[Te1[(rk[2] >> 24)] & 0xff] ^ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[2]) & 0xff] & 0xff];
  1428. rk[3] = Td0[Te1[(rk[3] >> 24)] & 0xff] ^ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[3]) & 0xff] & 0xff];
  1429. }
  1430. return true;
  1431. }
  1432. return false;
  1433. }
  1434. AES_ATTR void AES::encrypt(Ptr dest, CPtr src)C
  1435. {
  1436. #if AES_CPU
  1437. if(Cpu.flag()&CPU_AES)
  1438. {
  1439. const __m128i *key=(const __m128i*)_encrypt_key;
  1440. __m128i block=_mm_loadu_si128((const __m128i*)src);
  1441. block=_mm_xor_si128(block, key[0]);
  1442. for(Int i=1; i<_rounds-1; i+=2)
  1443. {
  1444. block=_mm_aesenc_si128(block, key[i ]);
  1445. block=_mm_aesenc_si128(block, key[i+1]);
  1446. }
  1447. block=_mm_aesenc_si128 (block, key[_rounds-1]);
  1448. block=_mm_aesenclast_si128(block, key[_rounds ]);
  1449. _mm_storeu_si128((__m128i*)dest, block);
  1450. return;
  1451. }
  1452. #endif
  1453. const Byte *in =(Byte*)src;
  1454. Byte *out=(Byte*)dest;
  1455. const U32 *rk =_encrypt_key;
  1456. U32 s0, s1, s2, s3, t0, t1, t2, t3;
  1457. s0=GETU32(in )^rk[0];
  1458. s1=GETU32(in+ 4)^rk[1];
  1459. s2=GETU32(in+ 8)^rk[2];
  1460. s3=GETU32(in+12)^rk[3];
  1461. #if AES_SMALL_CODE
  1462. Int r=_rounds>>1;
  1463. for(;;)
  1464. {
  1465. t0 = Te0[(s0 >> 24)] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3) & 0xff] ^ rk[4];
  1466. t1 = Te0[(s1 >> 24)] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0) & 0xff] ^ rk[5];
  1467. t2 = Te0[(s2 >> 24)] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1) & 0xff] ^ rk[6];
  1468. t3 = Te0[(s3 >> 24)] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2) & 0xff] ^ rk[7];
  1469. rk+=8;
  1470. if(--r<=0)break;
  1471. s0 = Te0[(t0 >> 24)] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3) & 0xff] ^ rk[0];
  1472. s1 = Te0[(t1 >> 24)] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t0) & 0xff] ^ rk[1];
  1473. s2 = Te0[(t2 >> 24)] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1) & 0xff] ^ rk[2];
  1474. s3 = Te0[(t3 >> 24)] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2) & 0xff] ^ rk[3];
  1475. }
  1476. #else
  1477. // round 1
  1478. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[4];
  1479. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[5];
  1480. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[6];
  1481. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[7];
  1482. // round 2
  1483. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[8];
  1484. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[9];
  1485. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
  1486. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
  1487. // round 3
  1488. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
  1489. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
  1490. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
  1491. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
  1492. // round 4
  1493. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
  1494. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
  1495. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
  1496. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
  1497. // round 5
  1498. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
  1499. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
  1500. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
  1501. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
  1502. // round 6
  1503. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
  1504. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
  1505. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
  1506. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
  1507. // round 7
  1508. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
  1509. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
  1510. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
  1511. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
  1512. // round 8
  1513. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
  1514. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
  1515. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
  1516. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
  1517. // round 9
  1518. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
  1519. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
  1520. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
  1521. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
  1522. if(_rounds>10)
  1523. {
  1524. // round 10
  1525. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
  1526. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
  1527. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
  1528. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
  1529. // round 11
  1530. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
  1531. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
  1532. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
  1533. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
  1534. if(_rounds>12)
  1535. {
  1536. // round 12
  1537. s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
  1538. s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
  1539. s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
  1540. s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
  1541. // round 13
  1542. t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
  1543. t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
  1544. t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
  1545. t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
  1546. }
  1547. }
  1548. rk+=_rounds<<2;
  1549. #endif
  1550. s0 = (Te2[(t0 >> 24)] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(out , s0);
  1551. s1 = (Te2[(t1 >> 24)] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(out+ 4, s1);
  1552. s2 = (Te2[(t2 >> 24)] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(out+ 8, s2);
  1553. s3 = (Te2[(t3 >> 24)] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(out+12, s3);
  1554. }
  1555. AES_ATTR void AES::decrypt(Ptr dest, CPtr src)C
  1556. {
  1557. #if AES_CPU
  1558. if(Cpu.flag()&CPU_AES)
  1559. {
  1560. const __m128i *key=(const __m128i*)_decrypt_key;
  1561. __m128i block=_mm_loadu_si128((const __m128i*)src);
  1562. block=_mm_xor_si128(block, key[0]);
  1563. for(Int i=1; i<_rounds-1; i+=2)
  1564. {
  1565. block=_mm_aesdec_si128(block, key[i ]);
  1566. block=_mm_aesdec_si128(block, key[i+1]);
  1567. }
  1568. block=_mm_aesdec_si128 (block, key[_rounds-1]);
  1569. block=_mm_aesdeclast_si128(block, key[_rounds ]);
  1570. _mm_storeu_si128((__m128i*)dest, block);
  1571. return;
  1572. }
  1573. #endif
  1574. const Byte *in =(Byte*)src;
  1575. Byte *out=(Byte*)dest;
  1576. const U32 *rk =_decrypt_key;
  1577. U32 s0, s1, s2, s3, t0, t1, t2, t3;
  1578. s0=GETU32(in )^rk[0];
  1579. s1=GETU32(in+ 4)^rk[1];
  1580. s2=GETU32(in+ 8)^rk[2];
  1581. s3=GETU32(in+12)^rk[3];
  1582. #if AES_SMALL_CODE
  1583. Int r=_rounds>>1;
  1584. for(;;)
  1585. {
  1586. t0 = Td0[(s0 >> 24)] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1) & 0xff] ^ rk[4];
  1587. t1 = Td0[(s1 >> 24)] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2) & 0xff] ^ rk[5];
  1588. t2 = Td0[(s2 >> 24)] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3) & 0xff] ^ rk[6];
  1589. t3 = Td0[(s3 >> 24)] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0) & 0xff] ^ rk[7];
  1590. rk+=8;
  1591. if(--r<=0)break;
  1592. s0 = Td0[(t0 >> 24)] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[(t1) & 0xff] ^ rk[0];
  1593. s1 = Td0[(t1 >> 24)] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[(t2) & 0xff] ^ rk[1];
  1594. s2 = Td0[(t2 >> 24)] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[(t3) & 0xff] ^ rk[2];
  1595. s3 = Td0[(t3 >> 24)] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[(t0) & 0xff] ^ rk[3];
  1596. }
  1597. #else
  1598. // round 1
  1599. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[4];
  1600. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[5];
  1601. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[6];
  1602. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[7];
  1603. // round 2
  1604. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[8];
  1605. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[9];
  1606. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
  1607. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
  1608. // round 3
  1609. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
  1610. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
  1611. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
  1612. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
  1613. // round 4
  1614. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
  1615. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
  1616. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
  1617. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
  1618. // round 5
  1619. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
  1620. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
  1621. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
  1622. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
  1623. // round 6
  1624. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
  1625. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
  1626. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
  1627. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
  1628. // round 7
  1629. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
  1630. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
  1631. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
  1632. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
  1633. // round 8
  1634. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
  1635. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
  1636. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
  1637. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
  1638. // round 9
  1639. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
  1640. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
  1641. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
  1642. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
  1643. if(_rounds>10)
  1644. {
  1645. // round 10
  1646. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
  1647. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
  1648. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
  1649. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
  1650. // round 11
  1651. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
  1652. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
  1653. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
  1654. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
  1655. if(_rounds>12)
  1656. {
  1657. // round 12
  1658. s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
  1659. s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
  1660. s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
  1661. s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
  1662. // round 13
  1663. t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
  1664. t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
  1665. t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
  1666. t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
  1667. }
  1668. }
  1669. rk+=_rounds<<2;
  1670. #endif
  1671. // apply last round and map cipher state to byte array block
  1672. s0 = ((U32)Td4[(t0 >> 24)] << 24) ^ ((U32)Td4[(t3 >> 16) & 0xff] << 16) ^ ((U32)Td4[(t2 >> 8) & 0xff] << 8) ^ ((U32)Td4[(t1) & 0xff]) ^ rk[0]; PUTU32(out , s0);
  1673. s1 = ((U32)Td4[(t1 >> 24)] << 24) ^ ((U32)Td4[(t0 >> 16) & 0xff] << 16) ^ ((U32)Td4[(t3 >> 8) & 0xff] << 8) ^ ((U32)Td4[(t2) & 0xff]) ^ rk[1]; PUTU32(out+ 4, s1);
  1674. s2 = ((U32)Td4[(t2 >> 24)] << 24) ^ ((U32)Td4[(t1 >> 16) & 0xff] << 16) ^ ((U32)Td4[(t0 >> 8) & 0xff] << 8) ^ ((U32)Td4[(t3) & 0xff]) ^ rk[2]; PUTU32(out+ 8, s2);
  1675. s3 = ((U32)Td4[(t3 >> 24)] << 24) ^ ((U32)Td4[(t2 >> 16) & 0xff] << 16) ^ ((U32)Td4[(t1 >> 8) & 0xff] << 8) ^ ((U32)Td4[(t0) & 0xff]) ^ rk[3]; PUTU32(out+12, s3);
  1676. }
  1677. #undef SWAP
  1678. #undef GETU32
  1679. #undef PUTU32
  1680. /******************************************************************************/
  1681. }
  1682. /******************************************************************************/