DCPcast256.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Cast256 ******************************}
  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 DCPcast256;
  26. interface
  27. uses
  28. Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  29. type
  30. TDCP_cast256= class(TDCP_blockcipher128)
  31. protected
  32. Kr, Km: array[0..11,0..3] of DWord;
  33. procedure InitKey(const Key; Size: longword); override;
  34. public
  35. class function GetId: integer; override;
  36. class function GetAlgorithm: string; override;
  37. class function GetMaxKeySize: integer; override;
  38. class function SelfTest: boolean; override;
  39. procedure Burn; override;
  40. procedure EncryptECB(const InData; var OutData); override;
  41. procedure DecryptECB(const InData; var OutData); override;
  42. end;
  43. {******************************************************************************}
  44. {******************************************************************************}
  45. implementation
  46. {$R-}{$Q-}
  47. {$I DCPcast256.inc}
  48. function LRot32(a, n: dword): dword;
  49. begin
  50. Result:= (a shl n) or (a shr (32-n));
  51. end;
  52. function SwapDword(a: dword): dword;
  53. begin
  54. Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
  55. end;
  56. function F1(a,rk,mk: DWord): DWord;
  57. var
  58. t: DWord;
  59. begin
  60. t:= LRot32(mk + a,rk);
  61. Result:= ((S1[t shr 24] xor S2[(t shr 16) and $FF]) - S3[(t shr 8) and $FF]) + S4[t and $FF];
  62. end;
  63. function F2(a,rk,mk: DWord): DWord;
  64. var
  65. t: DWord;
  66. begin
  67. t:= LRot32(mk xor a,rk);
  68. Result:= ((S1[t shr 24] - S2[(t shr 16) and $FF]) + S3[(t shr 8) and $FF]) xor S4[t and $FF];
  69. end;
  70. function F3(a,rk,mk: DWord): DWord;
  71. var
  72. t: DWord;
  73. begin
  74. t:= LRot32(mk - a,rk);
  75. Result:= ((S1[t shr 24] + S2[(t shr 16) and $FF]) xor S3[(t shr 8) and $FF]) - S4[t and $FF];
  76. end;
  77. class function TDCP_cast256.GetMaxKeySize: integer;
  78. begin
  79. Result:= 256;
  80. end;
  81. class function TDCP_cast256.GetId: integer;
  82. begin
  83. Result:= DCP_cast256;
  84. end;
  85. class function TDCP_cast256.GetAlgorithm: string;
  86. begin
  87. Result:= 'Cast256';
  88. end;
  89. class function TDCP_cast256.SelfTest: boolean;
  90. const
  91. Key1: array[0..15] of byte=
  92. ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$0a,$f7,$56,$47,$f2,$9f,$61,$5d);
  93. InBlock1: array[0..15] of byte=
  94. ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0c,$9b,$28,$07);
  95. OutBlock1: array[0..15] of byte=
  96. ($96,$3a,$8a,$50,$ce,$b5,$4d,$08,$e0,$de,$e0,$f1,$d0,$41,$3d,$cf);
  97. Key2: array[0..23] of byte=
  98. ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$be,$d0,$ac,$83,$94,$0a,$c2,$98,$ba,$c7,$7a,$77,$17,$94,$28,$63);
  99. InBlock2: array[0..15] of byte=
  100. ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$de,$25,$5a,$ff);
  101. OutBlock2: array[0..15] of byte=
  102. ($2b,$c1,$92,$9f,$30,$13,$47,$a9,$9d,$3f,$3e,$45,$ad,$34,$01,$e8);
  103. Key3: array[0..31] of byte=
  104. ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$be,$d0,$ac,$83,$94,$0a,$c2,$98,$8d,$7c,$47,$ce,$26,$49,$08,$46,$1c,$c1,$b5,$13,$7a,$e6,$b6,$04);
  105. InBlock3: array[0..15] of byte=
  106. ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c5,$fc,$eb,$19);
  107. OutBlock3: array[0..15] of byte=
  108. ($1e,$2e,$bc,$6c,$9f,$2e,$43,$8e,$1d,$90,$d9,$b9,$c6,$85,$32,$86);
  109. var
  110. Block: array[0..15] of byte;
  111. Cipher: TDCP_cast256;
  112. begin
  113. Cipher:= TDCP_cast256.Create(nil);
  114. Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  115. Cipher.EncryptECB(InBlock1,Block);
  116. Result:= boolean(CompareMem(@Block,@OutBlock1,8));
  117. Cipher.DecryptECB(Block,Block);
  118. Result:= Result and boolean(CompareMem(@Block,@InBlock1,16));
  119. Cipher.Burn;
  120. Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  121. Cipher.EncryptECB(InBlock2,Block);
  122. Result:= Result and boolean(CompareMem(@Block,@OutBlock2,8));
  123. Cipher.DecryptECB(Block,Block);
  124. Result:= Result and boolean(CompareMem(@Block,@InBlock2,16));
  125. Cipher.Burn;
  126. Cipher.Init(Key3,Sizeof(Key3)*8,nil);
  127. Cipher.EncryptECB(InBlock3,Block);
  128. Result:= Result and boolean(CompareMem(@Block,@OutBlock3,8));
  129. Cipher.DecryptECB(Block,Block);
  130. Result:= Result and boolean(CompareMem(@Block,@InBlock3,16));
  131. Cipher.Burn;
  132. Cipher.Free;
  133. end;
  134. procedure TDCP_cast256.InitKey(const Key; Size: longword);
  135. var
  136. x: array[0..7] of DWord;
  137. cm, cr: DWord;
  138. i, j: longword;
  139. tr, tm: array[0..7] of DWord;
  140. begin
  141. Size:= Size div 8;
  142. FillChar(x,Sizeof(x),0);
  143. Move(Key,x,Size);
  144. cm:= $5a827999;
  145. cr:= 19;
  146. for i:= 0 to 7 do
  147. x[i]:= (x[i] shl 24) or ((x[i] shl 8) and $FF0000) or ((x[i] shr 8) and $FF00) or (x[i] shr 24);
  148. for i:= 0 to 11 do
  149. begin
  150. for j:= 0 to 7 do
  151. begin
  152. tm[j]:= cm;
  153. Inc(cm,$6ed9eba1);
  154. tr[j]:= cr;
  155. Inc(cr,17);
  156. end;
  157. x[6]:= x[6] xor f1(x[7],tr[0],tm[0]);
  158. x[5]:= x[5] xor f2(x[6],tr[1],tm[1]);
  159. x[4]:= x[4] xor f3(x[5],tr[2],tm[2]);
  160. x[3]:= x[3] xor f1(x[4],tr[3],tm[3]);
  161. x[2]:= x[2] xor f2(x[3],tr[4],tm[4]);
  162. x[1]:= x[1] xor f3(x[2],tr[5],tm[5]);
  163. x[0]:= x[0] xor f1(x[1],tr[6],tm[6]);
  164. x[7]:= x[7] xor f2(x[0],tr[7],tm[7]);
  165. for j:= 0 to 7 do
  166. begin
  167. tm[j]:= cm;
  168. Inc(cm,$6ed9eba1);
  169. tr[j]:= cr;
  170. Inc(cr,17);
  171. end;
  172. x[6]:= x[6] xor f1(x[7],tr[0],tm[0]);
  173. x[5]:= x[5] xor f2(x[6],tr[1],tm[1]);
  174. x[4]:= x[4] xor f3(x[5],tr[2],tm[2]);
  175. x[3]:= x[3] xor f1(x[4],tr[3],tm[3]);
  176. x[2]:= x[2] xor f2(x[3],tr[4],tm[4]);
  177. x[1]:= x[1] xor f3(x[2],tr[5],tm[5]);
  178. x[0]:= x[0] xor f1(x[1],tr[6],tm[6]);
  179. x[7]:= x[7] xor f2(x[0],tr[7],tm[7]);
  180. Kr[i,0]:= x[0] and 31;
  181. Kr[i,1]:= x[2] and 31;
  182. Kr[i,2]:= x[4] and 31;
  183. Kr[i,3]:= x[6] and 31;
  184. Km[i,0]:= x[7];
  185. Km[i,1]:= x[5];
  186. Km[i,2]:= x[3];
  187. Km[i,3]:= x[1];
  188. end;
  189. FillChar(x,Sizeof(x),$FF);
  190. end;
  191. procedure TDCP_cast256.Burn;
  192. begin
  193. FillChar(Kr,Sizeof(Kr),$FF);
  194. FillChar(Km,Sizeof(Km),$FF);
  195. inherited Burn;
  196. end;
  197. procedure TDCP_cast256.EncryptECB(const InData; var OutData);
  198. var
  199. A: array[0..3] of DWord;
  200. begin
  201. if not fInitialized then
  202. raise EDCP_blockcipher.Create('Cipher not initialized');
  203. A[0]:= PDWord(@InData)^;
  204. A[1]:= PDWord(longword(@InData)+4)^;
  205. A[2]:= PDWord(longword(@InData)+8)^;
  206. A[3]:= PDWord(longword(@InData)+12)^;
  207. A[0]:= SwapDWord(A[0]);
  208. A[1]:= SwapDWord(A[1]);
  209. A[2]:= SwapDWord(A[2]);
  210. A[3]:= SwapDWord(A[3]);
  211. A[2]:= A[2] xor f1(A[3],kr[0,0],km[0,0]);
  212. A[1]:= A[1] xor f2(A[2],kr[0,1],km[0,1]);
  213. A[0]:= A[0] xor f3(A[1],kr[0,2],km[0,2]);
  214. A[3]:= A[3] xor f1(A[0],kr[0,3],km[0,3]);
  215. A[2]:= A[2] xor f1(A[3],kr[1,0],km[1,0]);
  216. A[1]:= A[1] xor f2(A[2],kr[1,1],km[1,1]);
  217. A[0]:= A[0] xor f3(A[1],kr[1,2],km[1,2]);
  218. A[3]:= A[3] xor f1(A[0],kr[1,3],km[1,3]);
  219. A[2]:= A[2] xor f1(A[3],kr[2,0],km[2,0]);
  220. A[1]:= A[1] xor f2(A[2],kr[2,1],km[2,1]);
  221. A[0]:= A[0] xor f3(A[1],kr[2,2],km[2,2]);
  222. A[3]:= A[3] xor f1(A[0],kr[2,3],km[2,3]);
  223. A[2]:= A[2] xor f1(A[3],kr[3,0],km[3,0]);
  224. A[1]:= A[1] xor f2(A[2],kr[3,1],km[3,1]);
  225. A[0]:= A[0] xor f3(A[1],kr[3,2],km[3,2]);
  226. A[3]:= A[3] xor f1(A[0],kr[3,3],km[3,3]);
  227. A[2]:= A[2] xor f1(A[3],kr[4,0],km[4,0]);
  228. A[1]:= A[1] xor f2(A[2],kr[4,1],km[4,1]);
  229. A[0]:= A[0] xor f3(A[1],kr[4,2],km[4,2]);
  230. A[3]:= A[3] xor f1(A[0],kr[4,3],km[4,3]);
  231. A[2]:= A[2] xor f1(A[3],kr[5,0],km[5,0]);
  232. A[1]:= A[1] xor f2(A[2],kr[5,1],km[5,1]);
  233. A[0]:= A[0] xor f3(A[1],kr[5,2],km[5,2]);
  234. A[3]:= A[3] xor f1(A[0],kr[5,3],km[5,3]);
  235. A[3]:= A[3] xor f1(A[0],kr[6,3],km[6,3]);
  236. A[0]:= A[0] xor f3(A[1],kr[6,2],km[6,2]);
  237. A[1]:= A[1] xor f2(A[2],kr[6,1],km[6,1]);
  238. A[2]:= A[2] xor f1(A[3],kr[6,0],km[6,0]);
  239. A[3]:= A[3] xor f1(A[0],kr[7,3],km[7,3]);
  240. A[0]:= A[0] xor f3(A[1],kr[7,2],km[7,2]);
  241. A[1]:= A[1] xor f2(A[2],kr[7,1],km[7,1]);
  242. A[2]:= A[2] xor f1(A[3],kr[7,0],km[7,0]);
  243. A[3]:= A[3] xor f1(A[0],kr[8,3],km[8,3]);
  244. A[0]:= A[0] xor f3(A[1],kr[8,2],km[8,2]);
  245. A[1]:= A[1] xor f2(A[2],kr[8,1],km[8,1]);
  246. A[2]:= A[2] xor f1(A[3],kr[8,0],km[8,0]);
  247. A[3]:= A[3] xor f1(A[0],kr[9,3],km[9,3]);
  248. A[0]:= A[0] xor f3(A[1],kr[9,2],km[9,2]);
  249. A[1]:= A[1] xor f2(A[2],kr[9,1],km[9,1]);
  250. A[2]:= A[2] xor f1(A[3],kr[9,0],km[9,0]);
  251. A[3]:= A[3] xor f1(A[0],kr[10,3],km[10,3]);
  252. A[0]:= A[0] xor f3(A[1],kr[10,2],km[10,2]);
  253. A[1]:= A[1] xor f2(A[2],kr[10,1],km[10,1]);
  254. A[2]:= A[2] xor f1(A[3],kr[10,0],km[10,0]);
  255. A[3]:= A[3] xor f1(A[0],kr[11,3],km[11,3]);
  256. A[0]:= A[0] xor f3(A[1],kr[11,2],km[11,2]);
  257. A[1]:= A[1] xor f2(A[2],kr[11,1],km[11,1]);
  258. A[2]:= A[2] xor f1(A[3],kr[11,0],km[11,0]);
  259. A[0]:= SwapDWord(A[0]);
  260. A[1]:= SwapDWord(A[1]);
  261. A[2]:= SwapDWord(A[2]);
  262. A[3]:= SwapDWord(A[3]);
  263. PDWord(@OutData)^:= A[0];
  264. PDWord(longword(@OutData)+4)^:= A[1];
  265. PDWord(longword(@OutData)+8)^:= A[2];
  266. PDWord(longword(@OutData)+12)^:= A[3];
  267. end;
  268. procedure TDCP_cast256.DecryptECB(const InData; var OutData);
  269. var
  270. A: array[0..3] of DWord;
  271. begin
  272. if not fInitialized then
  273. raise EDCP_blockcipher.Create('Cipher not initialized');
  274. A[0]:= PDWord(@InData)^;
  275. A[1]:= PDWord(longword(@InData)+4)^;
  276. A[2]:= PDWord(longword(@InData)+8)^;
  277. A[3]:= PDWord(longword(@InData)+12)^;
  278. A[0]:= SwapDWord(A[0]);
  279. A[1]:= SwapDWord(A[1]);
  280. A[2]:= SwapDWord(A[2]);
  281. A[3]:= SwapDWord(A[3]);
  282. A[2]:= A[2] xor f1(A[3],kr[11,0],km[11,0]);
  283. A[1]:= A[1] xor f2(A[2],kr[11,1],km[11,1]);
  284. A[0]:= A[0] xor f3(A[1],kr[11,2],km[11,2]);
  285. A[3]:= A[3] xor f1(A[0],kr[11,3],km[11,3]);
  286. A[2]:= A[2] xor f1(A[3],kr[10,0],km[10,0]);
  287. A[1]:= A[1] xor f2(A[2],kr[10,1],km[10,1]);
  288. A[0]:= A[0] xor f3(A[1],kr[10,2],km[10,2]);
  289. A[3]:= A[3] xor f1(A[0],kr[10,3],km[10,3]);
  290. A[2]:= A[2] xor f1(A[3],kr[9,0],km[9,0]);
  291. A[1]:= A[1] xor f2(A[2],kr[9,1],km[9,1]);
  292. A[0]:= A[0] xor f3(A[1],kr[9,2],km[9,2]);
  293. A[3]:= A[3] xor f1(A[0],kr[9,3],km[9,3]);
  294. A[2]:= A[2] xor f1(A[3],kr[8,0],km[8,0]);
  295. A[1]:= A[1] xor f2(A[2],kr[8,1],km[8,1]);
  296. A[0]:= A[0] xor f3(A[1],kr[8,2],km[8,2]);
  297. A[3]:= A[3] xor f1(A[0],kr[8,3],km[8,3]);
  298. A[2]:= A[2] xor f1(A[3],kr[7,0],km[7,0]);
  299. A[1]:= A[1] xor f2(A[2],kr[7,1],km[7,1]);
  300. A[0]:= A[0] xor f3(A[1],kr[7,2],km[7,2]);
  301. A[3]:= A[3] xor f1(A[0],kr[7,3],km[7,3]);
  302. A[2]:= A[2] xor f1(A[3],kr[6,0],km[6,0]);
  303. A[1]:= A[1] xor f2(A[2],kr[6,1],km[6,1]);
  304. A[0]:= A[0] xor f3(A[1],kr[6,2],km[6,2]);
  305. A[3]:= A[3] xor f1(A[0],kr[6,3],km[6,3]);
  306. A[3]:= A[3] xor f1(A[0],kr[5,3],km[5,3]);
  307. A[0]:= A[0] xor f3(A[1],kr[5,2],km[5,2]);
  308. A[1]:= A[1] xor f2(A[2],kr[5,1],km[5,1]);
  309. A[2]:= A[2] xor f1(A[3],kr[5,0],km[5,0]);
  310. A[3]:= A[3] xor f1(A[0],kr[4,3],km[4,3]);
  311. A[0]:= A[0] xor f3(A[1],kr[4,2],km[4,2]);
  312. A[1]:= A[1] xor f2(A[2],kr[4,1],km[4,1]);
  313. A[2]:= A[2] xor f1(A[3],kr[4,0],km[4,0]);
  314. A[3]:= A[3] xor f1(A[0],kr[3,3],km[3,3]);
  315. A[0]:= A[0] xor f3(A[1],kr[3,2],km[3,2]);
  316. A[1]:= A[1] xor f2(A[2],kr[3,1],km[3,1]);
  317. A[2]:= A[2] xor f1(A[3],kr[3,0],km[3,0]);
  318. A[3]:= A[3] xor f1(A[0],kr[2,3],km[2,3]);
  319. A[0]:= A[0] xor f3(A[1],kr[2,2],km[2,2]);
  320. A[1]:= A[1] xor f2(A[2],kr[2,1],km[2,1]);
  321. A[2]:= A[2] xor f1(A[3],kr[2,0],km[2,0]);
  322. A[3]:= A[3] xor f1(A[0],kr[1,3],km[1,3]);
  323. A[0]:= A[0] xor f3(A[1],kr[1,2],km[1,2]);
  324. A[1]:= A[1] xor f2(A[2],kr[1,1],km[1,1]);
  325. A[2]:= A[2] xor f1(A[3],kr[1,0],km[1,0]);
  326. A[3]:= A[3] xor f1(A[0],kr[0,3],km[0,3]);
  327. A[0]:= A[0] xor f3(A[1],kr[0,2],km[0,2]);
  328. A[1]:= A[1] xor f2(A[2],kr[0,1],km[0,1]);
  329. A[2]:= A[2] xor f1(A[3],kr[0,0],km[0,0]);
  330. A[0]:= SwapDWord(A[0]);
  331. A[1]:= SwapDWord(A[1]);
  332. A[2]:= SwapDWord(A[2]);
  333. A[3]:= SwapDWord(A[3]);
  334. PDWord(@OutData)^:= A[0];
  335. PDWord(longword(@OutData)+4)^:= A[1];
  336. PDWord(longword(@OutData)+8)^:= A[2];
  337. PDWord(longword(@OutData)+12)^:= A[3];
  338. end;
  339. end.