DCPcast128.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Cast128 ******************************}
  5. {******************************************************************************}
  6. {* Copyright (c) 1999-2002 David Barton *}
  7. {* Permission is hereby granted, free of charge, to any person obtaining a *}
  8. {* copy of this software and associated documentation files (the "Software"), *}
  9. {* to deal in the Software without restriction, including without limitation *}
  10. {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *}
  11. {* and/or sell copies of the Software, and to permit persons to whom the *}
  12. {* Software is furnished to do so, subject to the following conditions: *}
  13. {* *}
  14. {* The above copyright notice and this permission notice shall be included in *}
  15. {* all copies or substantial portions of the Software. *}
  16. {* *}
  17. {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
  18. {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *}
  19. {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *}
  20. {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
  21. {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *}
  22. {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *}
  23. {* DEALINGS IN THE SOFTWARE. *}
  24. {******************************************************************************}
  25. unit DCPcast128;
  26. interface
  27. uses
  28. Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  29. type
  30. TDCP_cast128= class(TDCP_blockcipher64)
  31. protected
  32. KeyData: array[0..31] of DWord;
  33. Rounds: longword;
  34. procedure InitKey(const Key; Size: longword); override;
  35. public
  36. class function GetID: integer; override;
  37. class function GetAlgorithm: string; override;
  38. class function GetMaxKeySize: integer; override;
  39. class function SelfTest: boolean; override;
  40. procedure Burn; override;
  41. procedure EncryptECB(const InData; var OutData); override;
  42. procedure DecryptECB(const InData; var OutData); override;
  43. end;
  44. {******************************************************************************}
  45. {******************************************************************************}
  46. implementation
  47. {$R-}{$Q-}
  48. {$I DCPcast128.inc}
  49. function LRot32(a, n: dword): dword;
  50. begin
  51. Result:= (a shl n) or (a shr (32-n));
  52. end;
  53. class function TDCP_cast128.GetMaxKeySize: integer;
  54. begin
  55. Result:= 128;
  56. end;
  57. class function TDCP_cast128.GetID: integer;
  58. begin
  59. Result:= DCP_cast128;
  60. end;
  61. class function TDCP_cast128.GetAlgorithm: string;
  62. begin
  63. Result:= 'Cast128';
  64. end;
  65. class function TDCP_cast128.SelfTest: boolean;
  66. const
  67. Key: array[0..15] of byte=
  68. ($01,$23,$45,$67,$12,$34,$56,$78,$23,$45,$67,$89,$34,$56,$78,$9A);
  69. InBlock: array[0..7] of byte=
  70. ($01,$23,$45,$67,$89,$AB,$CD,$EF);
  71. Out128: array[0..7] of byte=
  72. ($23,$8B,$4F,$E5,$84,$7E,$44,$B2);
  73. Out80: array[0..7] of byte=
  74. ($EB,$6A,$71,$1A,$2C,$02,$27,$1B);
  75. Out40: array[0..7] of byte=
  76. ($7A,$C8,$16,$D1,$6E,$9B,$30,$2E);
  77. var
  78. Block: array[0..7] of byte;
  79. Cipher: TDCP_cast128;
  80. begin
  81. Cipher:= TDCP_cast128.Create(nil);
  82. Cipher.Init(Key,128,nil);
  83. Cipher.EncryptECB(InBlock,Block);
  84. Result:= boolean(CompareMem(@Block,@Out128,8));
  85. Cipher.DecryptECB(Block,Block);
  86. Result:= Result and boolean(CompareMem(@Block,@InBlock,8));
  87. Cipher.Burn;
  88. Cipher.Init(Key,80,nil);
  89. Cipher.EncryptECB(InBlock,Block);
  90. Result:= Result and boolean(CompareMem(@Block,@Out80,8));
  91. Cipher.DecryptECB(Block,Block);
  92. Result:= Result and boolean(CompareMem(@Block,@InBlock,8));
  93. Cipher.Burn;
  94. Cipher.Init(Key,40,nil);
  95. Cipher.EncryptECB(InBlock,Block);
  96. Result:= Result and boolean(CompareMem(@Block,@Out40,8));
  97. Cipher.DecryptECB(Block,Block);
  98. Result:= Result and boolean(CompareMem(@Block,@InBlock,8));
  99. Cipher.Burn;
  100. Cipher.Free;
  101. end;
  102. procedure TDCP_cast128.InitKey(const Key; Size: longword);
  103. var
  104. x, t, z: array[0..3] of DWord;
  105. i: longword;
  106. begin
  107. Size:= Size div 8;
  108. if Size<= 10 then
  109. Rounds:= 12
  110. else
  111. Rounds:= 16;
  112. FillChar(x,Sizeof(x),0);
  113. Move(Key,x,Size);
  114. x[0]:= (x[0] shr 24) or ((x[0] shr 8) and $FF00) or ((x[0] shl 8) and $FF0000) or (x[0] shl 24);
  115. x[1]:= (x[1] shr 24) or ((x[1] shr 8) and $FF00) or ((x[1] shl 8) and $FF0000) or (x[1] shl 24);
  116. x[2]:= (x[2] shr 24) or ((x[2] shr 8) and $FF00) or ((x[2] shl 8) and $FF0000) or (x[2] shl 24);
  117. x[3]:= (x[3] shr 24) or ((x[3] shr 8) and $FF00) or ((x[3] shl 8) and $FF0000) or (x[3] shl 24);
  118. i:= 0;
  119. while i< 32 do
  120. begin
  121. case (i and 4) of
  122. 0:
  123. begin
  124. z[0]:= x[0] xor cast_sbox5[(x[3] shr 16) and $FF] xor
  125. cast_sbox6[x[3] and $FF] xor cast_sbox7[x[3] shr 24] xor
  126. cast_sbox8[(x[3] shr 8) and $FF] xor cast_sbox7[x[2] shr 24];
  127. t[0]:= z[0];
  128. z[1]:= x[2] xor cast_sbox5[z[0] shr 24] xor
  129. cast_sbox6[(z[0] shr 8) and $FF] xor cast_sbox7[(z[0] shr 16) and $FF] xor
  130. cast_sbox8[z[0] and $FF] xor cast_sbox8[(x[2] shr 8) and $FF];
  131. t[1]:= z[1];
  132. z[2]:= x[3] xor cast_sbox5[z[1] and $FF] xor
  133. cast_sbox6[(z[1] shr 8) and $FF] xor cast_sbox7[(z[1] shr 16) and $FF] xor
  134. cast_sbox8[z[1] shr 24] xor cast_sbox5[(x[2] shr 16) and $FF];
  135. t[2]:= z[2];
  136. z[3]:= x[1] xor cast_sbox5[(z[2] shr 8) and $FF] xor
  137. cast_sbox6[(z[2] shr 16) and $FF] xor cast_sbox7[z[2] and $FF] xor
  138. cast_sbox8[z[2] shr 24] xor cast_sbox6[x[2] and $FF];
  139. t[3]:= z[3];
  140. end;
  141. 4:
  142. begin
  143. x[0]:= z[2] xor cast_sbox5[(z[1] shr 16) and $FF] xor
  144. cast_sbox6[z[1] and $FF] xor cast_sbox7[z[1] shr 24] xor
  145. cast_sbox8[(z[1] shr 8) and $FF] xor cast_sbox7[z[0] shr 24];
  146. t[0]:= x[0];
  147. x[1]:= z[0] xor cast_sbox5[x[0] shr 24] xor
  148. cast_sbox6[(x[0] shr 8) and $FF] xor cast_sbox7[(x[0] shr 16) and $FF] xor
  149. cast_sbox8[x[0] and $FF] xor cast_sbox8[(z[0] shr 8) and $FF];
  150. t[1]:= x[1];
  151. x[2]:= z[1] xor cast_sbox5[x[1] and $FF] xor
  152. cast_sbox6[(x[1] shr 8) and $FF] xor cast_sbox7[(x[1] shr 16) and $FF] xor
  153. cast_sbox8[x[1] shr 24] xor cast_sbox5[(z[0] shr 16) and $FF];
  154. t[2]:= x[2];
  155. x[3]:= z[3] xor cast_sbox5[(x[2] shr 8) and $FF] xor
  156. cast_sbox6[(x[2] shr 16) and $FF] xor cast_sbox7[x[2] and $FF] xor
  157. cast_sbox8[x[2] shr 24] xor cast_sbox6[z[0] and $FF];
  158. t[3]:= x[3];
  159. end;
  160. end;
  161. case (i and 12) of
  162. 0,12:
  163. begin
  164. KeyData[i+0]:= cast_sbox5[t[2] shr 24] xor cast_sbox6[(t[2] shr 16) and $FF] xor
  165. cast_sbox7[t[1] and $FF] xor cast_sbox8[(t[1] shr 8) and $FF];
  166. KeyData[i+1]:= cast_sbox5[(t[2] shr 8) and $FF] xor cast_sbox6[t[2] and $FF] xor
  167. cast_sbox7[(t[1] shr 16) and $FF] xor cast_sbox8[t[1] shr 24];
  168. KeyData[i+2]:= cast_sbox5[t[3] shr 24] xor cast_sbox6[(t[3] shr 16) and $FF] xor
  169. cast_sbox7[t[0] and $FF] xor cast_sbox8[(t[0] shr 8) and $FF];
  170. KeyData[i+3]:= cast_sbox5[(t[3] shr 8) and $FF] xor cast_sbox6[t[3] and $FF] xor
  171. cast_sbox7[(t[0] shr 16) and $FF] xor cast_sbox8[t[0] shr 24];
  172. end;
  173. 4,8:
  174. begin
  175. KeyData[i+0]:= cast_sbox5[t[0] and $FF] xor cast_sbox6[(t[0] shr 8) and $FF] xor
  176. cast_sbox7[t[3] shr 24] xor cast_sbox8[(t[3] shr 16) and $FF];
  177. KeyData[i+1]:= cast_sbox5[(t[0] shr 16) and $FF] xor cast_sbox6[t[0] shr 24] xor
  178. cast_sbox7[(t[3] shr 8) and $FF] xor cast_sbox8[t[3] and $FF];
  179. KeyData[i+2]:= cast_sbox5[t[1] and $FF] xor cast_sbox6[(t[1] shr 8) and $FF] xor
  180. cast_sbox7[t[2] shr 24] xor cast_sbox8[(t[2] shr 16) and $FF];
  181. KeyData[i+3]:= cast_sbox5[(t[1] shr 16) and $FF] xor cast_sbox6[t[1] shr 24] xor
  182. cast_sbox7[(t[2] shr 8) and $FF] xor cast_sbox8[t[2] and $FF];
  183. end;
  184. end;
  185. case (i and 12) of
  186. 0:
  187. begin
  188. KeyData[i+0]:= KeyData[i+0] xor cast_sbox5[(z[0] shr 8) and $FF];
  189. KeyData[i+1]:= KeyData[i+1] xor cast_sbox6[(z[1] shr 8) and $FF];
  190. KeyData[i+2]:= KeyData[i+2] xor cast_sbox7[(z[2] shr 16) and $FF];
  191. KeyData[i+3]:= KeyData[i+3] xor cast_sbox8[z[3] shr 24];
  192. end;
  193. 4:
  194. begin
  195. KeyData[i+0]:= KeyData[i+0] xor cast_sbox5[x[2] shr 24];
  196. KeyData[i+1]:= KeyData[i+1] xor cast_sbox6[(x[3] shr 16) and $FF];
  197. KeyData[i+2]:= KeyData[i+2] xor cast_sbox7[x[0] and $FF];
  198. KeyData[i+3]:= KeyData[i+3] xor cast_sbox8[x[1] and $FF];
  199. end;
  200. 8:
  201. begin
  202. KeyData[i+0]:= KeyData[i+0] xor cast_sbox5[(z[2] shr 16) and $FF];
  203. KeyData[i+1]:= KeyData[i+1] xor cast_sbox6[z[3] shr 24];
  204. KeyData[i+2]:= KeyData[i+2] xor cast_sbox7[(z[0] shr 8) and $FF];
  205. KeyData[i+3]:= KeyData[i+3] xor cast_sbox8[(z[1] shr 8) and $FF];
  206. end;
  207. 12:
  208. begin
  209. KeyData[i+0]:= KeyData[i+0] xor cast_sbox5[x[0] and $FF];
  210. KeyData[i+1]:= KeyData[i+1] xor cast_sbox6[x[1] and $FF];
  211. KeyData[i+2]:= KeyData[i+2] xor cast_sbox7[x[2] shr 24];
  212. KeyData[i+3]:= KeyData[i+3] xor cast_sbox8[(x[3] shr 16) and $FF];
  213. end;
  214. end;
  215. if (i >= 16) then
  216. begin
  217. KeyData[i+0]:= KeyData[i+0] and 31;
  218. KeyData[i+1]:= KeyData[i+1] and 31;
  219. KeyData[i+2]:= KeyData[i+2] and 31;
  220. KeyData[i+3]:= KeyData[i+3] and 31;
  221. end;
  222. Inc(i,4);
  223. end;
  224. end;
  225. procedure TDCP_cast128.Burn;
  226. begin
  227. FillChar(KeyData,Sizeof(KeyData),$FF);
  228. Rounds:= 0;
  229. inherited Burn;
  230. end;
  231. procedure TDCP_cast128.EncryptECB(const InData; var OutData);
  232. var
  233. t, l, r: DWord;
  234. begin
  235. if not fInitialized then
  236. raise EDCP_blockcipher.Create('Cipher not initialized');
  237. l:= Pdword(@InData)^;
  238. r:= Pdword(longword(@InData)+4)^;
  239. l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
  240. r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
  241. t:= LRot32(KeyData[0]+r, KeyData[0+16]);
  242. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  243. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  244. t:= LRot32(KeyData[1] xor l, KeyData[1+16]);
  245. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  246. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  247. t:= LRot32(KeyData[2]-r, KeyData[2+16]);
  248. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  249. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  250. t:= LRot32(KeyData[3]+l, KeyData[3+16]);
  251. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  252. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  253. t:= LRot32(KeyData[4] xor r, KeyData[4+16]);
  254. l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  255. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  256. t:= LRot32(KeyData[5]-l, KeyData[5+16]);
  257. r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  258. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  259. t:= LRot32(KeyData[6]+r, KeyData[6+16]);
  260. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  261. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  262. t:= LRot32(KeyData[7] xor l, KeyData[7+16]);
  263. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  264. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  265. t:= LRot32(KeyData[8]-r, KeyData[8+16]);
  266. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  267. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  268. t:= LRot32(KeyData[9]+l, KeyData[9+16]);
  269. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  270. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  271. t:= LRot32(KeyData[10] xor r, KeyData[10+16]);
  272. l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  273. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  274. t:= LRot32(KeyData[11]-l, KeyData[11+16]);
  275. r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  276. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  277. if Rounds> 12 then
  278. begin
  279. t:= LRot32(KeyData[12]+r, KeyData[12+16]);
  280. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  281. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  282. t:= LRot32(KeyData[13] xor l, KeyData[13+16]);
  283. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  284. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  285. t:= LRot32(KeyData[14]-r, KeyData[14+16]);
  286. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  287. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  288. t:= LRot32(KeyData[15]+l, KeyData[15+16]);
  289. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  290. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  291. end;
  292. l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
  293. r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
  294. Pdword(@OutData)^:= r;
  295. Pdword(longword(@OutData)+4)^:= l;
  296. end;
  297. procedure TDCP_cast128.DecryptECB(const InData; var OutData);
  298. var
  299. t, l, r: DWord;
  300. begin
  301. if not fInitialized then
  302. raise EDCP_blockcipher.Create('Cipher not initialized');
  303. r:= Pdword(@InData)^;
  304. l:= Pdword(longword(@InData)+4)^;
  305. l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
  306. r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
  307. if Rounds> 12 then
  308. begin
  309. t:= LRot32(KeyData[15]+l, KeyData[15+16]);
  310. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  311. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  312. t:= LRot32(KeyData[14]-r, KeyData[14+16]);
  313. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  314. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  315. t:= LRot32(KeyData[13] xor l, KeyData[13+16]);
  316. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  317. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  318. t:= LRot32(KeyData[12]+r, KeyData[12+16]);
  319. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  320. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  321. end;
  322. t:= LRot32(KeyData[11]-l, KeyData[11+16]);
  323. r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  324. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  325. t:= LRot32(KeyData[10] xor r, KeyData[10+16]);
  326. l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  327. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  328. t:= LRot32(KeyData[9]+l, KeyData[9+16]);
  329. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  330. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  331. t:= LRot32(KeyData[8]-r, KeyData[8+16]);
  332. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  333. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  334. t:= LRot32(KeyData[7] xor l, KeyData[7+16]);
  335. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  336. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  337. t:= LRot32(KeyData[6]+r, KeyData[6+16]);
  338. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  339. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  340. t:= LRot32(KeyData[5]-l, KeyData[5+16]);
  341. r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  342. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  343. t:= LRot32(KeyData[4] xor r, KeyData[4+16]);
  344. l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  345. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  346. t:= LRot32(KeyData[3]+l, KeyData[3+16]);
  347. r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  348. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  349. t:= LRot32(KeyData[2]-r, KeyData[2+16]);
  350. l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
  351. cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
  352. t:= LRot32(KeyData[1] xor l, KeyData[1+16]);
  353. r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
  354. cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
  355. t:= LRot32(KeyData[0]+r, KeyData[0+16]);
  356. l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
  357. cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
  358. l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
  359. r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
  360. Pdword(@OutData)^:= l;
  361. Pdword(longword(@OutData)+4)^:= r;
  362. end;
  363. end.