with Bits; use Bits; package body Keccak_C is -- C interface procedure C_Get_Size(Size: out Interfaces.C.size_t) is begin Size := C_Context'Size / 8; end C_Get_Size; function C_Begin return C_Context_Access is Result : C_Context_Access; begin Result := new C_Context; KeccakBegin(Result.all); return Result; end C_Begin; procedure C_Hash(Ctx: in C_Context_Access; Input: Char_Star; Len: Interfaces.C.size_t) is Buffer_Size: constant Natural := 2048; Byte_Size: constant Natural := 8; N: Natural := 0; I: Natural := 0; L: Natural := Natural(Len); Buf: String(1..Buffer_Size); B: Bitstream(1..Buf'Length*Byte_Size); Ptr: Char_Star := Input; begin if Input = null then raise Strings.Dereference_Error; end if; while L > I loop N := 0; for Chr of Buf loop exit when L <= I; Chr := Character(Ptr.all); Char_Ptrs.Increment(Ptr); N := N + 1; I := I + 1; end loop; ToBitstream(Buf(1..N), B(1..N*Byte_Size)); KeccakHash(Ctx.all, B(1..N*Byte_Size)); end loop; end C_Hash; procedure C_End(Ctx: C_Context_Access; Output: Char_Star; Len: Interfaces.C.Size_T) is L: Natural := Natural(Len); S: String(1..L); B: Bitstream(1..S'Length*8); Ptr: Char_Star := Output; begin if Output = null then raise Strings.Dereference_Error; end if; KeccakEnd(Ctx.all, B); ToString(B, S); for Chr of S loop Ptr.all := Interfaces.C.char(Chr); Char_Ptrs.Increment(Ptr); end loop; -- Len = Count end C_End; procedure C_Context_Deallocate is new Ada.Unchecked_Deallocation (C_Context, C_Context_Access); procedure C_Deallocate(Ctx: in out C_Context_Access) is begin C_Context_Deallocate(Ctx); end C_Deallocate; end Keccak_C;