-
+ 680EFB9458A976F700A689A6B0678510172945E94D35207F07BEA280BB87B30EDC889968FBF6C922C8CC5C79B9193986AB66037CC36F47D52B49E91826C22FE4vtools/src/keccak_c.adb(0 . 0)(1 . 89)
192 package body Keccak_C is
193    -- helper functions
194    procedure ToBitstream(S: in String; B: out Bitstream ) is
195       V   : Unsigned_8;
196       Pos : Natural;
197    begin
198       Pos := B'First;
199       for C of S loop
200          V := Character'Pos( C );
201          B( Pos     ) := Bit( V and 1 );
202          B( Pos + 1 ) := Bit( Shift_Right( V, 1 ) and 1 );
203          B( Pos + 2 ) := Bit( Shift_Right( V, 2 ) and 1 );
204          B( Pos + 3 ) := Bit( Shift_Right( V, 3 ) and 1 );
205          B( Pos + 4 ) := Bit( Shift_Right( V, 4 ) and 1 );
206          B( Pos + 5 ) := Bit( Shift_Right( V, 5 ) and 1 );
207          B( Pos + 6 ) := Bit( Shift_Right( V, 6 ) and 1 );
208          B( Pos + 7 ) := Bit( Shift_Right( V, 7 ) and 1 );
209          Pos := Pos + 8;
210       end loop;
211    end ToBitstream;
212 
213    procedure ToString(B: in Bitstream; S: out String ) is
214       N   : Natural;
215       Pos : Natural;
216    begin
217       Pos := B'First;
218       for I in S'Range loop
219          N := Natural( B( Pos     ) ) +
220            Natural( B( Pos + 1 ) ) * 2 +
221            Natural( B( Pos + 2 ) ) * 4 +
222            Natural( B( Pos + 3 ) ) * 8 +
223            Natural( B( Pos + 4 ) ) * 16 +
224            Natural( B( Pos + 5 ) ) * 32 +
225            Natural( B( Pos + 6 ) ) * 64 +
226            Natural( B( Pos + 7 ) ) * 128;
227          Pos := Pos + 8;
228          S( I ) := Character'Val( N );
229       end loop;
230    end ToString;
231 
232    -- C interface
233 
234    procedure C_Get_Size(Size: out Interfaces.C.size_t) is
235    begin
236       Size := C_Context'Size / 8;
237    end C_Get_Size;
238 
239    function C_Begin return C_Context_Access is
240       Result : C_Context_Access;
241    begin
242       Result := new C_Context;
243       KeccakBegin(Result.all);
244       return Result;
245    end C_Begin;
246 
247    procedure C_Hash(Ctx: in C_Context_Access;
248                     Input: Interfaces.C.Char_Array;
249                     Len: Interfaces.C.Size_T) is
250       L: Natural := Natural(Len);
251       S: String(1..L);
252       B: Bitstream(1..S'Length*8);
253    begin
254       Interfaces.C.To_Ada(Input, S, L, Trim_Nul => False);
255       ToBitstream(S, B);
256       KeccakHash(Ctx.all, B);
257    end C_Hash;
258 
259    procedure C_End(Ctx: C_Context_Access;
260                    Output: out Interfaces.C.Char_Array;
261                    Len: Interfaces.C.Size_T) is
262       L: Natural := Natural(Len);
263       S: String(1..L);
264       B: Bitstream(1..S'Length*8);
265       Count: Interfaces.C.Size_T;
266    begin
267       KeccakEnd(Ctx.all, B);
268       ToString(B, S);
269       Interfaces.C.To_C(S, Output(0..Len), Count, Append_Nul => False);
270       -- Len = Count
271    end C_End;
272 
273    procedure C_Context_Deallocate is new Ada.Unchecked_Deallocation
274      (C_Context, C_Context_Access);
275 
276    procedure C_Deallocate(Ctx: in out C_Context_Access) is
277    begin
278       C_Context_Deallocate(Ctx);
279    end C_Deallocate;
280 end Keccak_C;