CryptoKeccakSponge.Mod 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. MODULE CryptoKeccakSponge; (** OUTHOR "GF"; PURPOSE "Keccak, sponge mode"; *)
  2. (*
  3. The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
  4. Michaël Peeters and Gilles Van Assche. For more information, feedback or
  5. questions, please refer to our website: http://keccak.noekeon.org/
  6. *)
  7. IMPORT Keccak := CryptoKeccakF1600;
  8. CONST
  9. LaneSize = Keccak.LaneSize;
  10. Width* = Keccak.Width;
  11. DefaultRate* = 1024;
  12. DefaultCapacity* = 576;
  13. TYPE
  14. Instance* = OBJECT
  15. VAR
  16. state: Keccak.Instance; (* The state processed by the permutation. *)
  17. chunk: LONGINT; (* The value of the rate in bytes *)
  18. index: LONGINT; (* The position in the state of the next byte to be
  19. input (when absorbing) or output (when squeezing). *)
  20. squeezing: BOOLEAN ; (* false: in the absorbing phase; otherwise, in the squeezing phase. *)
  21. cmodl: LONGINT; (* chunk MOD LaneSize *)
  22. cdivl: LONGINT; (* chunk DIV LaneSize *)
  23. PROCEDURE &Init*;
  24. BEGIN
  25. NEW( state );
  26. Initialize( DefaultRate, DefaultCapacity )
  27. END Init;
  28. PROCEDURE Initialize*( rate, capacity: LONGINT );
  29. BEGIN
  30. ASSERT( rate + capacity = Width );
  31. ASSERT( (rate > 0) & (rate <= Width) & (rate MOD 8 = 0) );
  32. state.Initialize;
  33. chunk := rate DIV 8;
  34. index := 0;
  35. cmodl := chunk MOD LaneSize;
  36. cdivl := chunk DIV LaneSize;
  37. squeezing := FALSE
  38. END Initialize;
  39. PROCEDURE Absorb*( CONST data: ARRAY OF CHAR; offset, len: LONGINT );
  40. VAR
  41. piece, lanes, laneNo, laneOffset, bytes: LONGINT;
  42. BEGIN
  43. ASSERT( squeezing = FALSE );
  44. WHILE len > 0 DO
  45. IF (index = 0) & ( len >= chunk) THEN
  46. (* fast lane: processing whole blocks first *)
  47. state.XORLanes( data, offset, cdivl );
  48. IF cmodl # 0 THEN state.XORBytesInLane( cdivl, 0, cmodl, data, offset ) END;
  49. state.Permute;
  50. INC( offset, chunk ); DEC( len, chunk );
  51. ELSE
  52. (* normal lane: using the message queue*)
  53. piece := len;
  54. IF index + piece > chunk THEN piece := chunk - index END;
  55. IF (index = 0) & (piece >= LaneSize) THEN
  56. lanes := piece DIV LaneSize; bytes := lanes*LaneSize;
  57. state.XORLanes( data, offset, lanes );
  58. INC( offset, bytes ); DEC( len, bytes ); DEC( piece, bytes );
  59. INC( index, bytes );
  60. END;
  61. WHILE piece > 0 DO
  62. laneNo := index DIV LaneSize;
  63. laneOffset := index MOD LaneSize;
  64. bytes := LaneSize - laneOffset;
  65. IF bytes > piece THEN bytes := piece END;
  66. state.XORBytesInLane( laneNo, laneOffset, bytes, data, offset );
  67. INC( offset, bytes ); DEC( len, bytes ); DEC( piece, bytes );
  68. INC( index, bytes )
  69. END;
  70. IF index = chunk THEN state.Permute; index := 0 END
  71. END
  72. END
  73. END Absorb;
  74. PROCEDURE Squeeze*( VAR data: ARRAY OF CHAR; offset, len: LONGINT );
  75. VAR piece, lanes, laneNo, laneOffset, bytes: LONGINT;
  76. BEGIN
  77. IF ~squeezing THEN AbsorbLastFewBits( 01X ) END;
  78. WHILE len > 0 DO
  79. IF (index = chunk) & (len >= chunk) THEN
  80. (* fast lane: processing whole blocks first*)
  81. state.Permute;
  82. state.ExtractLanes( data, offset, cdivl );
  83. IF cmodl # 0 THEN state.ExtractBytesInLane( cdivl, 0, cmodl, data, offset + cdivl*LaneSize ) END;
  84. INC( offset, chunk ); DEC( len, chunk )
  85. ELSE
  86. (* normal lane: using the message queue *)
  87. IF index = chunk THEN state.Permute; index := 0 END;
  88. piece := len;
  89. IF index + piece > chunk THEN piece := chunk - index END;
  90. IF (index = 0) & (piece >= LaneSize) THEN
  91. lanes := piece DIV LaneSize; bytes := lanes*LaneSize;
  92. state.ExtractLanes( data, offset, lanes );
  93. DEC( len, bytes ); INC( offset, bytes );
  94. INC( index, bytes ); DEC( piece, bytes )
  95. END;
  96. WHILE piece > 0 DO
  97. laneNo := index DIV LaneSize;
  98. laneOffset := index MOD LaneSize;
  99. bytes := LaneSize - laneOffset;
  100. IF bytes > piece THEN bytes := piece END;
  101. state.ExtractBytesInLane( laneNo, laneOffset, bytes, data, offset );
  102. DEC( len, bytes ); INC( offset, bytes );
  103. INC( index, bytes ); DEC( piece, bytes )
  104. END
  105. END
  106. END;
  107. END Squeeze;
  108. PROCEDURE AbsorbLastFewBits*( data: CHAR );
  109. VAR tmp: ARRAY 4 OF CHAR;
  110. BEGIN
  111. ASSERT( (data # 0X) & (squeezing = FALSE) );
  112. tmp[0] := data;
  113. state.XORBytesInLane( index DIV LaneSize, index MOD LaneSize, 1, tmp, 0 );
  114. IF (data >= 80X) & (index = chunk - 1) THEN state.Permute END;
  115. state.ComplementBit( chunk*8 - 1 );
  116. state.Permute;
  117. index := 0;
  118. squeezing := TRUE
  119. END AbsorbLastFewBits;
  120. END Instance;
  121. END CryptoKeccakSponge.