CryptoSHA1.Mod 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. MODULE CryptoSHA1; (** AUTHOR "G.F."; PURPOSE "SHA-1"; *)
  2. IMPORT
  3. S := SYSTEM, Hashes := CryptoHashes, U := CryptoUtils;
  4. CONST
  5. BlockSize = 64;
  6. TYPE
  7. State = ARRAY 5 OF LONGINT;
  8. Hash* = OBJECT (Hashes.Hash)
  9. VAR
  10. hash: State;
  11. Nl, Nh: LONGINT;
  12. cdata: ARRAY BlockSize OF CHAR; (* pending data *)
  13. cn: LONGINT (* number of chars in data *)
  14. PROCEDURE &Init*;
  15. BEGIN
  16. SetNameAndSize( "sha1", 20 );
  17. initialized := FALSE
  18. END Init;
  19. PROCEDURE Initialize*;
  20. BEGIN
  21. hash[0] := LONGINT( 067452301H );
  22. hash[1] := LONGINT( 0EFCDAB89H );
  23. hash[2] := LONGINT( 098BADCFEH );
  24. hash[3] := LONGINT( 010325476H );
  25. hash[4] := LONGINT( 0C3D2E1F0H );
  26. Nl := 0;
  27. Nh := 0;
  28. cn := 0;
  29. initialized := TRUE
  30. END Initialize;
  31. PROCEDURE HashContextBlock;
  32. BEGIN
  33. HashBlock( hash, cdata, 0 ); cn := 0
  34. END HashContextBlock;
  35. (** data: value to be hashed *)
  36. PROCEDURE Update*( CONST data: ARRAY OF CHAR; pos, len: LONGINT );
  37. VAR n, i, l: LONGINT;
  38. BEGIN
  39. ASSERT( initialized );
  40. l := Nl + len *8;
  41. IF l < Nl THEN INC( Nh ) (* overflow *) END;
  42. Nh := Nh + ASH( len, -29 ); Nl := l;
  43. IF cn > 0 THEN
  44. IF cn + len < BlockSize THEN
  45. i := cn; INC( cn, len );
  46. WHILE i < cn DO cdata[i] := data[pos]; INC( i ); INC( pos ) END;
  47. RETURN
  48. ELSE
  49. WHILE cn < BlockSize DO
  50. cdata[cn] := data[pos]; INC( cn ); INC( pos ); DEC( len )
  51. END;
  52. HashContextBlock;
  53. END
  54. END;
  55. n := 0;
  56. WHILE n < len DIV BlockSize DO
  57. HashBlock( hash, data, pos ); INC( n ); INC( pos, BlockSize )
  58. END;
  59. len := len MOD BlockSize;
  60. WHILE cn < len DO cdata[cn] := data[pos]; INC( cn ); INC( pos ) END;
  61. END Update;
  62. (** get the hashvalue of length SELF.size *)
  63. PROCEDURE GetHash*( VAR buf: ARRAY OF CHAR; pos: LONGINT );
  64. VAR p: LONGINT;
  65. BEGIN
  66. cdata[cn] := 80X; INC( cn );
  67. IF cn > BlockSize - 8 THEN
  68. WHILE cn < BlockSize DO cdata[cn] := 0X; INC( cn ) END;
  69. HashContextBlock;
  70. END;
  71. p := BlockSize - 8;
  72. WHILE cn < p DO cdata[cn] := 0X; INC( cn ) END;
  73. U.IntToBufferBE( Nh, cdata, p ); U.IntToBufferBE( Nl, cdata, p + 4 );
  74. HashContextBlock;
  75. U.BlockToBufferBE( hash, buf, pos )
  76. END GetHash;
  77. END Hash;
  78. (* PROCEDURES *******************************************************************************)
  79. (** get an instance of SHA1 *)
  80. PROCEDURE NewHash*( ) : Hashes.Hash;
  81. VAR h: Hash;
  82. BEGIN
  83. NEW( h ); RETURN h
  84. END NewHash;
  85. (* PROCEDURE F1( b, c, d: LONGINT ): LONGINT;
  86. BEGIN
  87. RETURN S.VAL( LONGINT, ((S.VAL( SET32, c ) / S.VAL( SET32, d )) * S.VAL( SET32, b )) / S.VAL( SET32, d ) )
  88. END F1;
  89. PROCEDURE F2( b, c, d: LONGINT ): LONGINT;
  90. BEGIN
  91. RETURN S.VAL( LONGINT, S.VAL( SET32, b ) / S.VAL( SET32, c ) / S.VAL( SET32, d ) )
  92. END F2;
  93. PROCEDURE F3( b, c, d: LONGINT ): LONGINT;
  94. BEGIN
  95. RETURN S.VAL( LONGINT, (S.VAL( SET32, b ) * S.VAL( SET32, c )) + ((S.VAL( SET32, b ) + S.VAL( SET32, c )) * S.VAL( SET32, d )) )
  96. END F3;
  97. *)
  98. PROCEDURE -tr0019( a: LONGINT; VAR b: LONGINT; c, d, e: LONGINT; VAR f: LONGINT; x: SET32 );
  99. BEGIN
  100. f := S.VAL( LONGINT, x ) + e + 5A827999H + ROT( a, 5 ) +
  101. (*F1( b, c, d );*)
  102. S.VAL( LONGINT, ((S.VAL( SET32, c ) / S.VAL( SET32, d )) * S.VAL( SET32, b )) / S.VAL( SET32, d ) );
  103. b := ROT( b, 30 );
  104. END tr0019;
  105. PROCEDURE -tr2039( a: LONGINT; VAR b: LONGINT; c, d, e: LONGINT; VAR f: LONGINT; x: SET32 );
  106. BEGIN
  107. f := S.VAL( LONGINT, x ) + e + 6ED9EBA1H + ROT( a, 5 ) +
  108. (*F2( b, c, d );*)
  109. S.VAL( LONGINT, S.VAL( SET32, b ) / S.VAL( SET32, c ) / S.VAL( SET32, d ) );
  110. b := ROT( b, 30 );
  111. END tr2039;
  112. PROCEDURE -tr4059( a: LONGINT; VAR b: LONGINT; c, d, e: LONGINT; VAR f: LONGINT; x: SET32);
  113. BEGIN
  114. f := S.VAL( LONGINT, x ) + e + LONGINT(8F1BBCDCH) + ROT( a, 5 ) +
  115. (*F3( b, c, d );*)
  116. S.VAL( LONGINT, (S.VAL( SET32, b ) * S.VAL( SET32, c )) + ((S.VAL( SET32, b ) + S.VAL( SET32, c )) * S.VAL( SET32, d )) );
  117. b := ROT( b, 30 )
  118. END tr4059;
  119. PROCEDURE -tr6079( a: LONGINT; VAR b: LONGINT; c, d, e: LONGINT; VAR f: LONGINT; x: SET32 );
  120. BEGIN
  121. f := S.VAL( LONGINT, x ) + e + LONGINT(0CA62C1D6H) + ROT( a, 5 ) +
  122. (*F2( b, c, d );*)
  123. S.VAL( LONGINT, S.VAL( SET32, b ) / S.VAL( SET32, c ) / S.VAL( SET32, d ) );
  124. b := ROT( b, 30 );
  125. END tr6079;
  126. PROCEDURE HashBlock( VAR state: State; CONST buf: ARRAY OF CHAR; pos: LONGINT );
  127. VAR
  128. A, B, C, D, E, T: LONGINT;
  129. x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf: SET32;
  130. BEGIN
  131. A := state[0]; B := state[1]; C := state[2]; D := state[3]; E := state[4];
  132. x0 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( A, B, C, D, E, T, x0 );
  133. x1 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( T, A, B, C, D, E, x1 );
  134. x2 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( E, T, A, B, C, D, x2 );
  135. x3 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( D, E, T, A, B, C, x3 );
  136. x4 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( C, D, E, T, A, B, x4 );
  137. x5 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( B, C, D, E, T, A, x5 );
  138. x6 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( A, B, C, D, E, T, x6 );
  139. x7 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( T, A, B, C, D, E, x7 );
  140. x8 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( E, T, A, B, C, D, x8 );
  141. x9 := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( D, E, T, A, B, C, x9 );
  142. xa := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( C, D, E, T, A, B, xa );
  143. xb := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( B, C, D, E, T, A, xb );
  144. xc := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( A, B, C, D, E, T, xc );
  145. xd := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( T, A, B, C, D, E, xd );
  146. xe := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( E, T, A, B, C, D, xe );
  147. xf := U.SetFromBufferBE( buf, pos ); INC( pos, 4 ); tr0019( D, E, T, A, B, C, xf );
  148. x0 := ROT( x0 / x2 / x8 / xd, 1 ); tr0019( C, D, E, T, A, B, x0 );
  149. x1 := ROT( x1 / x3 / x9 / xe, 1 ); tr0019( B, C, D, E, T, A, x1 );
  150. x2 := ROT( x2 / x4 / xa / xf, 1 ); tr0019( A, B, C, D, E, T, x2 );
  151. x3 := ROT( x3 / x5 / xb / x0, 1 ); tr0019( T, A, B, C, D, E, x3 );
  152. x4 := ROT( x4 / x6 / xc / x1, 1 ); tr2039( E, T, A, B, C, D, x4 );
  153. x5 := ROT( x5 / x7 / xd / x2, 1 ); tr2039( D, E, T, A, B, C, x5 );
  154. x6 := ROT( x6 / x8 / xe / x3, 1 ); tr2039( C, D, E, T, A, B, x6 );
  155. x7 := ROT( x7 / x9 / xf / x4, 1 ); tr2039( B, C, D, E, T, A, x7 );
  156. x8 := ROT( x8 / xa / x0 / x5, 1 ); tr2039( A, B, C, D, E, T, x8 );
  157. x9 := ROT( x9 / xb / x1 / x6, 1 ); tr2039( T, A, B, C, D, E, x9 );
  158. xa := ROT( xa / xc / x2 / x7, 1 ); tr2039( E, T, A, B, C, D, xa );
  159. xb := ROT( xb / xd / x3 / x8, 1 ); tr2039( D, E, T, A, B, C, xb );
  160. xc := ROT( xc / xe / x4 / x9, 1 ); tr2039( C, D, E, T, A, B, xc );
  161. xd := ROT( xd / xf / x5 / xa, 1 ); tr2039( B, C, D, E, T, A, xd );
  162. xe := ROT( xe / x0 / x6 / xb, 1 ); tr2039( A, B, C, D, E, T, xe );
  163. xf := ROT( xf / x1 / x7 / xc, 1 ); tr2039( T, A, B, C, D, E, xf );
  164. x0 := ROT( x0 / x2 / x8 / xd, 1 ); tr2039( E, T, A, B, C, D, x0 );
  165. x1 := ROT( x1 / x3 / x9 / xe, 1 ); tr2039( D, E, T, A, B, C, x1 );
  166. x2 := ROT( x2 / x4 / xa / xf, 1 ); tr2039( C, D, E, T, A, B, x2 );
  167. x3 := ROT( x3 / x5 / xb / x0, 1 ); tr2039( B, C, D, E, T, A, x3 );
  168. x4 := ROT( x4 / x6 / xc / x1, 1 ); tr2039( A, B, C, D, E, T, x4 );
  169. x5 := ROT( x5 / x7 / xd / x2, 1 ); tr2039( T, A, B, C, D, E, x5 );
  170. x6 := ROT( x6 / x8 / xe / x3, 1 ); tr2039( E, T, A, B, C, D, x6 );
  171. x7 := ROT( x7 / x9 / xf / x4, 1 ); tr2039( D, E, T, A, B, C, x7 );
  172. x8 := ROT( x8 / xa / x0 / x5, 1 ); tr4059( C, D, E, T, A, B, x8 );
  173. x9 := ROT( x9 / xb / x1 / x6, 1 ); tr4059( B, C, D, E, T, A, x9 );
  174. xa := ROT( xa / xc / x2 / x7, 1 ); tr4059( A, B, C, D, E, T, xa );
  175. xb := ROT( xb / xd / x3 / x8, 1 ); tr4059( T, A, B, C, D, E, xb );
  176. xc := ROT( xc / xe / x4 / x9, 1 ); tr4059( E, T, A, B, C, D, xc );
  177. xd := ROT( xd / xf / x5 / xa, 1 ); tr4059( D, E, T, A, B, C, xd );
  178. xe := ROT( xe / x0 / x6 / xb, 1 ); tr4059( C, D, E, T, A, B, xe );
  179. xf := ROT( xf / x1 / x7 / xc, 1 ); tr4059( B, C, D, E, T, A, xf );
  180. x0 := ROT( x0 / x2 / x8 / xd, 1 ); tr4059( A, B, C, D, E, T, x0 );
  181. x1 := ROT( x1 / x3 / x9 / xe, 1 ); tr4059( T, A, B, C, D, E, x1 );
  182. x2 := ROT( x2 / x4 / xa / xf, 1 ); tr4059( E, T, A, B, C, D, x2 );
  183. x3 := ROT( x3 / x5 / xb / x0, 1 ); tr4059( D, E, T, A, B, C, x3 );
  184. x4 := ROT( x4 / x6 / xc / x1, 1 ); tr4059( C, D, E, T, A, B, x4 );
  185. x5 := ROT( x5 / x7 / xd / x2, 1 ); tr4059( B, C, D, E, T, A, x5 );
  186. x6 := ROT( x6 / x8 / xe / x3, 1 ); tr4059( A, B, C, D, E, T, x6 );
  187. x7 := ROT( x7 / x9 / xf / x4, 1 ); tr4059( T, A, B, C, D, E, x7 );
  188. x8 := ROT( x8 / xa / x0 / x5, 1 ); tr4059( E, T, A, B, C, D, x8 );
  189. x9 := ROT( x9 / xb / x1 / x6, 1 ); tr4059( D, E, T, A, B, C, x9 );
  190. xa := ROT( xa / xc / x2 / x7, 1 ); tr4059( C, D, E, T, A, B, xa );
  191. xb := ROT( xb / xd / x3 / x8, 1 ); tr4059( B, C, D, E, T, A, xb );
  192. xc := ROT( xc / xe / x4 / x9, 1 ); tr6079( A, B, C, D, E, T, xc );
  193. xd := ROT( xd / xf / x5 / xa, 1 ); tr6079( T, A, B, C, D, E, xd );
  194. xe := ROT( xe / x0 / x6 / xb, 1 ); tr6079( E, T, A, B, C, D, xe );
  195. xf := ROT( xf / x1 / x7 / xc, 1 ); tr6079( D, E, T, A, B, C, xf );
  196. x0 := ROT( x0 / x2 / x8 / xd, 1 ); tr6079( C, D, E, T, A, B, x0 );
  197. x1 := ROT( x1 / x3 / x9 / xe, 1 ); tr6079( B, C, D, E, T, A, x1 );
  198. x2 := ROT( x2 / x4 / xa / xf, 1 ); tr6079( A, B, C, D, E, T, x2 );
  199. x3 := ROT( x3 / x5 / xb / x0, 1 ); tr6079( T, A, B, C, D, E, x3 );
  200. x4 := ROT( x4 / x6 / xc / x1, 1 ); tr6079( E, T, A, B, C, D, x4 );
  201. x5 := ROT( x5 / x7 / xd / x2, 1 ); tr6079( D, E, T, A, B, C, x5 );
  202. x6 := ROT( x6 / x8 / xe / x3, 1 ); tr6079( C, D, E, T, A, B, x6 );
  203. x7 := ROT( x7 / x9 / xf / x4, 1 ); tr6079( B, C, D, E, T, A, x7 );
  204. x8 := ROT( x8 / xa / x0 / x5, 1 ); tr6079( A, B, C, D, E, T, x8 );
  205. x9 := ROT( x9 / xb / x1 / x6, 1 ); tr6079( T, A, B, C, D, E, x9 );
  206. xa := ROT( xa / xc / x2 / x7, 1 ); tr6079( E, T, A, B, C, D, xa );
  207. xb := ROT( xb / xd / x3 / x8, 1 ); tr6079( D, E, T, A, B, C, xb );
  208. xc := ROT( xc / xe / x4 / x9, 1 ); tr6079( C, D, E, T, A, B, xc );
  209. xd := ROT( xd / xf / x5 / xa, 1 ); tr6079( B, C, D, E, T, A, xd );
  210. xe := ROT( xe / x0 / x6 / xb, 1 ); tr6079( A, B, C, D, E, T, xe );
  211. xf := ROT( xf / x1 / x7 / xc, 1 ); tr6079( T, A, B, C, D, E, xf );
  212. INC( state[0], E ); INC( state[1], T ); INC( state[2], A );
  213. INC( state[3], B ); INC( state[4], C );
  214. END HashBlock;
  215. END CryptoSHA1.