1-- This program is free software; you can redistribute it and/or
2-- modify it under the terms of the GNU General Public License as
3-- published by the Free Software Foundation; either version 2 of the
4-- License, or (at your option) any later version.
5
6-- This program is distributed in the hope that it will be useful,
7-- but WITHOUT ANY WARRANTY; without even the implied warranty of
8-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9-- General Public License for more details.
10
11-- You should have received a copy of the GNU General Public License
12-- along with this program; if not, write to the Free Software
13-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
14-- 02111-1307, USA.
15
16-- As a special exception, if other files instantiate generics from
17-- this unit, or you link this unit with other files to produce an
18-- executable, this unit does not by itself cause the resulting
19-- executable to be covered by the GNU General Public License. This
20-- exception does not however invalidate any other reasons why the
21-- executable file might be covered by the GNU Public License.
22
23-- Original Source code author: Martin Kausche, 2008.
24-- This source code is released to the public domain.
25
26with Crypto.Symmetric.Algorithm.Threefish;
27use  Crypto.Symmetric.Algorithm.Threefish;
28
29package Crypto.Symmetric.Algorithm.Skein is
30
31   --Interface fixed to Skein 512 mode, 256 and 1024 mode available as well
32
33   type Generic_Interface is Interface;
34   type Skein_512_Context is new Generic_Interface with
35      record
36         Hash_Value : W_Block512;
37      end record;
38
39   ---------------------------------------------------------------------------
40
41   -- low level API with object
42   procedure Init(This 		: in out Skein_512_Context);
43
44   procedure Round(This 	: in out 	Skein_512_Context;
45                   Message_Block: in 		W_Block512);
46
47   function Final_Round(This 		    : in out Skein_512_Context;
48                        Last_Message_Block  : W_Block512;
49                        Last_Message_Length : Natural)
50                        return W_Block512;
51
52   ---------------------------------------------------------------------------
53
54   -- high level API
55
56   procedure Hash(Message : in String; Hash_Value : out W_Block512);
57
58   procedure Hash(Message : in Bytes;  Hash_Value : out W_Block512);
59
60   procedure F_Hash(Filename : in String; Hash_Value : out W_Block512);
61
62
63   --complete call for Skein
64   --no key or hashing is used here
65   -- Output / Message Length in Bits
66   procedure Skein_Complete
67     (Mode           	 : in Skein_Mode;
68      Output_Length_Bits : in Natural;
69      Message        	 : in Bytes;
70      Message_Length_Bits: in Natural;
71      Result         	 : out Bytes);
72
73
74private
75
76    --sometimes we need to set a single Bit inside of a Byte
77   procedure Set_Bit
78     (b        : in out Byte;
79      Position : in Natural;
80      Value    : in Boolean);
81
82
83   --also Input-Messages of length mod 8 != 0 are allowed, so we need
84   --a special type for this.
85   type Skein_Message_Length_Bits is range 0 .. Natural'Last * 8;
86
87   --for the Full Skein implementation we need a type
88   --for storing a list of message and tweak tuples
89   --we also want to store the correct message-length in Bits
90   --a record type is used for this
91   type Skein_Message_Tweak_Tuple
92     (Message_Length_Bits : Natural;
93      Message_Bytes_Last  : Integer)   --we need Integer here because if we
94                                       --have an empty
95   --array of Byte we need it with index 0..-1
96   is
97      record
98         Message        : Bytes (0 .. Message_Bytes_Last);
99         Message_Length : Natural := Message_Length_Bits;
100         Type_Value     : Byte;
101      end record;
102
103   --we need an array of this record type,
104   --as it is an unconstrained type which is not allowed in records
105   --we define an seperate acces type and build an array of
106   --access types :/
107   type Skein_Message_Tweak_Tuple_Pointer is access all
108     Skein_Message_Tweak_Tuple;
109   type Skein_Message_Tweak_Tuple_Pointer_Array is
110     array (Natural range <>) of Skein_Message_Tweak_Tuple_Pointer;
111
112   function Create
113     (Size : Natural)
114      return Skein_Message_Tweak_Tuple_Pointer_Array;
115   procedure Set_Data
116     (List                : in out Skein_Message_Tweak_Tuple_Pointer_Array;
117      Index               : in Natural;
118      Message             : in Bytes;
119      Message_Length_Bits : in Natural;
120      Type_Value          : in Byte);
121
122   --    package Skein_Message_Tweak_Tuple_Pointer_List is new
123   --Ada.Containers.Doubly_Linked_Lists(
124   --        Element_Type => Skein_Message_Tweak_Tuple_Pointer);
125
126
127
128   --we need Matrix or tensors of Integes to store various things
129   --we need this to initialize a tensor for saving the number of Differences
130   --for every word after every round
131   --we also use this type for saving the number of differences for every bit
132   type Integer_Tensor is
133     array (Natural range <>, Natural range <>, Natural range <>) of Integer;
134
135   type Integer_Matrix is
136     array (Natural range <>, Natural range <>) of Integer;
137
138   type Integer_Array is array (Natural range <>) of Integer;
139
140   type Bytes_Access is access Bytes;
141
142
143
144     --calculates a new Byte-Aray for a given length of Bits
145   --the most significant not ued Bit is set to 1
146   --all other unused Bits are set to 0
147   function Message_Bit_Padding
148     (Message        : in Bytes;
149      Desired_Length : in Natural)
150      return           Bytes;
151
152   --returns a Boolean-value if a Bit padding took place
153   --we need this information to calculate the configuration Sting later
154   function Get_Bit_Padding_Status
155     (Message        : in Bytes;
156      Desired_Length : in Natural)
157      return           Boolean;
158
159   --padds a given Byte-Array to a given length (defined by the Skein_Mode)
160   --too long arays will be cut off to the correct length
161   function Message_Byte_Padding
162     (Mode             : in Skein_Mode;
163      Original_Message : in Bytes)
164      return             Bytes;
165
166   --return a modified Tweak for given parameters
167   function Get_Current_Tweak
168     (T_S       : in Bytes;
169      N_M       : in DWord;      --Number of Bytes in Input
170                                                --Message
171      Index     : in Natural;    --index of Message Block we are curently
172                                 --working on
173      N_b       : in Natural;    --Number State-Bytes for the current mode
174      First_Run : in Boolean;    --a_i
175      Last_Run  : in Boolean;    --b_i
176      B         : in Boolean)    --was there any BitPadding?
177      return      Bytes;
178
179   --calculates the UBI for given parameters
180   --see Skein paper for details
181   procedure Straight_UBI
182     (Mode              : in Skein_Mode;
183      G                 : in Bytes;    --starting value on N_B Bytes
184      Full_Message      : in Bytes;    --Message of variable lenght
185      Full_Message_Bits : in Natural;  --the length of the input Message in
186                                       --Bits
187      T_S               : in Bytes;    --Starting Tweak T_S of 16 Byte
188      Result            : out Bytes);   --the result of UBI:
189
190
191   --calculates the output of the Skein Hashfunction for a given length
192   --internal UBI is used for this
193   --see Skein paper for details
194   procedure Output
195     (Mode   : in Skein_Mode;
196      G      : in Bytes;     --the chaining value
197      N_0    : in Natural;   --number of required output BITS
198      Result : out Bytes);    --the result, if N_0 mod 8 != 0
199                              --the last byte is only partially used
200
201   --returns the configuration String C for given parameters
202   --this String is used in Init
203   function Get_Configuration_String
204     (N_0  : in Natural;
205      Y_l  : in Natural := 0;
206      Y_f  : in Natural := 0;
207      Y_m  : in Natural := 0)
208      return Bytes;
209
210   --------------------------------------------------------
211   -- various Init, Update and Final calls
212   --------------------------------------------------------
213
214   --full Init call for Skein
215   --State is the result of the Configuration call
216   procedure Init
217     (Mode  : in Skein_Mode;
218      N_0   : in Natural;
219      K     : in Bytes;
220      Y_l   : in Natural;
221      Y_f   : in Natural;
222      Y_m   : in Natural;
223      State : out Bytes);
224
225   --simplified Init-call for Simple_Skein
226   --no key and no tree-hashing is used
227   procedure Init
228     (Mode  : in Skein_Mode;
229      N_0   : in Natural;
230      State : out Bytes);
231
232   --full Update call for Skein
233   --this Call can be done multiple times for a list of tuples (T,M)
234   --New-State is the result after each UBI
235   procedure Update
236     (Mode           : in Skein_Mode;
237      Old_State      : in Bytes;
238      Message        : in Bytes;
239      Message_Length : in Natural;
240      Type_Value     : in Byte;
241      Y_l            : in Natural;
242      Y_f            : in Natural;
243      Y_m            : in Natural;
244      New_State      : out Bytes);
245
246   --simplified Update call for Skein
247   --no key or treehashing is used
248   procedure Update
249     (Mode           : in Skein_Mode;
250      Old_State      : in Bytes;
251      Message        : in Bytes;
252      Message_Length : in Natural;
253      New_State      : out Bytes);
254
255   --Final call for Skein
256   --here only the correct is calculated using UBI
257   --see Skein paper for details
258   procedure Final
259     (Mode      : in Skein_Mode;
260      Old_State : in Bytes;
261      N_0       : in Natural;
262      New_State : out Bytes);
263
264
265   --all-in-one-call for Skein
266   --here an array of tuples (T,M) is used as inputs
267   procedure Hash
268     (Mode        : in Skein_Mode;
269      N_0         : in Natural;
270      K           : in Bytes;
271      Y_l         : in Natural;
272      Y_f         : in Natural;
273      Y_m         : in Natural;
274      Tuple_Array : in Skein_Message_Tweak_Tuple_Pointer_Array;
275      Result      : out Bytes);
276
277   --all-in-one-call for Skein
278   --using only one tuple (T,M)
279   procedure Hash
280     (Mode           : in Skein_Mode;
281      N_0            : in Natural;
282      K              : in Bytes;
283      Y_l            : in Natural;
284      Y_f            : in Natural;
285      Y_m            : in Natural;
286      Message        : in Bytes;
287      Message_Length : in Natural;
288      Type_Value     : in Byte;
289      Result         : out Bytes);
290
291end Crypto.Symmetric.Algorithm.Skein;
292