OverbyteIcsDES.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. {*_* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. Author: François PIETTE
  3. Creation: Sep 03, 2004
  4. Version: 1.00
  5. Description: DES encryption
  6. Credit: Implementation of the Data Encryption Standard (DES) as
  7. described in the book:
  8. Schneier, B., "Applied Cryptography - Protocols Algorithms, and
  9. source code in C", John Wiley & Sons, Inc. 1994.
  10. Original turbo-pascal implementation by Menno Victor van der Star
  11. <s795238@dutiws.twi.tudelft.nl>. His code is available at
  12. http://www.geocities.com/SiliconValley/2926/tpsrc/despas.txt
  13. F. Piette updated the code to use typed parameters.
  14. EMail: francois.piette@overbyte.be http://www.overbyte.be
  15. Support: Use the mailing list twsocket@elists.org
  16. Follow "support" link at http://www.overbyte.be for subscription.
  17. Legal issues: Copyright (C) 2004-2006 by François PIETTE
  18. Rue de Grady 24, 4053 Embourg, Belgium. Fax: +32-4-365.74.56
  19. <francois.piette@overbyte.be>
  20. This software is provided 'as-is', without any express or
  21. implied warranty. In no event will the author be held liable
  22. for any damages arising from the use of this software.
  23. Permission is granted to anyone to use this software for any
  24. purpose, including commercial applications, and to alter it
  25. and redistribute it freely, subject to the following
  26. restrictions:
  27. 1. The origin of this software must not be misrepresented,
  28. you must not claim that you wrote the original software.
  29. If you use this software in a product, an acknowledgment
  30. in the product documentation would be appreciated but is
  31. not required.
  32. 2. Altered source versions must be plainly marked as such, and
  33. must not be misrepresented as being the original software.
  34. 3. This notice may not be removed or altered from any source
  35. distribution.
  36. 4. You must register this software by sending a picture postcard
  37. to the author. Use a nice stamp and mention your name, street
  38. address, EMail address and any comment you like to say.
  39. History:
  40. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  41. unit OverbyteIcsDES;
  42. {$R-}
  43. {$Q-}
  44. {$I OverbyteIcsDefs.inc}
  45. interface
  46. const
  47. IcsDESVersion = 100;
  48. CopyRight : String = ' IcsDES (c) 2004-2006 F. Piette V1.00 ';
  49. type
  50. TArrayOf8Bytes = array [0..7] of Byte;
  51. PArrayOf8Bytes = ^TArrayOf8Bytes;
  52. procedure DES( { Function encrypt/decrypt data using DES algotithm }
  53. const Input : TArrayOf8Bytes; { 64 bit of input }
  54. var Output : TArrayOf8Bytes; { 64 bit output from DES algorithm }
  55. const Key : TArrayOf8Bytes; { 64 bit key for DES algorithm }
  56. Encrypt : Boolean); { TRUE to encrypt, FALSE to decrypt }
  57. implementation
  58. type
  59. TArrayOf16Bytes = array [1..16] of Byte;
  60. TArrayOf28Bytes = array [1..28] of Byte;
  61. TArrayOf32Bytes = array [1..32] of Byte;
  62. TArrayOf48Bytes = array [1..48] of Byte;
  63. TArrayOf56Bytes = array [1..56] of Byte;
  64. TArrayOf64Bytes = array [1..64] of Byte;
  65. TDesData = record
  66. InputValue : TArrayOf64Bytes;
  67. OutputValue : TArrayOf64Bytes;
  68. RoundKeys : array [1..16] of TArrayOf48Bytes;
  69. L, R : TArrayOf32Bytes;
  70. FunctionResult : TArrayOf32Bytes;
  71. C, D : TArrayOf28Bytes;
  72. end;
  73. const
  74. { Initial Permutation }
  75. IP : TArrayOf64Bytes = (58, 50, 42, 34, 26, 18, 10, 2,
  76. 60, 52, 44, 36, 28, 20, 12, 4,
  77. 62, 54, 46, 38, 30, 22, 14, 6,
  78. 64, 56, 48, 40, 32, 24, 16, 8,
  79. 57, 49, 41, 33, 25, 17, 9, 1,
  80. 59, 51, 43, 35, 27, 19, 11, 3,
  81. 61, 53, 45, 37, 29, 21, 13, 5,
  82. 63, 55, 47, 39, 31, 23, 15, 7);
  83. { Final Permutation }
  84. InvIP : TArrayOf64Bytes = (40, 8, 48, 16, 56, 24, 64, 32,
  85. 39, 7, 47, 15, 55, 23, 63, 31,
  86. 38, 6, 46, 14, 54, 22, 62, 30,
  87. 37, 5, 45, 13, 53, 21, 61, 29,
  88. 36, 4, 44, 12, 52, 20, 60, 28,
  89. 35, 3, 43, 11, 51, 19, 59, 27,
  90. 34, 2, 42, 10, 50, 18, 58, 26,
  91. 33, 1, 41, 9, 49, 17, 57, 25);
  92. { Expansion Permutation }
  93. E : TArrayOf48Bytes = (32, 1, 2, 3, 4, 5,
  94. 4, 5, 6, 7, 8, 9,
  95. 8, 9, 10, 11, 12, 13,
  96. 12, 13, 14, 15, 16, 17,
  97. 16, 17, 18, 19, 20, 21,
  98. 20, 21, 22, 23, 24, 25,
  99. 24, 25, 26, 27, 28, 29,
  100. 28, 29, 30, 31, 32, 1);
  101. { P-Box permutation }
  102. P : TArrayOf32Bytes = (16, 7, 20, 21, 29, 12, 28, 17,
  103. 1, 15, 23, 26, 5, 18, 31, 10,
  104. 2, 8, 24, 14, 32, 27, 3, 9,
  105. 19, 13, 30, 6, 22, 11, 4, 25);
  106. { Key Permutation }
  107. PC_1 : TArrayOf56Bytes = (57, 49, 41, 33, 25, 17, 9,
  108. 1, 58, 50, 42, 34, 26, 18,
  109. 10, 2, 59, 51, 43, 35, 27,
  110. 19, 11, 3, 60, 52, 44, 36,
  111. 63, 55, 47, 39, 31, 23, 15,
  112. 7, 62, 54, 46, 38, 30, 22,
  113. 14, 6, 61, 53, 45, 37, 29,
  114. 21, 13, 5, 28, 20, 12, 4);
  115. { Compression Permutation }
  116. PC_2 : TArrayOf48Bytes = (14, 17, 11, 24, 1, 5,
  117. 3, 28, 15, 6, 21, 10,
  118. 23, 19, 12, 4, 26, 8,
  119. 16, 7, 27, 20, 13, 2,
  120. 41, 52, 31, 37, 47, 55,
  121. 30, 40, 51, 45, 33, 48,
  122. 44, 49, 39, 56, 34, 53,
  123. 46, 42, 50, 36, 29, 32);
  124. { Number of key bits shifted per round }
  125. ST : TArrayOf16Bytes = ( 1, 1, 2, 2, 2, 2, 2, 2,
  126. 1, 2, 2, 2, 2, 2, 2, 1);
  127. { S-Boxes }
  128. SBoxes : array [1..8, 0..3, 0..15] of Byte =
  129. (((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7),
  130. ( 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8),
  131. ( 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0),
  132. (15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13)),
  133. ((15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10),
  134. ( 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5),
  135. ( 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15),
  136. (13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9)),
  137. ((10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8),
  138. (13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1),
  139. (13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7),
  140. ( 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12)),
  141. ((7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15),
  142. (13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9),
  143. (10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4),
  144. ( 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14)),
  145. ((2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9),
  146. (14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6),
  147. ( 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14),
  148. (11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3)),
  149. ((12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11),
  150. (10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8),
  151. ( 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6),
  152. ( 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13)),
  153. ((4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1),
  154. (13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6),
  155. ( 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2),
  156. ( 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12)),
  157. ((13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7),
  158. ( 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2),
  159. ( 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8),
  160. ( 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)));
  161. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  162. function GetBit(const Bits: TArrayOf8Bytes; Index: Byte): Byte;
  163. begin
  164. Dec(Index);
  165. if Bits[Index div 8] and (128 shr(Index mod 8)) > 0 then
  166. Result := 1
  167. else
  168. Result := 0;
  169. end;
  170. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  171. procedure SetBit(var Bits: TArrayOf8Bytes; Index, Value : Byte);
  172. var
  173. Bit: Byte;
  174. begin
  175. Dec(Index);
  176. Bit := 128 shr(Index mod 8);
  177. case Value of
  178. 0: Bits[Index div 8] := Bits[Index div 8] and (not Bit);
  179. 1: Bits[Index div 8] := Bits[Index div 8] or Bit;
  180. end;
  181. end;
  182. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  183. procedure F(
  184. var FR : TArrayOf32Bytes;
  185. var FK : TArrayOf48Bytes;
  186. var TotalOut : TArrayOf32Bytes);
  187. var
  188. Temp1 : TArrayOf48Bytes;
  189. Temp2 : TArrayOf32Bytes;
  190. n, h, i, j, Row, Column : Integer;
  191. begin
  192. for n := 1 to 48 do
  193. Temp1[n] := FR[E[n]] xor FK[n];
  194. for n := 1 to 8 do begin
  195. i := (n - 1) * 6;
  196. j := (n - 1) * 4;
  197. Row := Temp1[i + 1] * 2 + Temp1[i + 6];
  198. Column := Temp1[i + 2] * 8 + Temp1[i + 3] * 4 +
  199. Temp1[i + 4] * 2 + Temp1[i + 5];
  200. for h := 1 to 4 Do begin
  201. case h of
  202. 1: Temp2[j + h] := (SBoxes[n, Row, Column] and 8) div 8;
  203. 2: Temp2[j + h] := (SBoxes[n, Row, Column] and 4) div 4;
  204. 3: Temp2[j + h] := (SBoxes[n, Row, Column] and 2) div 2;
  205. 4: Temp2[j + h] := (SBoxes[n, Row, Column] and 1);
  206. end;
  207. end;
  208. end;
  209. for n := 1 to 32 do
  210. TotalOut[n] := Temp2[P[n]];
  211. end;
  212. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  213. procedure Shift(var SubKeyPart : TArrayOf28Bytes);
  214. var
  215. n, b: Byte;
  216. begin
  217. b := SubKeyPart[1];
  218. for n := 1 to 27 do
  219. SubKeyPart[n] := SubKeyPart[n + 1];
  220. SubKeyPart[28] := b;
  221. end;
  222. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  223. procedure SubKey(
  224. var DesData : TDesData;
  225. Round : Byte;
  226. var SubKey : TArrayOf48Bytes);
  227. var
  228. n, b : Byte;
  229. begin
  230. for n := 1 to ST[Round] do begin
  231. Shift(DesData.C);
  232. Shift(DesData.D);
  233. end;
  234. for n := 1 to 48 do begin
  235. b := PC_2[n];
  236. if b <= 28 then
  237. SubKey[n] := DesData.C[b]
  238. else
  239. SubKey[n] := DesData.D[b - 28];
  240. end;
  241. end;
  242. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  243. procedure DES(
  244. const Input : TArrayOf8Bytes;
  245. var Output : TArrayOf8Bytes;
  246. const Key : TArrayOf8Bytes;
  247. Encrypt : Boolean);
  248. var
  249. n, b, Round : Byte;
  250. DesData : TDesData;
  251. begin
  252. for n := 1 to 64 do
  253. DesData.InputValue[n] := GetBit(Input, n);
  254. for n := 1 to 28 do begin
  255. DesData.C[n] := GetBit(Key, PC_1[n]);
  256. DesData.D[n] := GetBit(Key, PC_1[n + 28]);
  257. end;
  258. for n := 1 to 16 do
  259. SubKey(DesData, n, DesData.RoundKeys[n]);
  260. for n := 1 to 64 do begin
  261. if n <= 32 then
  262. DesData.L[n] := DesData.InputValue[IP[n]]
  263. else
  264. DesData.R[n - 32] := DesData.InputValue[IP[n]];
  265. end;
  266. for Round := 1 to 16 do begin
  267. if Encrypt then
  268. F(DesData.R, DesData.RoundKeys[Round], DesData.FunctionResult)
  269. else
  270. F(DesData.R, DesData.RoundKeys[17 - Round], DesData.FunctionResult);
  271. for n := 1 to 32 do
  272. DesData.FunctionResult[n] := DesData.FunctionResult[n] xor DesData.L[n];
  273. DesData.L := DesData.R;
  274. DesData.R := DesData.FunctionResult;
  275. end;
  276. for n := 1 to 64 do begin
  277. b := InvIP[n];
  278. if b <= 32 then
  279. DesData.OutputValue[n] := DesData.R[b]
  280. else
  281. DesData.OutputValue[n] := DesData.L[b-32];
  282. end;
  283. for n := 1 to 64 do
  284. SetBit(Output, n, DesData.OutputValue[n]);
  285. end;
  286. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  287. end.