steelcrypt/src/sponge/spritz/spritz.adb

113 lines
2.5 KiB
Ada

package body Spritz is
procedure InitializeContext (ctx : out Context) is
begin
ctx.i := 0;
ctx.j := 0;
ctx.k := 0;
ctx.z := 0;
ctx.a := 0;
ctx.w := 1;
for i in ctx.S'Range loop
ctx.S(i) := u8(i);
end loop;
end;
procedure Output (ctx : in out Context; z : out u8) is
begin
ctx.z := ctx.S(ctx.j + ctx.S(ctx.i + ctx.S(ctx.z + ctx.k)));
z := ctx.z;
end Output;
procedure Update (ctx : in out Context) is
begin
ctx.i := ctx.i + ctx.w;
ctx.j := ctx.k + ctx.S(ctx.j + ctx.S(ctx.i));
ctx.k := ctx.i + ctx.k + ctx.S(ctx.j);
Swap(ctx.S(ctx.i), ctx.S(ctx.j));
end Update;
procedure Crush (ctx : in out Context) is
begin
for v in u8 range 0 .. u8(N / 2 - 1) loop
if ctx.S(v) > ctx.S(u8(N - 1) - v) then
Swap(ctx.S(v), ctx.S(u8(N - 1) - v));
end if;
end loop;
end Crush;
procedure Whip (ctx : in out Context) is
begin
for i in 0 .. (2 * N - 1) loop
Update(ctx);
end loop;
ctx.w := ctx.w + 2;
end Whip;
procedure Shuffle (ctx : in out Context) is
begin
Whip(ctx);
Crush(ctx);
Whip(ctx);
Crush(ctx);
Whip(ctx);
ctx.a := 0;
end Shuffle;
procedure Drip (ctx : in out Context; z : out u8) is
begin
if ctx.a > 0 then
Shuffle(ctx);
end if;
Update(ctx);
Output(ctx, z);
end Drip;
procedure Squeeze (ctx : in out Context; P : out u8_Array) is
z : u8;
begin
for i in P'Range loop
Drip(ctx, z);
P(i) := z;
end loop;
end Squeeze;
procedure AbsorbStop (ctx : in out Context) is
begin
if ctx.a = u8(N / 2) then
Shuffle(ctx);
end if;
ctx.a := ctx.a + 1;
end AbsorbStop;
procedure AbsorbNibble (ctx : in out Context; x : in u8) is
begin
if ctx.a = u8(N / 2) then
Shuffle(ctx);
end if;
Swap(ctx.S(ctx.a), ctx.S(u8(N / 2) + x));
ctx.a := ctx.a + 1;
end AbsorbNibble;
procedure Absorb (ctx : in out Context; x : in u8) is
begin
AbsorbNibble(ctx, x and 15);
AbsorbNibble(ctx, Shift_Right(x, 4));
end Absorb;
procedure Absorb (ctx : in out Context; x : in u8_Array) is
begin
for i in x'Range loop
Absorb(ctx, x(i));
end loop;
end Absorb;
procedure Absorb (ctx : in out Context; x : in String) is
begin
for i in x'Range loop
Absorb(ctx, u8(Character'Pos(x(i))));
end loop;
end Absorb;
end Spritz;