CryptoSHA256.Mod 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. MODULE CryptoSHA256; (** AUTHOR "G.F."; PURPOSE "SHA-256"; *)
  2. IMPORT
  3. S := SYSTEM, Hashes := CryptoHashes, U := CryptoUtils;
  4. CONST
  5. BlockSize = 64;
  6. VAR
  7. K256: ARRAY 64 OF LONGINT;
  8. TYPE
  9. Hash* = OBJECT (Hashes.Hash)
  10. VAR
  11. hash: ARRAY 8 OF LONGINT; (* state *)
  12. Nl, Nh: LONGINT;
  13. cdata: ARRAY BlockSize OF CHAR; (* pending data *)
  14. cn: LONGINT (* number of chars in cdata *)
  15. PROCEDURE &Init*;
  16. BEGIN
  17. SetNameAndSize( "sha256", 32 );
  18. initialized := FALSE
  19. END Init;
  20. PROCEDURE Initialize*;
  21. BEGIN
  22. hash[0] := 6A09E667H; hash[1] := LONGINT( 0BB67AE85H );
  23. hash[2] := 3C6EF372H; hash[3] := LONGINT( 0A54FF53AH );
  24. hash[4] := 510E527FH; hash[5] := LONGINT( 09B05688CH );
  25. hash[6] := 1F83D9ABH; hash[7] := LONGINT( 05BE0CD19H );
  26. Nl := 0;
  27. Nh := 0;
  28. cn := 0;
  29. initialized := TRUE
  30. END Initialize;
  31. PROCEDURE HashBlock( CONST buf: ARRAY OF CHAR; pos: LONGINT );
  32. VAR a, b, c, d, e, f, g, h, s0, s1, s, T1, T2, i: LONGINT;
  33. X: ARRAY 16 OF LONGINT
  34. BEGIN
  35. a := hash[0]; b := hash[1]; c := hash[2]; d := hash[3];
  36. e := hash[4]; f := hash[5]; g := hash[6]; h := hash[7];
  37. FOR i := 0 TO 63 DO
  38. IF i < 16 THEN
  39. X[i] := U.IntFromBufferBE( buf, pos ); INC( pos, 4 )
  40. ELSE
  41. s0 := sigma0( X[(i + 1) MOD 16] );
  42. s1 := sigma1( X[(i + 14) MOD 16] );
  43. s := s0 + s1 + X[(i + 9) MOD 16];
  44. INC( X[i MOD 16], s );
  45. END;
  46. T1 := X[i MOD 16] + h + Sigma1Ch( e, f, g ) + K256[i];
  47. T2 := Sigma0Maj( a, b, c );
  48. h := g; g := f; f := e; e := d + T1;
  49. d := c; c := b; b := a; a := T1 + T2;
  50. END;
  51. INC( hash[0], a ); INC( hash[1], b ); INC( hash[2], c ); INC( hash[3], d );
  52. INC( hash[4], e ); INC( hash[5], f ); INC( hash[6], g ); INC( hash[7], h );
  53. END HashBlock;
  54. PROCEDURE HashContextBlock;
  55. BEGIN
  56. HashBlock( cdata, 0 ); cn := 0
  57. END HashContextBlock;
  58. (** data: value to be hashed *)
  59. PROCEDURE Update*( CONST data: ARRAY OF CHAR; pos, len: LONGINT );
  60. VAR n, i, l: LONGINT;
  61. BEGIN
  62. ASSERT( initialized );
  63. l := Nl + len*8;
  64. IF l < Nl THEN INC( Nh ) (* overflow *) END;
  65. Nh := Nh + ASH( len, -29 ); Nl := l;
  66. IF cn > 0 THEN
  67. IF cn + len < BlockSize THEN
  68. i := cn; INC( cn, len );
  69. WHILE i < cn DO cdata[i] := data[pos]; INC( i ); INC( pos ) END;
  70. RETURN
  71. ELSE
  72. WHILE cn < BlockSize DO
  73. cdata[cn] := data[pos]; INC( cn ); INC( pos ); DEC( len )
  74. END;
  75. HashContextBlock;
  76. END
  77. END;
  78. n := 0;
  79. WHILE n < len DIV BlockSize DO HashBlock( data, pos ); INC( n ) END;
  80. len := len MOD BlockSize;
  81. WHILE cn < len DO cdata[cn] := data[pos]; INC( cn ); INC( pos ) END;
  82. END Update;
  83. (** get the hashvalue of length SELF.size *)
  84. PROCEDURE GetHash*( VAR buf: ARRAY OF CHAR; pos: LONGINT );
  85. VAR p, i: LONGINT;
  86. BEGIN
  87. cdata[cn] := 80X; INC( cn );
  88. IF cn > BlockSize - 8 THEN
  89. WHILE cn < BlockSize DO cdata[cn] := 0X; INC( cn ) END;
  90. HashContextBlock;
  91. END;
  92. p := BlockSize - 8;
  93. WHILE cn < p DO cdata[cn] := 0X; INC( cn ) END;
  94. U.IntToBufferBE( Nh, cdata, p ); U.IntToBufferBE( Nl, cdata, p + 4 );
  95. HashContextBlock;
  96. FOR i := 0 TO 7 DO U.IntToBufferBE( hash[i], buf, pos ); INC( pos, 4 ) END;
  97. END GetHash;
  98. END Hash;
  99. (* PROCEDURES *******************************************************************************)
  100. (** get an instance of SHA256 *)
  101. PROCEDURE NewHash*( ) : Hashes.Hash;
  102. VAR h: Hash;
  103. BEGIN
  104. NEW( h ); RETURN h
  105. END NewHash;
  106. PROCEDURE -Sigma0Maj( px, py, pz: LONGINT ): LONGINT;
  107. VAR x, y, z, a, b: SET32;
  108. BEGIN
  109. x := S.VAL( SET32, px ); y := S.VAL( SET32, py ); z := S.VAL( SET32, pz );
  110. a := ROT( x, 30 ) / ROT( x, 19 ) / ROT( x, 10 );
  111. b := (x*y) / (x*z) / (y*z);
  112. RETURN S.VAL( LONGINT, a ) + S.VAL( LONGINT, b )
  113. END Sigma0Maj;
  114. PROCEDURE -Sigma1Ch( px, py, pz: LONGINT ): LONGINT;
  115. VAR x, y, z, a, b: SET32;
  116. BEGIN
  117. x := S.VAL( SET32, px ); y := S.VAL( SET32, py ); z := S.VAL( SET32, pz );
  118. a := ROT( x, 26 ) / ROT( x, 21 ) / ROT( x, 7 );
  119. b := (x*y) / ((-x)*z);
  120. RETURN S.VAL( LONGINT, a ) + S.VAL( LONGINT, b )
  121. END Sigma1Ch;
  122. PROCEDURE -sigma0( px: LONGINT ): LONGINT;
  123. VAR x: SET32;
  124. BEGIN
  125. x :=S.VAL( SET32, px );
  126. RETURN S.VAL( LONGINT, ROT( x , 25 ) / ROT( x, 14 ) / LSH( x, -3 ) )
  127. END sigma0;
  128. PROCEDURE -sigma1( px: LONGINT ): LONGINT;
  129. VAR x: SET32;
  130. BEGIN
  131. x := S.VAL( SET32, px );
  132. RETURN S.VAL( LONGINT, ROT( x , 15 ) / ROT( x, 13 ) / LSH( x, -10 ) )
  133. END sigma1;
  134. PROCEDURE InitializeK;
  135. VAR
  136. buf: U.InitBuffer; i: LONGINT;
  137. BEGIN
  138. NEW( buf, 2048 );
  139. buf.Add( "428A2F98 71374491 B5C0FBCF E9B5DBA5 " );
  140. buf.Add( "3956C25B 59F111F1 923F82A4 AB1C5ED5 " );
  141. buf.Add( "D807AA98 12835B01 243185BE 550C7DC3 " );
  142. buf.Add( "72BE5D74 80DEB1FE 9BDC06A7 C19BF174 " );
  143. buf.Add( "E49B69C1 EFBE4786 0FC19DC6 240CA1CC " );
  144. buf.Add( "2DE92C6F 4A7484AA 5CB0A9DC 76F988DA " );
  145. buf.Add( "983E5152 A831C66D B00327C8 BF597FC7 " );
  146. buf.Add( "C6E00BF3 D5A79147 06CA6351 14292967 " );
  147. buf.Add( "27B70A85 2E1B2138 4D2C6DFC 53380D13 " );
  148. buf.Add( "650A7354 766A0ABB 81C2C92E 92722C85 " );
  149. buf.Add( "A2BFE8A1 A81A664B C24B8B70 C76C51A3 " );
  150. buf.Add( "D192E819 D6990624 F40E3585 106AA070 " );
  151. buf.Add( "19A4C116 1E376C08 2748774C 34B0BCB5 " );
  152. buf.Add( "391C0CB3 4ED8AA4A 5B9CCA4F 682E6FF3 " );
  153. buf.Add( "748F82EE 78A5636F 84C87814 8CC70208 " );
  154. buf.Add( "90BEFFFA A4506CEB BEF9A3F7 C67178F2 " );
  155. FOR i := 0 TO 63 DO K256[i] := buf.GetInt() END;
  156. END InitializeK;
  157. BEGIN
  158. InitializeK
  159. END CryptoSHA256.