(64 . 6)(64 . 75)
311 end; -- end squeeze stage
312 end Sponge;
313
314 -- public interface, state based Sponge
315 procedure KeccakBegin(Ctx : in out Keccak_Context) is
316 begin
317 Ctx.Internal := (others => (others => 0));
318 Ctx.Block := (others => 0);
319 Ctx.Pos := Ctx.Block'First;
320 end;
321
322 procedure KeccakHash(Ctx : in out Keccak_Context;
323 Input : Bitstream) is
324 I0 : Natural;
325 I1 : Natural;
326 B0 : Natural;
327 B1 : Natural;
328 begin
329 I0 := Input'First;
330 <<Block_Process_Loop>>
331 I1 := Input'Last;
332 B0 := Ctx.Pos;
333 B1 := B0 + (I1-I0);
334
335 if B1>Ctx.Block'Last then
336 B1 := Ctx.Block'Last;
337 I1 := I0 + (B1-B0);
338 end if;
339 Ctx.Block(B0..B1) := Input(I0..I1);
340 Ctx.Pos := B1 + 1;
341 -- we've filled up the buffer
342 if Ctx.Pos > Ctx.Block'Last then
343 AbsorbBlock(Ctx.Block, Ctx.Internal);
344 Ctx.Internal := Keccak_Function(Ctx.Internal);
345 Ctx.Pos := Ctx.Block'First;
346 end if;
347 -- we haven't processed entire input block, loop
348 if I1 < Input'Last then
349 I0 := I1 + 1;
350 goto Block_Process_Loop;
351 end if;
352 end;
353
354 procedure KeccakEnd(Ctx : in out Keccak_Context;
355 Output : out Bitstream) is
356 BlocksPerOutput : constant Natural := Output'Length / Ctx.Block_Len;
357 StrayPerOutput : constant Natural := Output'Length mod Ctx.Block_Len;
358 Block : Bitstream(1 .. Ctx.Block_Len);
359 Need : Natural;
360 begin
361 if Ctx.Pos /= 0 then -- needs padding
362 Block := (others => 0);
363 Need := Ctx.Block'Last - Ctx.Pos;
364 Block(Block'First) := 1;
365 Block(Block'First+Need) := 1;
366 KeccakHash(Ctx, Block(1..Need+1));
367 end if;
368
369 -- squeez bits
370 for I in 0 .. BlocksPerOutput - 1 loop
371 SqueezeBlock(Block, Ctx.Internal);
372 Output(Output'First + I * Ctx.Block_Len ..
373 Output'First + (I + 1) * Ctx.Block_Len -1) := Block;
374 Ctx.Internal := Keccak_Function(Ctx.Internal);
375 end loop;
376 if StrayPerOutput > 0 then
377 SqueezeBlock(Block, Ctx.Internal);
378 Output(Output'Last - StrayPerOutput + 1 .. Output'Last) :=
379 Block(Block'First .. Block'First + StrayPerOutput - 1);
380 end if;
381 end;
382
383 -- convert from a bitstream of ZWord size to an actual ZWord number
384 function BitsToWord( BWord: in Bitword ) return ZWord is
385 W : ZWord;