AsphyreXTEA.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:8k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreXTEA;
  2. //---------------------------------------------------------------------------
  3. // AsphyreXTEA.pas                                      Modified: 16-Mar-2006
  4. // XTEA 128-bit cipher using 64-bit block mode                   Version 1.01
  5. // Copyright (c) 2006  Yuriy Kotsarenko (lifepower@mail333.com)
  6. //---------------------------------------------------------------------------
  7. //
  8. // The contents of this file are subject to the Mozilla Public License
  9. // Version 1.1 (the "License"); you may not use this file except in
  10. // compliance with the License. You may obtain a copy of the License at
  11. // http://www.mozilla.org/MPL/
  12. //
  13. // Software distributed under the License is distributed on an "AS IS"
  14. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing rights and limitations
  16. // under the License.
  17. //
  18. //---------------------------------------------------------------------------
  19. //
  20. // For more information about XTEA cipher, visit:
  21. //   http://en.wikipedia.org/wiki/XTEA
  22. //
  23. // Block cipher operation modes are explained at:
  24. //   http://en.wikipedia.org/wiki/Cipher_block_chaining
  25. //
  26. // Thanks to Robert Kosek for providing information about this cipher in the
  27. // following discussion on Afterwarp forums:
  28. //   http://www.afterwarp.net/forum/thread460.html
  29. //
  30. //---------------------------------------------------------------------------
  31. //
  32. // Additional Information
  33. //
  34. // This is an implementation of XTEA block cipher encryption in CBC mode,
  35. // using residual block termination for data that is not 64-bit divisible.
  36. // The cipher code uses extensive parenthesis usage to avoid ambiguity.
  37. //
  38. //---------------------------------------------------------------------------
  39. interface
  40. //---------------------------------------------------------------------------
  41. type
  42.  PBlock64 = ^TBlock64;
  43.  TBlock64 = array[0..1] of Longword;
  44. //---------------------------------------------------------------------------
  45.  PKey128 = ^TKey128;
  46.  TKey128 = array[0..3] of Longword;
  47. //---------------------------------------------------------------------------
  48. // CipherEntryXEA()
  49. //
  50. // Encrypts a single 64-bit block using XTEA cipher.
  51. //---------------------------------------------------------------------------
  52. procedure CipherEntryXTEA(Src, Dest: PBlock64; Key: PKey128);
  53. //---------------------------------------------------------------------------
  54. // DecipherEntryXEA()
  55. //
  56. // Decrypts a single 64-bit block using XTEA cipher.
  57. //---------------------------------------------------------------------------
  58. procedure DecipherEntryXTEA(Src, Dest: PBlock64; Key: PKey128);
  59. //---------------------------------------------------------------------------
  60. // CipherDataXTEA()
  61. //
  62. // Encrypts data using XTEA cipher in CBC chaining mode and residual block
  63. // termination for data not being multiple of 8 bytes.
  64. //---------------------------------------------------------------------------
  65. procedure CipherDataXTEA(Source, Dest: Pointer; Count: Integer;
  66.  Key: PKey128; InitVec: PBlock64);
  67. //---------------------------------------------------------------------------
  68. // DecipherDataXTEA()
  69. //
  70. // Decrypts data using XTEA cipher in CBC chaining mode and residual block
  71. // termination for data not being multiple of 8 bytes.
  72. //---------------------------------------------------------------------------
  73. procedure DecipherDataXTEA(Source, Dest: Pointer; Count: Integer;
  74.  Key: PKey128; InitVec: PBlock64);
  75. //---------------------------------------------------------------------------
  76. implementation
  77. //---------------------------------------------------------------------------
  78. const
  79.  Delta = $9E3779B9;
  80. //---------------------------------------------------------------------------
  81. procedure CipherEntryXTEA(Src, Dest: PBlock64; Key: PKey128);
  82. var
  83.  i: Integer;
  84.  Sum, v0, v1: Longword;
  85. begin
  86.  Sum:= 0;
  87.  v0:= Src[0];
  88.  v1:= Src[1];
  89.  for i:= 0 to 31 do
  90.   begin
  91.    Inc(v0, (((v1 shl 4) xor (v1 shr 5)) + v1) xor (Sum + Key[Sum and 3]));
  92.    Inc(Sum, Delta);
  93.    Inc(v1, (((v0 shl 4) xor (v0 shr 5)) + v0) xor (Sum + Key[(Sum shr 11) and 3]));
  94.   end;
  95.  Dest[0]:= v0;
  96.  Dest[1]:= v1;
  97. end;
  98. //---------------------------------------------------------------------------
  99. procedure DecipherEntryXTEA(Src, Dest: PBlock64; Key: PKey128);
  100. var
  101.  i: Integer;
  102.  Sum, v0, v1: Longword;
  103. begin
  104.  Sum:= $C6EF3720;
  105.  v0:= Src[0];
  106.  v1:= Src[1];
  107.  for i:= 0 to 31 do
  108.   begin
  109.    Dec(v1, (((v0 shl 4) xor (v0 shr 5)) + v0) xor (Sum + Key[(Sum shr 11) and 3]));
  110.    Dec(Sum, Delta);
  111.    Dec(v0, (((v1 shl 4) xor (v1 shr 5)) + v1) xor (Sum + Key[Sum and 3]));
  112.   end;
  113.  Dest[0]:= v0;
  114.  Dest[1]:= v1;
  115. end;
  116. //---------------------------------------------------------------------------
  117. procedure CipherDataXTEA(Source, Dest: Pointer; Count: Integer;
  118.  Key: PKey128; InitVec: PBlock64);
  119. var
  120.  i: Integer;
  121.  SrcBlock : PBlock64;
  122.  DestBlock: PBlock64;
  123.  AuxBlock : TBlock64;
  124.  LastBlock: TBlock64;
  125. begin
  126.  // Apply CBC mode in the block cipher.
  127.  Move(InitVec^, LastBlock, SizeOf(TBlock64));
  128.  SrcBlock := Source;
  129.  DestBlock:= Dest;
  130.  for i:= 0 to (Count div 8) - 1 do
  131.   begin
  132.    AuxBlock[0]:= SrcBlock[0] xor LastBlock[0];
  133.    AuxBlock[1]:= SrcBlock[1] xor LastBlock[1];
  134.    CipherEntryXTEA(@AuxBlock, @LastBlock, Key);
  135.    DestBlock[0]:= LastBlock[0];
  136.    DestBlock[1]:= LastBlock[1];
  137.    Inc(SrcBlock);
  138.    Inc(DestBlock);
  139.   end;
  140.  // Residual block termination.
  141.  if (Count mod 8 > 0) then
  142.   begin
  143.    // Use encrypted IV, if message is too small.
  144.    if (Count < 8) then
  145.     CipherEntryXTEA(InitVec, @LastBlock, Key);
  146.    // Encrypt last block again.
  147.    CipherEntryXTEA(@LastBlock, @LastBlock, Key);
  148.    // Fill the auxiliary block with remaining bytes.
  149.    AuxBlock[0]:= 0;
  150.    AuxBlock[1]:= 0;
  151.    Move(SrcBlock^, AuxBlock, Count mod 8);
  152.    // Encrypt the remaining bytes.
  153.    AuxBlock[0]:= AuxBlock[0] xor LastBlock[0];
  154.    AuxBlock[1]:= AuxBlock[1] xor LastBlock[1];
  155.    // Write the remaining bytes to destination.
  156.    Move(AuxBlock, DestBlock^, Count mod 8);
  157.   end;
  158. end;
  159. //---------------------------------------------------------------------------
  160. procedure DecipherDataXTEA(Source, Dest: Pointer; Count: Integer;
  161.  Key: PKey128; InitVec: PBlock64);
  162. var
  163.  i: Integer;
  164.  SrcBlock : PBlock64;
  165.  DestBlock: PBlock64;
  166.  AuxBlock : TBlock64;
  167.  LastBlock: TBlock64;
  168. begin
  169.  // Apply CBC mode in block cipher.
  170.  Move(InitVec^, LastBlock, SizeOf(TBlock64));
  171.  SrcBlock := Source;
  172.  DestBlock:= Dest;
  173.  for i:= 0 to (Count div 8) - 1 do
  174.   begin
  175.    DecipherEntryXTEA(SrcBlock, @AuxBlock, Key);
  176.    AuxBlock[0]:= AuxBlock[0] xor LastBlock[0];
  177.    AuxBlock[1]:= AuxBlock[1] xor LastBlock[1];
  178.    LastBlock[0]:= SrcBlock[0];
  179.    LastBlock[1]:= SrcBlock[1];
  180.    DestBlock[0]:= AuxBlock[0];
  181.    DestBlock[1]:= AuxBlock[1];
  182.    Inc(SrcBlock);
  183.    Inc(DestBlock);
  184.   end;
  185.  // Residual block termination.
  186.  if (Count mod 8 > 0) then
  187.   begin
  188.    // Use encrypted IV, if message is too small.
  189.    if (Count < 8) then
  190.     CipherEntryXTEA(InitVec, @LastBlock, Key);
  191.    // Encrypt last block again.
  192.    CipherEntryXTEA(@LastBlock, @LastBlock, Key);
  193.    // Fill the auxiliary block with remaining bytes.
  194.    AuxBlock[0]:= 0;
  195.    AuxBlock[1]:= 0;
  196.    Move(SrcBlock^, AuxBlock, Count mod 8);
  197.    // Decrypt the remaining bytes.
  198.    AuxBlock[0]:= AuxBlock[0] xor LastBlock[0];
  199.    AuxBlock[1]:= AuxBlock[1] xor LastBlock[1];
  200.    // Write the remaining bytes to destination.
  201.    Move(AuxBlock, DestBlock^, Count mod 8);
  202.   end;
  203. end;
  204. //---------------------------------------------------------------------------
  205. end.