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