├── .gitattributes ├── .gitignore ├── Binding_Sodium ├── sodium-functions.adb ├── sodium-functions.ads ├── sodium-thin_binding.ads └── sodium.ads ├── License.txt ├── README.md ├── default.gpr └── examples ├── AEAD ├── demo-c.c ├── demo.gpr └── demo_ada.adb ├── common.gpr ├── encryption ├── demo.gpr └── demo_ada.adb ├── hash_multipart ├── demo-c.c ├── demo.gpr └── demo_ada.adb ├── hash_password ├── demo-c.c ├── demo.gpr └── demo_ada.adb ├── hash_short ├── demo-c.c ├── demo.gpr └── demo_ada.adb ├── hash_single ├── demo-c.c ├── demo.gpr └── demo_ada.adb ├── msg_authentication ├── demo.gpr └── demo_ada.adb ├── nonce ├── demo.gpr └── demo_ada.adb ├── random ├── demo.gpr └── demo_ada.adb ├── sealed_box ├── demo.gpr └── demo_ada.adb ├── signatures ├── demo-c.c ├── demo.gpr └── demo_ada.adb └── symmetric_encryption ├── demo.gpr └── demo_ada.adb /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf 3 | 4 | *.adb text 5 | *.ads text 6 | *.gpr text 7 | *.md text 8 | *.html text 9 | *.shtml text 10 | *.css text 11 | *.tpl text 12 | 13 | *.png binary 14 | *.jpg binary 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | run 3 | libsodium-1.0.10-mingw 4 | 5 | # Object file 6 | *.o 7 | 8 | # Ada Library Information 9 | *.ali 10 | 11 | Makefile 12 | -------------------------------------------------------------------------------- /Binding_Sodium/sodium-functions.adb: -------------------------------------------------------------------------------- 1 | -- This file is covered by the Internet Software Consortium (ISC) License 2 | -- Reference: ../License.txt 3 | 4 | package body Sodium.Functions is 5 | 6 | --------------------------------- 7 | -- initialize_sodium_library -- 8 | --------------------------------- 9 | function initialize_sodium_library return Boolean 10 | is 11 | use type Thin.IC.int; 12 | res : Thin.IC.int; 13 | begin 14 | res := Thin.sodium_init; 15 | if res = 1 then 16 | raise Sodium_Already_Initialized; 17 | end if; 18 | return (res = 0); 19 | end initialize_sodium_library; 20 | 21 | 22 | ----------------------- 23 | -- Keyless_Hash #1 -- 24 | ----------------------- 25 | function Keyless_Hash (plain_text : String) return Standard_Hash 26 | is 27 | res : Thin.IC.int; 28 | hash_length : constant Thin.IC.size_t := Thin.IC.size_t (Standard_Hash'Length); 29 | target : aliased Thin.IC.char_array := (1 .. hash_length => Thin.IC.nul); 30 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 31 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (plain_text'Length); 32 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (plain_text); 33 | begin 34 | res := Thin.crypto_generichash (text_out => hash_pointer, 35 | outlen => hash_length, 36 | text_in => text_pointer, 37 | inlen => text_length, 38 | key => Thin.ICS.Null_Ptr, 39 | keylen => 0); 40 | Thin.ICS.Free (text_pointer); 41 | return convert (target); 42 | end Keyless_Hash; 43 | 44 | 45 | ----------------------- 46 | -- Keyless_Hash #2 -- 47 | ----------------------- 48 | function Keyless_Hash (plain_text : String; 49 | output_size : Hash_Size_Range) return Any_Hash 50 | is 51 | res : Thin.IC.int; 52 | hash_length : constant Thin.IC.size_t := Thin.IC.size_t (output_size); 53 | target : aliased Thin.IC.char_array := (1 .. hash_length => Thin.IC.nul); 54 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 55 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (plain_text'Length); 56 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (plain_text); 57 | begin 58 | res := Thin.crypto_generichash (text_out => hash_pointer, 59 | outlen => hash_length, 60 | text_in => text_pointer, 61 | inlen => text_length, 62 | key => Thin.ICS.Null_Ptr, 63 | keylen => 0); 64 | Thin.ICS.Free (text_pointer); 65 | return convert (target); 66 | end Keyless_Hash; 67 | 68 | 69 | --------------------- 70 | -- Keyed_Hash #1 -- 71 | --------------------- 72 | function Keyed_Hash (plain_text : String; key : Standard_Key) return Standard_Hash 73 | is 74 | res : Thin.IC.int; 75 | hash_length : constant Thin.IC.size_t := Thin.IC.size_t (Standard_Hash'Length); 76 | target : aliased Thin.IC.char_array := (1 .. hash_length => Thin.IC.nul); 77 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 78 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (plain_text'Length); 79 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (plain_text); 80 | key_length : constant Thin.IC.size_t := Thin.IC.size_t (key'Length); 81 | key_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (key); 82 | begin 83 | res := Thin.crypto_generichash (text_out => hash_pointer, 84 | outlen => hash_length, 85 | text_in => text_pointer, 86 | inlen => text_length, 87 | key => key_pointer, 88 | keylen => key_length); 89 | Thin.ICS.Free (text_pointer); 90 | Thin.ICS.Free (key_pointer); 91 | return convert (target); 92 | end Keyed_Hash; 93 | 94 | 95 | --------------------- 96 | -- Keyed_Hash #2 -- 97 | --------------------- 98 | function Keyed_Hash (plain_text : String; 99 | key : Any_Key; 100 | output_size : Hash_Size_Range) return Any_Hash 101 | is 102 | res : Thin.IC.int; 103 | hash_length : constant Thin.IC.size_t := Thin.IC.size_t (output_size); 104 | target : aliased Thin.IC.char_array := (1 .. hash_length => Thin.IC.nul); 105 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 106 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (plain_text'Length); 107 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (plain_text); 108 | key_length : constant Thin.IC.size_t := Thin.IC.size_t (key'Length); 109 | key_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (key); 110 | begin 111 | res := Thin.crypto_generichash (text_out => hash_pointer, 112 | outlen => hash_length, 113 | text_in => text_pointer, 114 | inlen => text_length, 115 | key => key_pointer, 116 | keylen => key_length); 117 | Thin.ICS.Free (text_pointer); 118 | Thin.ICS.Free (key_pointer); 119 | return convert (target); 120 | end Keyed_Hash; 121 | 122 | 123 | ------------------ 124 | -- convert #1 -- 125 | ------------------ 126 | function convert (data : Thin.IC.char_array) return String 127 | is 128 | use type Thin.IC.size_t; 129 | result : String (1 .. data'Length); 130 | arrow : Thin.IC.size_t := data'First; 131 | begin 132 | for z in result'Range loop 133 | result (z) := Character (data (arrow)); 134 | arrow := arrow + 1; 135 | end loop; 136 | return result; 137 | end convert; 138 | 139 | ------------------ 140 | -- convert #2 -- 141 | ------------------ 142 | function convert (data : String) return Thin.IC.char_array 143 | is 144 | use type Thin.IC.size_t; 145 | reslen : Thin.IC.size_t := Thin.IC.size_t (data'Length); 146 | result : Thin.IC.char_array (1 .. reslen); 147 | arrow : Thin.IC.size_t := 1; 148 | begin 149 | for z in data'Range loop 150 | result (arrow) := Thin.IC.char (data (z)); 151 | arrow := arrow + 1; 152 | end loop; 153 | return result; 154 | end convert; 155 | 156 | 157 | ---------------------------- 158 | -- Multipart_Hash_Start -- 159 | ---------------------------- 160 | function Multipart_Hash_Start (output_size : Hash_Size_Range) return Hash_State 161 | is 162 | res : Thin.IC.int; 163 | result : Hash_State; 164 | begin 165 | result.hash_length := Thin.IC.size_t (output_size); 166 | res := Thin.crypto_generichash_init (state => result.state'Unchecked_Access, 167 | key => Thin.ICS.Null_Ptr, 168 | keylen => 0, 169 | outlen => result.hash_length); 170 | return result; 171 | end Multipart_Hash_Start; 172 | 173 | 174 | ---------------------------------- 175 | -- Multipart_Keyed_Hash_Start -- 176 | ---------------------------------- 177 | function Multipart_Keyed_Hash_Start (key : Any_Key; 178 | output_size : Hash_Size_Range) return Hash_State 179 | is 180 | res : Thin.IC.int; 181 | result : Hash_State; 182 | key_length : constant Thin.IC.size_t := Thin.IC.size_t (key'Length); 183 | key_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (key); 184 | begin 185 | result.hash_length := Thin.IC.size_t (output_size); 186 | res := Thin.crypto_generichash_init (state => result.state'Unchecked_Access, 187 | key => key_pointer, 188 | keylen => key_length, 189 | outlen => result.hash_length); 190 | Thin.ICS.Free (key_pointer); 191 | return result; 192 | end Multipart_Keyed_Hash_Start; 193 | 194 | 195 | ------------------------ 196 | -- Multipart_Append -- 197 | ------------------------ 198 | procedure Multipart_Append (plain_text : String; state : in out Hash_State) 199 | is 200 | res : Thin.IC.int; 201 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (plain_text'Length); 202 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (plain_text); 203 | begin 204 | res := Thin.crypto_generichash_update (state => state.state'Unchecked_Access, 205 | text_in => text_pointer, 206 | inlen => text_length); 207 | Thin.ICS.Free (text_pointer); 208 | end Multipart_Append; 209 | 210 | 211 | ------------------------------- 212 | -- Multipart_Hash_Complete -- 213 | ------------------------------- 214 | function Multipart_Hash_Complete (state : in out Hash_State) return Any_Hash 215 | is 216 | res : Thin.IC.int; 217 | target : aliased Thin.IC.char_array := (1 .. state.hash_length => Thin.IC.nul); 218 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 219 | begin 220 | res := Thin.crypto_generichash_final (state => state.state'Unchecked_Access, 221 | text_out => hash_pointer, 222 | outlen => state.hash_length); 223 | return convert (target); 224 | end Multipart_Hash_Complete; 225 | 226 | 227 | ------------------------ 228 | -- Short_Input_Hash -- 229 | ------------------------ 230 | function Short_Input_Hash (short_data : String; key : Short_Key) return Short_Hash 231 | is 232 | res : Thin.IC.int; 233 | hash_length : constant Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_shorthash_BYTES); 234 | target : aliased Thin.IC.char_array := (1 .. hash_length => Thin.IC.nul); 235 | hash_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (target'Unchecked_Access); 236 | text_length : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (short_data'Length); 237 | text_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (short_data); 238 | key_pointer : Thin.ICS.chars_ptr := Thin.ICS.New_String (key); 239 | begin 240 | res := Thin.crypto_shorthash (text_out => hash_pointer, 241 | text_in => text_pointer, 242 | inlen => text_length, 243 | k => key_pointer); 244 | Thin.ICS.Free (text_pointer); 245 | Thin.ICS.Free (key_pointer); 246 | return convert (target); 247 | end Short_Input_Hash; 248 | 249 | 250 | ------------------- 251 | -- Random_Word -- 252 | ------------------- 253 | function Random_Word return Natural32 254 | is 255 | result : Thin.NaCl_uint32 := Thin.randombytes_random; 256 | begin 257 | return Natural32 (result); 258 | end Random_Word; 259 | 260 | 261 | --------------------------- 262 | -- Random_Limited_Word -- 263 | --------------------------- 264 | function Random_Limited_Word (upper_bound : Natural32) return Natural32 265 | is 266 | upper : Thin.NaCl_uint32 := Thin.NaCl_uint32 (upper_bound); 267 | result : Thin.NaCl_uint32 := Thin.randombytes_uniform (upper); 268 | begin 269 | return Natural32 (result); 270 | end Random_Limited_Word; 271 | 272 | 273 | ------------------- 274 | -- Random_Salt -- 275 | ------------------- 276 | function Random_Salt return Password_Salt 277 | is 278 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Password_Salt'Last); 279 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 280 | begin 281 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 282 | return convert (buffer); 283 | end Random_Salt; 284 | 285 | 286 | ------------------------ 287 | -- Random_Short_Key -- 288 | ------------------------ 289 | function Random_Short_Key return Short_Key 290 | is 291 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Short_Key'Last); 292 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 293 | begin 294 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 295 | return convert (buffer); 296 | end Random_Short_Key; 297 | 298 | 299 | -------------------------------- 300 | -- Random_Standard_Hash_key -- 301 | -------------------------------- 302 | function Random_Standard_Hash_Key return Standard_Key 303 | is 304 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Standard_Key'Last); 305 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 306 | begin 307 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 308 | return convert (buffer); 309 | end Random_Standard_Hash_Key; 310 | 311 | 312 | ----------------------- 313 | -- Random_Hash_Key -- 314 | ----------------------- 315 | function Random_Hash_Key (Key_Size : Key_Size_Range) return Any_Key 316 | is 317 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Key_Size); 318 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 319 | begin 320 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 321 | return convert (buffer); 322 | end Random_Hash_Key; 323 | 324 | 325 | ---------------------------- 326 | -- Random_Sign_Key_seed -- 327 | ---------------------------- 328 | function Random_Sign_Key_seed return Sign_Key_Seed 329 | is 330 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Sign_Key_Seed'Last); 331 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 332 | begin 333 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 334 | return convert (buffer); 335 | end Random_Sign_Key_seed; 336 | 337 | 338 | --------------------------- 339 | -- Random_Box_Key_seed -- 340 | --------------------------- 341 | function Random_Box_Key_seed return Box_Key_Seed 342 | is 343 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Box_Key_Seed'Last); 344 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 345 | begin 346 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 347 | return convert (buffer); 348 | end Random_Box_Key_seed; 349 | 350 | 351 | -------------------- 352 | -- Random_Nonce -- 353 | -------------------- 354 | function Random_Nonce return Box_Nonce 355 | is 356 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Box_Nonce'Last); 357 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 358 | begin 359 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 360 | return convert (buffer); 361 | end Random_Nonce; 362 | 363 | 364 | ---------------------------- 365 | -- Random_Symmetric_Key -- 366 | ---------------------------- 367 | function Random_Symmetric_Key return Symmetric_Key 368 | is 369 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Symmetric_Key'Last); 370 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 371 | begin 372 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 373 | return convert (buffer); 374 | end Random_Symmetric_Key; 375 | 376 | 377 | ------------------------------ 378 | -- Random_Symmetric_Nonce -- 379 | ------------------------------ 380 | function Random_Symmetric_Nonce return Symmetric_Nonce 381 | is 382 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Symmetric_Nonce'Last); 383 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 384 | begin 385 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 386 | return convert (buffer); 387 | end Random_Symmetric_Nonce; 388 | 389 | 390 | ----------------------- 391 | -- Random_Auth_Key -- 392 | ----------------------- 393 | function Random_Auth_Key return Auth_Key 394 | is 395 | bufferlen : constant Thin.IC.size_t := Thin.IC.size_t (Auth_Key'Last); 396 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 397 | begin 398 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 399 | return convert (buffer); 400 | end Random_Auth_Key; 401 | 402 | 403 | ------------------------- 404 | -- Random_AEAD_Nonce -- 405 | ------------------------- 406 | function Random_AEAD_Nonce (construction : AEAD_Construction := ChaCha20_Poly1305) 407 | return AEAD_Nonce 408 | is 409 | function nonce_size return Thin.IC.size_t; 410 | function nonce_size return Thin.IC.size_t is 411 | begin 412 | case construction is 413 | when ChaCha20_Poly1305 => 414 | return Thin.IC.size_t (Thin.crypto_aead_chacha20poly1305_NPUBBYTES); 415 | when ChaCha20_Poly1305_IETF => 416 | return Thin.IC.size_t (Thin.crypto_aead_chacha20poly1305_ietf_NPUBBYTES); 417 | when AES256_GCM => 418 | return Thin.IC.size_t (Thin.crypto_aead_aes256gcm_NPUBBYTES); 419 | end case; 420 | end nonce_size; 421 | bufferlen : constant Thin.IC.size_t := nonce_size; 422 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 423 | begin 424 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 425 | return convert (buffer); 426 | end Random_AEAD_Nonce; 427 | 428 | 429 | ----------------------- 430 | -- Random_AEAD_Key -- 431 | ----------------------- 432 | function Random_AEAD_Key (construction : AEAD_Construction := ChaCha20_Poly1305) 433 | return AEAD_Key 434 | is 435 | function key_size return Thin.IC.size_t; 436 | function key_size return Thin.IC.size_t is 437 | begin 438 | case construction is 439 | when ChaCha20_Poly1305 => 440 | return Thin.IC.size_t (Thin.crypto_aead_chacha20poly1305_KEYBYTES); 441 | when ChaCha20_Poly1305_IETF => 442 | return Thin.IC.size_t (Thin.crypto_aead_chacha20poly1305_ietf_KEYBYTES); 443 | when AES256_GCM => 444 | return Thin.IC.size_t (Thin.crypto_aead_aes256gcm_KEYBYTES); 445 | end case; 446 | end key_size; 447 | bufferlen : constant Thin.IC.size_t := key_size; 448 | buffer : Thin.IC.char_array := (1 .. bufferlen => Thin.IC.nul); 449 | begin 450 | Thin.randombytes_buf (buf => buffer (buffer'First)'Address, size => bufferlen); 451 | return convert (buffer); 452 | end Random_AEAD_Key; 453 | 454 | 455 | --------------------------- 456 | -- Derive_Password_Key -- 457 | --------------------------- 458 | function Derive_Password_Key 459 | (criticality : Data_Criticality := online_interactive; 460 | passkey_size : Passkey_Size_Range := Positive (Thin.crypto_box_SEEDBYTES); 461 | password : String; 462 | salt : Password_Salt) return Any_Password_Key 463 | is 464 | opslimit : Thin.NaCl_uint64; 465 | memlimit : Thin.IC.size_t; 466 | 467 | password_size : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (password'Length); 468 | password_tank : aliased Thin.IC.char_array := convert (password); 469 | password_pointer : Thin.ICS.chars_ptr := 470 | Thin.ICS.To_Chars_Ptr (password_tank'Unchecked_Access); 471 | passkey_size_F : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (passkey_size); 472 | passkey_size_C : constant Thin.IC.size_t := Thin.IC.size_t (passkey_size); 473 | passkey_tank : aliased Thin.IC.char_array := (1 .. passkey_size_C => Thin.IC.nul); 474 | passkey_pointer : Thin.ICS.chars_ptr := 475 | Thin.ICS.To_Chars_Ptr (passkey_tank'Unchecked_Access); 476 | salt_tank : aliased Thin.IC.char_array := convert (salt); 477 | salt_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (salt_tank'Unchecked_Access); 478 | begin 479 | case criticality is 480 | when online_interactive => 481 | opslimit := Thin.crypto_pwhash_OPSLIMIT_INTERACTIVE; 482 | memlimit := Thin.crypto_pwhash_MEMLIMIT_INTERACTIVE; 483 | when moderate => 484 | opslimit := Thin.crypto_pwhash_OPSLIMIT_MODERATE; 485 | memlimit := Thin.crypto_pwhash_MEMLIMIT_MODERATE; 486 | when highly_sensitive => 487 | opslimit := Thin.crypto_pwhash_OPSLIMIT_SENSITIVE; 488 | memlimit := Thin.crypto_pwhash_MEMLIMIT_SENSITIVE; 489 | end case; 490 | declare 491 | use type Thin.IC.int; 492 | res : Thin.IC.int; 493 | begin 494 | res := Thin.crypto_pwhash (text_out => passkey_pointer, 495 | outlen => passkey_size_F, 496 | passwd => password_pointer, 497 | passwdlen => password_size, 498 | salt => salt_pointer, 499 | opslimit => opslimit, 500 | memlimit => memlimit, 501 | alg => Thin.crypto_pwhash_ALG_DEFAULT); 502 | if res /= 0 then 503 | raise Sodium_Out_Of_Memory with "Derive_Password_Key"; 504 | end if; 505 | end; 506 | return convert (passkey_tank); 507 | end Derive_Password_Key; 508 | 509 | 510 | ------------------------------ 511 | -- Generate_Password_Hash -- 512 | ------------------------------ 513 | function Generate_Password_Hash (criticality : Data_Criticality := online_interactive; 514 | password : String) return Any_Hash 515 | is 516 | opslimit : Thin.NaCl_uint64; 517 | memlimit : Thin.IC.size_t; 518 | hash_tank : Thin.Password_Hash_Container; 519 | 520 | password_size : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (password'Length); 521 | password_tank : aliased Thin.IC.char_array := convert (password); 522 | password_pointer : Thin.ICS.chars_ptr := 523 | Thin.ICS.To_Chars_Ptr (password_tank'Unchecked_Access); 524 | begin 525 | case criticality is 526 | when online_interactive => 527 | opslimit := Thin.crypto_pwhash_OPSLIMIT_INTERACTIVE; 528 | memlimit := Thin.crypto_pwhash_MEMLIMIT_INTERACTIVE; 529 | when moderate => 530 | opslimit := Thin.crypto_pwhash_OPSLIMIT_MODERATE; 531 | memlimit := Thin.crypto_pwhash_MEMLIMIT_MODERATE; 532 | when highly_sensitive => 533 | opslimit := Thin.crypto_pwhash_OPSLIMIT_SENSITIVE; 534 | memlimit := Thin.crypto_pwhash_MEMLIMIT_SENSITIVE; 535 | end case; 536 | declare 537 | use type Thin.IC.int; 538 | use type Thin.IC.char; 539 | res : Thin.IC.int; 540 | product : String (hash_tank'Range); 541 | lastz : Natural := 0; 542 | begin 543 | res := Thin.crypto_pwhash_str (text_out => hash_tank, 544 | passwd => password_pointer, 545 | passwdlen => password_size, 546 | opslimit => opslimit, 547 | memlimit => memlimit); 548 | if res /= 0 then 549 | raise Sodium_Out_Of_Memory with "Generate_Password_Hash"; 550 | end if; 551 | for z in hash_tank'Range loop 552 | if hash_tank (z) = Thin.IC.nul then 553 | return product (product'First .. lastz); 554 | end if; 555 | product (z) := Character (hash_tank (z)); 556 | lastz := z; 557 | end loop; 558 | return product; 559 | end; 560 | end Generate_Password_Hash; 561 | 562 | 563 | ----------------------------- 564 | -- Password_Hash_Matches -- 565 | ----------------------------- 566 | function Password_Hash_Matches (hash : Any_Hash; password : String) return Boolean 567 | is 568 | hash_tank : Thin.Password_Hash_Container := (others => Thin.IC.nul); 569 | password_size : constant Thin.NaCl_uint64 := Thin.NaCl_uint64 (password'Length); 570 | password_tank : aliased Thin.IC.char_array := convert (password); 571 | password_pointer : Thin.ICS.chars_ptr := 572 | Thin.ICS.To_Chars_Ptr (password_tank'Unchecked_Access); 573 | arrow : Positive := Thin.Password_Hash_Container'First; 574 | begin 575 | for z in hash'Range loop 576 | hash_tank (arrow) := Thin.IC.char (hash (z)); 577 | arrow := arrow + 1; 578 | end loop; 579 | declare 580 | use type Thin.IC.int; 581 | res : Thin.IC.int; 582 | begin 583 | res := Thin.crypto_pwhash_str_verify (text_str => hash_tank, 584 | passwd => password_pointer, 585 | passwdlen => password_size); 586 | return (res = 0); 587 | end; 588 | end Password_Hash_Matches; 589 | 590 | 591 | ---------------------- 592 | -- As_Hexidecimal -- 593 | ---------------------- 594 | function As_Hexidecimal (binary : String) return String 595 | is 596 | type byte is mod 2 ** 8; 597 | subtype octet is String (1 .. 2); 598 | function Hex (mychar : Character) return octet; 599 | 600 | mask0 : constant byte := 16#F#; 601 | mask1 : constant byte := 16#F0#; 602 | zero : constant Natural := Character'Pos ('0'); 603 | alpha : constant Natural := Character'Pos ('a') - 10; 604 | 605 | function Hex (mychar : Character) return octet 606 | is 607 | mybyte : byte := byte (Character'Pos (mychar)); 608 | val0 : byte := (mybyte and mask0); 609 | val1 : byte := (mybyte and mask1); 610 | result : octet; 611 | begin 612 | case val0 is 613 | when 0 .. 9 => result (2) := Character'Val (zero + Natural (val0)); 614 | when 10 .. 15 => result (2) := Character'Val (alpha + Natural (val0)); 615 | when others => null; 616 | end case; 617 | case val1 is 618 | when 16#00# => result (1) := '0'; 619 | when 16#10# => result (1) := '1'; 620 | when 16#20# => result (1) := '2'; 621 | when 16#30# => result (1) := '3'; 622 | when 16#40# => result (1) := '4'; 623 | when 16#50# => result (1) := '5'; 624 | when 16#60# => result (1) := '6'; 625 | when 16#70# => result (1) := '7'; 626 | when 16#80# => result (1) := '8'; 627 | when 16#90# => result (1) := '9'; 628 | when 16#A0# => result (1) := 'a'; 629 | when 16#B0# => result (1) := 'b'; 630 | when 16#C0# => result (1) := 'c'; 631 | when 16#D0# => result (1) := 'd'; 632 | when 16#E0# => result (1) := 'e'; 633 | when 16#F0# => result (1) := 'f'; 634 | when others => null; 635 | end case; 636 | return result; 637 | end Hex; 638 | 639 | product : String (1 .. 2 * binary'Length); 640 | arrow : Positive := 1; 641 | begin 642 | for z in binary'Range loop 643 | product (arrow .. arrow + 1) := Hex (binary (z)); 644 | arrow := arrow + 2; 645 | end loop; 646 | return product; 647 | end As_Hexidecimal; 648 | 649 | 650 | ----------------- 651 | -- As_Binary -- 652 | ----------------- 653 | function As_Binary (hexidecimal : String; ignore : String := "") return String 654 | is 655 | subtype octet is String (1 .. 2); 656 | function decvalue (byte : octet) return Character; 657 | 658 | pass1 : String := (1 .. hexidecimal'Length => ASCII.NUL); 659 | real_size : Natural := 0; 660 | adiff : constant Natural := Character'Pos ('a') - Character'Pos ('A'); 661 | found : Boolean; 662 | 663 | function decvalue (byte : octet) return Character 664 | is 665 | position : Natural := 0; 666 | zero : constant Natural := Character'Pos ('0'); 667 | alpha : constant Natural := Character'Pos ('A') - 10; 668 | sixt : Character renames byte (1); 669 | ones : Character renames byte (2); 670 | begin 671 | case sixt is 672 | when '0' .. '9' => position := (Character'Pos (sixt) - zero) * 16; 673 | when 'A' .. 'F' => position := (Character'Pos (sixt) - alpha) * 16; 674 | when others => null; 675 | end case; 676 | case byte (2) is 677 | when '0' .. '9' => position := position + (Character'Pos (ones) - zero); 678 | when 'A' .. 'F' => position := position + (Character'Pos (ones) - alpha); 679 | when others => null; 680 | end case; 681 | return Character'Val (position); 682 | end decvalue; 683 | 684 | begin 685 | for z in hexidecimal'Range loop 686 | case hexidecimal (z) is 687 | when '0' .. '9' | 'A' .. 'F' => 688 | real_size := real_size + 1; 689 | pass1 (real_size) := hexidecimal (z); 690 | when 'a' .. 'f' => 691 | real_size := real_size + 1; 692 | pass1 (real_size) := Character'Val (Character'Pos (hexidecimal (z)) - adiff); 693 | when others => 694 | found := False; 695 | for y in ignore'Range loop 696 | if hexidecimal (z) = ignore (y) then 697 | found := True; 698 | exit; 699 | end if; 700 | end loop; 701 | if not found then 702 | raise Sodium_Invalid_Input 703 | with "As_Binary - illegal character: " & hexidecimal (z); 704 | end if; 705 | end case; 706 | end loop; 707 | if real_size = 0 then 708 | raise Sodium_Invalid_Input 709 | with "As_Binary - no hexidecimal digits found: " & hexidecimal; 710 | end if; 711 | if real_size mod 2 /= 0 then 712 | raise Sodium_Invalid_Input 713 | with "As_Binary - odd number of hexidecimal digits: " & hexidecimal; 714 | end if; 715 | declare 716 | bin_size : constant Natural := real_size / 2; 717 | product : String (1 .. bin_size); 718 | index : Natural; 719 | begin 720 | for z in 1 .. bin_size loop 721 | index := z * 2 - 1; 722 | product (z) := decvalue (pass1 (index .. index + 1)); 723 | end loop; 724 | return product; 725 | end; 726 | end As_Binary; 727 | 728 | 729 | ----------------------------- 730 | -- Generate_Sign_Keys #1 -- 731 | ----------------------------- 732 | procedure Generate_Sign_Keys (sign_key_public : out Public_Sign_Key; 733 | sign_key_secret : out Secret_Sign_Key) 734 | is 735 | res : Thin.IC.int; 736 | public_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_sign_PUBLICKEYBYTES); 737 | public_key_tank : aliased Thin.IC.char_array := (1 .. public_key_size => Thin.IC.nul); 738 | public_pointer : Thin.ICS.chars_ptr := 739 | Thin.ICS.To_Chars_Ptr (public_key_tank'Unchecked_Access); 740 | 741 | secret_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_sign_SECRETKEYBYTES); 742 | secret_key_tank : aliased Thin.IC.char_array := (1 .. secret_key_size => Thin.IC.nul); 743 | secret_pointer : Thin.ICS.chars_ptr := 744 | Thin.ICS.To_Chars_Ptr (secret_key_tank'Unchecked_Access); 745 | begin 746 | res := Thin.crypto_sign_keypair (pk => public_pointer, sk => secret_pointer); 747 | sign_key_public := convert (public_key_tank); 748 | sign_key_secret := convert (secret_key_tank); 749 | end Generate_Sign_Keys; 750 | 751 | 752 | ----------------------------- 753 | -- Generate_Sign_Keys #2 -- 754 | ----------------------------- 755 | procedure Generate_Sign_Keys (sign_key_public : out Public_Sign_Key; 756 | sign_key_secret : out Secret_Sign_Key; 757 | seed : Sign_Key_Seed) 758 | is 759 | res : Thin.IC.int; 760 | public_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_sign_PUBLICKEYBYTES); 761 | public_key_tank : aliased Thin.IC.char_array := (1 .. public_key_size => Thin.IC.nul); 762 | public_pointer : Thin.ICS.chars_ptr := 763 | Thin.ICS.To_Chars_Ptr (public_key_tank'Unchecked_Access); 764 | 765 | secret_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_sign_SECRETKEYBYTES); 766 | secret_key_tank : aliased Thin.IC.char_array := (1 .. secret_key_size => Thin.IC.nul); 767 | secret_pointer : Thin.ICS.chars_ptr := 768 | Thin.ICS.To_Chars_Ptr (secret_key_tank'Unchecked_Access); 769 | seed_tank : aliased Thin.IC.char_array := convert (seed); 770 | seed_pointer : Thin.ICS.chars_ptr := 771 | Thin.ICS.To_Chars_Ptr (seed_tank'Unchecked_Access); 772 | begin 773 | res := Thin.crypto_sign_seed_keypair (pk => public_pointer, 774 | sk => secret_pointer, 775 | seed => seed_pointer); 776 | sign_key_public := convert (public_key_tank); 777 | sign_key_secret := convert (secret_key_tank); 778 | end Generate_Sign_Keys; 779 | 780 | 781 | ------------------------ 782 | -- Obtain_Signature -- 783 | ------------------------ 784 | function Obtain_Signature (plain_text_message : String; 785 | sign_key_secret : Secret_Sign_Key) return Signature 786 | is 787 | res : Thin.IC.int; 788 | message_tank : aliased Thin.IC.char_array := convert (plain_text_message); 789 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 790 | message_pointer : Thin.ICS.chars_ptr := 791 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 792 | secret_tank : aliased Thin.IC.char_array := convert (sign_key_secret); 793 | secret_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (secret_tank'Unchecked_Access); 794 | 795 | result_size : Thin.IC.size_t := Thin.IC.size_t (Signature'Length); 796 | result_tank : aliased Thin.IC.char_array := (1 .. result_size => Thin.IC.nul); 797 | result_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (result_tank'Unchecked_Access); 798 | begin 799 | res := Thin.crypto_sign_detached (sig => result_pointer, 800 | siglen => Thin.ICS.Null_Ptr, 801 | m => message_pointer, 802 | mlen => message_size, 803 | sk => secret_pointer); 804 | return convert (result_tank); 805 | end Obtain_Signature; 806 | 807 | 808 | ------------------------- 809 | -- Signature_Matches -- 810 | ------------------------- 811 | function Signature_Matches (plain_text_message : String; 812 | sender_signature : Signature; 813 | sender_sign_key : Public_Sign_Key) return Boolean 814 | is 815 | use type Thin.IC.int; 816 | res : Thin.IC.int; 817 | message_tank : aliased Thin.IC.char_array := convert (plain_text_message); 818 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 819 | message_pointer : Thin.ICS.chars_ptr := 820 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 821 | sendsig_tank : aliased Thin.IC.char_array := convert (sender_signature); 822 | sendsig_pointer : Thin.ICS.chars_ptr := 823 | Thin.ICS.To_Chars_Ptr (sendsig_tank'Unchecked_Access); 824 | sendkey_tank : aliased Thin.IC.char_array := convert (sender_sign_key); 825 | sendkey_pointer : Thin.ICS.chars_ptr := 826 | Thin.ICS.To_Chars_Ptr (sendkey_tank'Unchecked_Access); 827 | begin 828 | res := Thin.crypto_sign_verify_detached (sig => sendsig_pointer, 829 | m => message_pointer, 830 | mlen => message_size, 831 | pk => sendkey_pointer); 832 | return (res = 0); 833 | end Signature_Matches; 834 | 835 | 836 | ---------------------------- 837 | -- Generate_Box_Keys #1 -- 838 | ---------------------------- 839 | procedure Generate_Box_Keys (box_key_public : out Public_Box_Key; 840 | box_key_secret : out Secret_Box_Key) 841 | is 842 | res : Thin.IC.int; 843 | public_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_box_PUBLICKEYBYTES); 844 | public_key_tank : aliased Thin.IC.char_array := (1 .. public_key_size => Thin.IC.nul); 845 | public_pointer : Thin.ICS.chars_ptr := 846 | Thin.ICS.To_Chars_Ptr (public_key_tank'Unchecked_Access); 847 | 848 | secret_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_box_SECRETKEYBYTES); 849 | secret_key_tank : aliased Thin.IC.char_array := (1 .. secret_key_size => Thin.IC.nul); 850 | secret_pointer : Thin.ICS.chars_ptr := 851 | Thin.ICS.To_Chars_Ptr (secret_key_tank'Unchecked_Access); 852 | begin 853 | res := Thin.crypto_box_keypair (pk => public_pointer, sk => secret_pointer); 854 | box_key_public := convert (public_key_tank); 855 | box_key_secret := convert (secret_key_tank); 856 | end Generate_Box_Keys; 857 | 858 | 859 | ---------------------------- 860 | -- Generate_Box_Keys #2 -- 861 | ---------------------------- 862 | procedure Generate_Box_Keys (box_key_public : out Public_Box_Key; 863 | box_key_secret : out Secret_Box_Key; 864 | seed : Box_Key_Seed) 865 | is 866 | res : Thin.IC.int; 867 | public_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_box_PUBLICKEYBYTES); 868 | public_key_tank : aliased Thin.IC.char_array := (1 .. public_key_size => Thin.IC.nul); 869 | public_pointer : Thin.ICS.chars_ptr := 870 | Thin.ICS.To_Chars_Ptr (public_key_tank'Unchecked_Access); 871 | 872 | secret_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_box_SECRETKEYBYTES); 873 | secret_key_tank : aliased Thin.IC.char_array := (1 .. secret_key_size => Thin.IC.nul); 874 | secret_pointer : Thin.ICS.chars_ptr := 875 | Thin.ICS.To_Chars_Ptr (secret_key_tank'Unchecked_Access); 876 | seed_tank : aliased Thin.IC.char_array := convert (seed); 877 | seed_pointer : Thin.ICS.chars_ptr := 878 | Thin.ICS.To_Chars_Ptr (seed_tank'Unchecked_Access); 879 | begin 880 | res := Thin.crypto_box_seed_keypair (pk => public_pointer, 881 | sk => secret_pointer, 882 | seed => seed_pointer); 883 | box_key_public := convert (public_key_tank); 884 | box_key_secret := convert (secret_key_tank); 885 | end Generate_Box_Keys; 886 | 887 | 888 | --------------------------- 889 | -- Generate_Shared_Key -- 890 | --------------------------- 891 | function Generate_Shared_Key (recipient_public_key : Public_Box_Key; 892 | sender_secret_key : Secret_Box_Key) return Box_Shared_Key 893 | is 894 | res : Thin.IC.int; 895 | public_key_tank : aliased Thin.IC.char_array := convert (recipient_public_key); 896 | public_pointer : Thin.ICS.chars_ptr := 897 | Thin.ICS.To_Chars_Ptr (public_key_tank'Unchecked_Access); 898 | 899 | secret_key_tank : aliased Thin.IC.char_array := convert (sender_secret_key); 900 | secret_pointer : Thin.ICS.chars_ptr := 901 | Thin.ICS.To_Chars_Ptr (secret_key_tank'Unchecked_Access); 902 | shared_key_size : Thin.IC.size_t := Thin.IC.size_t (Thin.crypto_box_BEFORENMBYTES); 903 | shared_key_tank : aliased Thin.IC.char_array := (1 .. shared_key_size => Thin.IC.nul); 904 | shared_pointer : Thin.ICS.chars_ptr := 905 | Thin.ICS.To_Chars_Ptr (shared_key_tank'Unchecked_Access); 906 | begin 907 | res := Thin.crypto_box_beforenm (k => shared_pointer, 908 | pk => public_pointer, 909 | sk => secret_pointer); 910 | return convert (shared_key_tank); 911 | end Generate_Shared_Key; 912 | 913 | 914 | -------------------------- 915 | -- Encrypt_Message #1 -- 916 | -------------------------- 917 | function Encrypt_Message (plain_text_message : String; 918 | shared_key : Box_Shared_Key; 919 | unique_nonce : Box_Nonce) return Encrypted_Data 920 | is 921 | use type Thin.IC.size_t; 922 | res : Thin.IC.int; 923 | message_tank : aliased Thin.IC.char_array := convert (plain_text_message); 924 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 925 | message_pointer : Thin.ICS.chars_ptr := 926 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 927 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 928 | nonce_pointer : Thin.ICS.chars_ptr := 929 | Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 930 | skey_tank : aliased Thin.IC.char_array := convert (shared_key); 931 | skey_pointer : Thin.ICS.chars_ptr := 932 | Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 933 | product_size : Thin.IC.size_t := Thin.IC.size_t (Cipher_Length (plain_text_message)); 934 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 935 | product_pointer : Thin.ICS.chars_ptr := 936 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 937 | begin 938 | res := Thin.crypto_box_easy_afternm (c => product_pointer, 939 | m => message_pointer, 940 | mlen => message_size, 941 | n => nonce_pointer, 942 | k => skey_pointer); 943 | return convert (product_tank); 944 | end Encrypt_Message; 945 | 946 | 947 | -------------------------- 948 | -- Encrypt_Message #2 -- 949 | -------------------------- 950 | function Encrypt_Message (plain_text_message : String; 951 | recipient_public_key : Public_Box_Key; 952 | sender_secret_key : Secret_Box_Key; 953 | unique_nonce : Box_Nonce) return Encrypted_Data 954 | is 955 | use type Thin.IC.size_t; 956 | res : Thin.IC.int; 957 | message_tank : aliased Thin.IC.char_array := convert (plain_text_message); 958 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 959 | message_pointer : Thin.ICS.chars_ptr := 960 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 961 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 962 | nonce_pointer : Thin.ICS.chars_ptr := 963 | Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 964 | pkey_tank : aliased Thin.IC.char_array := convert (recipient_public_key); 965 | pkey_pointer : Thin.ICS.chars_ptr := 966 | Thin.ICS.To_Chars_Ptr (pkey_tank'Unchecked_Access); 967 | skey_tank : aliased Thin.IC.char_array := convert (sender_secret_key); 968 | skey_pointer : Thin.ICS.chars_ptr := 969 | Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 970 | product_size : Thin.IC.size_t := Thin.IC.size_t (Cipher_Length (plain_text_message)); 971 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 972 | product_pointer : Thin.ICS.chars_ptr := 973 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 974 | 975 | begin 976 | res := Thin.crypto_box_easy (c => product_pointer, 977 | m => message_pointer, 978 | mlen => message_size, 979 | n => nonce_pointer, 980 | pk => pkey_pointer, 981 | sk => skey_pointer); 982 | return convert (product_tank); 983 | end Encrypt_Message; 984 | 985 | 986 | -------------------------- 987 | -- Decrypt_Message #1 -- 988 | -------------------------- 989 | function Decrypt_Message (ciphertext : Encrypted_Data; 990 | shared_key : Box_Shared_Key; 991 | unique_nonce : Box_Nonce) return String 992 | is 993 | use type Thin.IC.size_t; 994 | res : Thin.IC.int; 995 | cipher_tank : aliased Thin.IC.char_array := convert (ciphertext); 996 | cipher_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (cipher_tank'Length); 997 | cipher_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (cipher_tank'Unchecked_Access); 998 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 999 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1000 | skey_tank : aliased Thin.IC.char_array := convert (shared_key); 1001 | skey_pointer : Thin.ICS.chars_ptr := 1002 | Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1003 | product_size : Thin.IC.size_t := Thin.IC.size_t (Clear_Text_Length (ciphertext)); 1004 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1005 | product_pointer : Thin.ICS.chars_ptr := 1006 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1007 | begin 1008 | res := Thin.crypto_box_open_easy_afternm (m => product_pointer, 1009 | c => cipher_pointer, 1010 | clen => cipher_size, 1011 | n => nonce_pointer, 1012 | k => skey_pointer); 1013 | return convert (product_tank); 1014 | end Decrypt_Message; 1015 | 1016 | 1017 | -------------------------- 1018 | -- Decrypt_Message #2 -- 1019 | -------------------------- 1020 | function Decrypt_Message (ciphertext : Encrypted_Data; 1021 | sender_public_key : Public_Box_Key; 1022 | recipient_secret_key : Secret_Box_Key; 1023 | unique_nonce : Box_Nonce) return String 1024 | is 1025 | use type Thin.IC.size_t; 1026 | res : Thin.IC.int; 1027 | cipher_tank : aliased Thin.IC.char_array := convert (ciphertext); 1028 | cipher_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (cipher_tank'Length); 1029 | cipher_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (cipher_tank'Unchecked_Access); 1030 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 1031 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1032 | pkey_tank : aliased Thin.IC.char_array := convert (sender_public_key); 1033 | pkey_pointer : Thin.ICS.chars_ptr := 1034 | Thin.ICS.To_Chars_Ptr (pkey_tank'Unchecked_Access); 1035 | skey_tank : aliased Thin.IC.char_array := convert (recipient_secret_key); 1036 | skey_pointer : Thin.ICS.chars_ptr := 1037 | Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1038 | product_size : Thin.IC.size_t := Thin.IC.size_t (Clear_Text_Length (ciphertext)); 1039 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1040 | product_pointer : Thin.ICS.chars_ptr := 1041 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1042 | begin 1043 | res := Thin.crypto_box_open_easy (m => product_pointer, 1044 | c => cipher_pointer, 1045 | clen => cipher_size, 1046 | n => nonce_pointer, 1047 | pk => pkey_pointer, 1048 | sk => skey_pointer); 1049 | return convert (product_tank); 1050 | end Decrypt_Message; 1051 | 1052 | 1053 | --------------------- 1054 | -- Cipher_Length -- 1055 | --------------------- 1056 | function Cipher_Length (plain_text_message : String) return Positive is 1057 | begin 1058 | return plain_text_message'Length + Positive (Thin.crypto_box_MACBYTES); 1059 | end Cipher_Length; 1060 | 1061 | 1062 | ------------------------- 1063 | -- Clear_Text_Length -- 1064 | ------------------------- 1065 | function Clear_Text_Length (ciphertext : Encrypted_Data) return Positive is 1066 | begin 1067 | return ciphertext'Length - Positive (Thin.crypto_box_MACBYTES); 1068 | end Clear_Text_Length; 1069 | 1070 | 1071 | ---------------------------- 1072 | -- Sealed_Cipher_Length -- 1073 | ---------------------------- 1074 | function Sealed_Cipher_Length (plain_text : String) return Positive is 1075 | begin 1076 | return plain_text'Length + Positive (Thin.crypto_box_SEALBYTES); 1077 | end Sealed_Cipher_Length; 1078 | 1079 | 1080 | -------------------------------- 1081 | -- Sealed_Clear_Text_Length -- 1082 | -------------------------------- 1083 | function Sealed_Clear_Text_Length (ciphertext : Sealed_Data) return Positive is 1084 | begin 1085 | return ciphertext'Length - Positive (Thin.crypto_box_SEALBYTES); 1086 | end Sealed_Clear_Text_Length; 1087 | 1088 | 1089 | -------------------- 1090 | -- Seal_Message -- 1091 | -------------------- 1092 | function Seal_Message (plain_text_message : String; 1093 | recipient_public_key : Public_Box_Key) return Sealed_Data 1094 | is 1095 | use type Thin.IC.size_t; 1096 | res : Thin.IC.int; 1097 | message_tank : aliased Thin.IC.char_array := convert (plain_text_message); 1098 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 1099 | message_pointer : Thin.ICS.chars_ptr := 1100 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 1101 | pkey_tank : aliased Thin.IC.char_array := convert (recipient_public_key); 1102 | pkey_pointer : Thin.ICS.chars_ptr := 1103 | Thin.ICS.To_Chars_Ptr (pkey_tank'Unchecked_Access); 1104 | product_size : Thin.IC.size_t := 1105 | Thin.IC.size_t (Sealed_Cipher_Length (plain_text_message)); 1106 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1107 | product_pointer : Thin.ICS.chars_ptr := 1108 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1109 | begin 1110 | res := Thin.crypto_box_seal (c => product_pointer, 1111 | m => message_pointer, 1112 | mlen => message_size, 1113 | pk => pkey_pointer); 1114 | return convert (product_tank); 1115 | end Seal_Message; 1116 | 1117 | 1118 | ---------------------- 1119 | -- Unseal_Message -- 1120 | ---------------------- 1121 | function Unseal_Message (ciphertext : Sealed_Data; 1122 | recipient_public_key : Public_Box_Key; 1123 | recipient_secret_key : Secret_Box_Key) return String 1124 | is 1125 | use type Thin.IC.int; 1126 | use type Thin.IC.size_t; 1127 | res : Thin.IC.int; 1128 | cipher_tank : aliased Thin.IC.char_array := convert (ciphertext); 1129 | cipher_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (cipher_tank'Length); 1130 | cipher_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (cipher_tank'Unchecked_Access); 1131 | pkey_tank : aliased Thin.IC.char_array := convert (recipient_public_key); 1132 | pkey_pointer : Thin.ICS.chars_ptr := 1133 | Thin.ICS.To_Chars_Ptr (pkey_tank'Unchecked_Access); 1134 | skey_tank : aliased Thin.IC.char_array := convert (recipient_secret_key); 1135 | skey_pointer : Thin.ICS.chars_ptr := 1136 | Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1137 | product_size : Thin.IC.size_t := 1138 | Thin.IC.size_t (Sealed_Clear_Text_Length (ciphertext)); 1139 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1140 | product_pointer : Thin.ICS.chars_ptr := 1141 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1142 | begin 1143 | res := Thin.crypto_box_seal_open (m => product_pointer, 1144 | c => cipher_pointer, 1145 | clen => cipher_size, 1146 | pk => pkey_pointer, 1147 | sk => skey_pointer); 1148 | if res = 0 then 1149 | return convert (product_tank); 1150 | end if; 1151 | raise Sodium_Wrong_Recipient; 1152 | end Unseal_Message; 1153 | 1154 | 1155 | ------------------------------- 1156 | -- Symmetric_Cipher_Length -- 1157 | ------------------------------- 1158 | function Symmetric_Cipher_Length (plain_text : String) return Positive is 1159 | begin 1160 | return plain_text'Length + Positive (Thin.crypto_secretbox_MACBYTES); 1161 | end Symmetric_Cipher_Length; 1162 | 1163 | 1164 | ----------------------------------- 1165 | -- Symmetric_Clear_Text_Length -- 1166 | ----------------------------------- 1167 | function Symmetric_Clear_Text_Length (ciphertext : Encrypted_Data) return Positive is 1168 | begin 1169 | return ciphertext'Length - Positive (Thin.crypto_secretbox_MACBYTES); 1170 | end Symmetric_Clear_Text_Length; 1171 | 1172 | 1173 | ------------------------- 1174 | -- Symmetric_Encrypt -- 1175 | ------------------------- 1176 | function Symmetric_Encrypt (clear_text : String; 1177 | secret_key : Symmetric_Key; 1178 | unique_nonce : Symmetric_Nonce) return Encrypted_Data 1179 | is 1180 | res : Thin.IC.int; 1181 | message_tank : aliased Thin.IC.char_array := convert (clear_text); 1182 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 1183 | message_pointer : Thin.ICS.chars_ptr := 1184 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 1185 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 1186 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1187 | skey_tank : aliased Thin.IC.char_array := convert (secret_key); 1188 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1189 | product_size : Thin.IC.size_t := 1190 | Thin.IC.size_t (Symmetric_Cipher_Length (clear_text)); 1191 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1192 | product_pointer : Thin.ICS.chars_ptr := 1193 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1194 | begin 1195 | res := Thin.crypto_secretbox_easy (c => product_pointer, 1196 | m => message_pointer, 1197 | mlen => message_size, 1198 | n => nonce_pointer, 1199 | k => skey_pointer); 1200 | return convert (product_tank); 1201 | end Symmetric_Encrypt; 1202 | 1203 | 1204 | ------------------------- 1205 | -- Symmetric_Decrypt -- 1206 | ------------------------- 1207 | function Symmetric_Decrypt (ciphertext : Encrypted_Data; 1208 | secret_key : Symmetric_Key; 1209 | unique_nonce : Symmetric_Nonce) return String 1210 | is 1211 | use type Thin.IC.int; 1212 | res : Thin.IC.int; 1213 | cipher_tank : aliased Thin.IC.char_array := convert (ciphertext); 1214 | cipher_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (cipher_tank'Length); 1215 | cipher_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (cipher_tank'Unchecked_Access); 1216 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 1217 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1218 | skey_tank : aliased Thin.IC.char_array := convert (secret_key); 1219 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1220 | product_size : Thin.IC.size_t := 1221 | Thin.IC.size_t (Symmetric_Clear_Text_Length (ciphertext)); 1222 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1223 | product_pointer : Thin.ICS.chars_ptr := 1224 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1225 | begin 1226 | res := Thin.crypto_secretbox_open_easy (m => product_pointer, 1227 | c => cipher_pointer, 1228 | clen => cipher_size, 1229 | n => nonce_pointer, 1230 | k => skey_pointer); 1231 | if res = 0 then 1232 | return convert (product_tank); 1233 | end if; 1234 | raise Sodium_Symmetric_Failed 1235 | with "Message forged or incorrect secret key"; 1236 | end Symmetric_Decrypt; 1237 | 1238 | 1239 | ----------------------------------- 1240 | -- Generate_Authentication_Tag -- 1241 | ----------------------------------- 1242 | function Generate_Authentication_Tag (message : String; authentication_key : Auth_Key) 1243 | return Auth_Tag 1244 | is 1245 | res : Thin.IC.int; 1246 | message_tank : aliased Thin.IC.char_array := convert (message); 1247 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 1248 | message_pointer : Thin.ICS.chars_ptr := 1249 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 1250 | skey_tank : aliased Thin.IC.char_array := convert (authentication_key); 1251 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1252 | product_tank : aliased Thin.IC.char_array := (1 .. Auth_Tag'Length => Thin.IC.nul); 1253 | product_pointer : Thin.ICS.chars_ptr := 1254 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1255 | begin 1256 | res := Thin.crypto_auth (tag => product_pointer, 1257 | text_in => message_pointer, 1258 | inlen => message_size, 1259 | k => skey_pointer); 1260 | return convert (product_tank); 1261 | end Generate_Authentication_Tag; 1262 | 1263 | 1264 | ------------------------- 1265 | -- Authentic_Message -- 1266 | ------------------------- 1267 | function Authentic_Message (message : String; authentication_tag : Auth_Tag; 1268 | authentication_key : Auth_Key) return Boolean 1269 | is 1270 | use type Thin.IC.int; 1271 | res : Thin.IC.int; 1272 | message_tank : aliased Thin.IC.char_array := convert (message); 1273 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 1274 | message_pointer : Thin.ICS.chars_ptr := 1275 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 1276 | skey_tank : aliased Thin.IC.char_array := convert (authentication_key); 1277 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1278 | tag_tank : aliased Thin.IC.char_array := convert (authentication_tag); 1279 | tag_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (tag_tank'Unchecked_Access); 1280 | begin 1281 | res := Thin.crypto_auth_verify (tag => tag_pointer, 1282 | text_in => message_pointer, 1283 | inlen => message_size, 1284 | k => skey_pointer); 1285 | return (res = 0); 1286 | end Authentic_Message; 1287 | 1288 | 1289 | ----------------------- 1290 | -- increment_nonce -- 1291 | ----------------------- 1292 | procedure increment_nonce (nonce : in out String) 1293 | is 1294 | arrow : Natural := nonce'Last; 1295 | value : Natural; 1296 | FF : constant Character := Character'Val (16#FF#); 1297 | ultimate : constant String (nonce'Range) := (others => FF); 1298 | begin 1299 | if nonce = ultimate then 1300 | for z in nonce'Range loop 1301 | nonce (z) := ASCII.NUL; 1302 | end loop; 1303 | return; 1304 | end if; 1305 | loop 1306 | if nonce (arrow) = FF then 1307 | nonce (arrow) := ASCII.NUL; 1308 | arrow := arrow - 1; 1309 | else 1310 | value := Character'Pos (nonce (arrow)); 1311 | nonce (arrow) := Character'Val (value + 1); 1312 | exit; 1313 | end if; 1314 | end loop; 1315 | end increment_nonce; 1316 | 1317 | 1318 | -------------------------- 1319 | -- AEAD_Cipher_Length -- 1320 | -------------------------- 1321 | function AEAD_Cipher_Length (plain_text : String; 1322 | construction : AEAD_Construction := ChaCha20_Poly1305) 1323 | return Positive is 1324 | begin 1325 | case construction is 1326 | when ChaCha20_Poly1305 => 1327 | return plain_text'Length + Positive (Thin.crypto_aead_chacha20poly1305_ABYTES); 1328 | when ChaCha20_Poly1305_IETF => 1329 | return plain_text'Length + Positive (Thin.crypto_aead_chacha20poly1305_ietf_ABYTES); 1330 | when AES256_GCM => 1331 | return plain_text'Length + Positive (Thin.crypto_aead_aes256gcm_ABYTES); 1332 | end case; 1333 | end AEAD_Cipher_Length; 1334 | 1335 | 1336 | ------------------------------ 1337 | -- AEAD_Clear_Text_Length -- 1338 | ------------------------------ 1339 | function AEAD_Clear_Text_Length (ciphertext : Encrypted_Data; 1340 | construction : AEAD_Construction := ChaCha20_Poly1305) 1341 | return Positive is 1342 | begin 1343 | case construction is 1344 | when ChaCha20_Poly1305 => 1345 | return ciphertext'Length - Positive (Thin.crypto_aead_chacha20poly1305_ABYTES); 1346 | when ChaCha20_Poly1305_IETF => 1347 | return ciphertext'Length - Positive (Thin.crypto_aead_chacha20poly1305_ietf_ABYTES); 1348 | when AES256_GCM => 1349 | return ciphertext'Length - Positive (Thin.crypto_aead_aes256gcm_ABYTES); 1350 | end case; 1351 | end AEAD_Clear_Text_Length; 1352 | 1353 | 1354 | -------------------- 1355 | -- AEAD_Encrypt -- 1356 | -------------------- 1357 | function AEAD_Encrypt (data_to_encrypt : String; 1358 | additional_data : String; 1359 | secret_key : AEAD_Key; 1360 | unique_nonce : AEAD_Nonce; 1361 | construction : AEAD_Construction := ChaCha20_Poly1305) 1362 | return Encrypted_Data 1363 | is 1364 | res : Thin.IC.int; 1365 | message_tank : aliased Thin.IC.char_array := convert (data_to_encrypt); 1366 | message_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (message_tank'Length); 1367 | message_pointer : Thin.ICS.chars_ptr := 1368 | Thin.ICS.To_Chars_Ptr (message_tank'Unchecked_Access); 1369 | metadata_tank : aliased Thin.IC.char_array := convert (additional_data); 1370 | metadata_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (metadata_tank'Length); 1371 | metadata_pointer : Thin.ICS.chars_ptr := 1372 | Thin.ICS.To_Chars_Ptr (metadata_tank'Unchecked_Access); 1373 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 1374 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1375 | skey_tank : aliased Thin.IC.char_array := convert (secret_key); 1376 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1377 | product_size : Thin.IC.size_t := 1378 | Thin.IC.size_t (AEAD_Cipher_Length (data_to_encrypt, construction)); 1379 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1380 | product_pointer : Thin.ICS.chars_ptr := 1381 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1382 | product_realsize : aliased Thin.NaCl_uint64; 1383 | begin 1384 | case construction is 1385 | when ChaCha20_Poly1305 => 1386 | res := Thin.crypto_aead_chacha20poly1305_encrypt 1387 | (c => product_pointer, 1388 | clen_p => product_realsize'Unchecked_Access, 1389 | m => message_pointer, 1390 | mlen => message_size, 1391 | ad => metadata_pointer, 1392 | adlen => metadata_size, 1393 | nsec => Thin.ICS.Null_Ptr, 1394 | npub => nonce_pointer, 1395 | k => skey_pointer); 1396 | when ChaCha20_Poly1305_IETF => 1397 | res := Thin.crypto_aead_chacha20poly1305_ietf_encrypt 1398 | (c => product_pointer, 1399 | clen_p => product_realsize'Unchecked_Access, 1400 | m => message_pointer, 1401 | mlen => message_size, 1402 | ad => metadata_pointer, 1403 | adlen => metadata_size, 1404 | nsec => Thin.ICS.Null_Ptr, 1405 | npub => nonce_pointer, 1406 | k => skey_pointer); 1407 | when AES256_GCM => 1408 | res := Thin.crypto_aead_aes256gcm_encrypt 1409 | (c => product_pointer, 1410 | clen_p => product_realsize'Unchecked_Access, 1411 | m => message_pointer, 1412 | mlen => message_size, 1413 | ad => metadata_pointer, 1414 | adlen => metadata_size, 1415 | nsec => Thin.ICS.Null_Ptr, 1416 | npub => nonce_pointer, 1417 | k => skey_pointer); 1418 | end case; 1419 | declare 1420 | result : constant String := convert (product_tank); 1421 | begin 1422 | return result (1 .. Natural (product_realsize)); 1423 | end; 1424 | end AEAD_Encrypt; 1425 | 1426 | 1427 | -------------------- 1428 | -- AEAD_Decrypt -- 1429 | -------------------- 1430 | function AEAD_Decrypt (ciphertext : Encrypted_Data; 1431 | additional_data : String; 1432 | secret_key : AEAD_Key; 1433 | unique_nonce : AEAD_Nonce; 1434 | construction : AEAD_Construction := ChaCha20_Poly1305) return String 1435 | is 1436 | use type Thin.IC.int; 1437 | res : Thin.IC.int; 1438 | cipher_tank : aliased Thin.IC.char_array := convert (ciphertext); 1439 | cipher_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (cipher_tank'Length); 1440 | cipher_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (cipher_tank'Unchecked_Access); 1441 | 1442 | metadata_tank : aliased Thin.IC.char_array := convert (additional_data); 1443 | metadata_size : Thin.NaCl_uint64 := Thin.NaCl_uint64 (metadata_tank'Length); 1444 | metadata_pointer : Thin.ICS.chars_ptr := 1445 | Thin.ICS.To_Chars_Ptr (metadata_tank'Unchecked_Access); 1446 | nonce_tank : aliased Thin.IC.char_array := convert (unique_nonce); 1447 | nonce_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (nonce_tank'Unchecked_Access); 1448 | skey_tank : aliased Thin.IC.char_array := convert (secret_key); 1449 | skey_pointer : Thin.ICS.chars_ptr := Thin.ICS.To_Chars_Ptr (skey_tank'Unchecked_Access); 1450 | product_size : Thin.IC.size_t := 1451 | Thin.IC.size_t (AEAD_Clear_Text_Length (ciphertext, construction)); 1452 | product_tank : aliased Thin.IC.char_array := (1 .. product_size => Thin.IC.nul); 1453 | product_pointer : Thin.ICS.chars_ptr := 1454 | Thin.ICS.To_Chars_Ptr (product_tank'Unchecked_Access); 1455 | product_realsize : aliased Thin.NaCl_uint64; 1456 | begin 1457 | case construction is 1458 | when ChaCha20_Poly1305 => 1459 | res := Thin.crypto_aead_chacha20poly1305_decrypt 1460 | (m => product_pointer, 1461 | mlen_p => product_realsize'Unchecked_Access, 1462 | nsec => Thin.ICS.Null_Ptr, 1463 | c => cipher_pointer, 1464 | clen => cipher_size, 1465 | ad => metadata_pointer, 1466 | adlen => metadata_size, 1467 | npub => nonce_pointer, 1468 | k => skey_pointer); 1469 | when ChaCha20_Poly1305_IETF => 1470 | res := Thin.crypto_aead_chacha20poly1305_ietf_decrypt 1471 | (m => product_pointer, 1472 | mlen_p => product_realsize'Unchecked_Access, 1473 | nsec => Thin.ICS.Null_Ptr, 1474 | c => cipher_pointer, 1475 | clen => cipher_size, 1476 | ad => metadata_pointer, 1477 | adlen => metadata_size, 1478 | npub => nonce_pointer, 1479 | k => skey_pointer); 1480 | when AES256_GCM => 1481 | res := Thin.crypto_aead_aes256gcm_decrypt 1482 | (m => product_pointer, 1483 | mlen_p => product_realsize'Unchecked_Access, 1484 | nsec => Thin.ICS.Null_Ptr, 1485 | c => cipher_pointer, 1486 | clen => cipher_size, 1487 | ad => metadata_pointer, 1488 | adlen => metadata_size, 1489 | npub => nonce_pointer, 1490 | k => skey_pointer); 1491 | end case; 1492 | 1493 | if res = 0 then 1494 | declare 1495 | result : constant String := convert (product_tank); 1496 | begin 1497 | return result (1 .. Natural (product_realsize)); 1498 | end; 1499 | end if; 1500 | raise Sodium_AEAD_Failed 1501 | with "Message verification failed"; 1502 | end AEAD_Decrypt; 1503 | 1504 | 1505 | ---------------------------- 1506 | -- AES256_GCM_Available -- 1507 | ---------------------------- 1508 | function AES256_GCM_Available return Boolean 1509 | is 1510 | use type Thin.IC.int; 1511 | res : Thin.IC.int; 1512 | begin 1513 | res := Thin.crypto_aead_aes256gcm_is_available; 1514 | return (res = 1); 1515 | end AES256_GCM_Available; 1516 | 1517 | end Sodium.Functions; 1518 | -------------------------------------------------------------------------------- /Binding_Sodium/sodium-functions.ads: -------------------------------------------------------------------------------- 1 | -- This file is covered by the Internet Software Consortium (ISC) License 2 | -- Reference: ../License.txt 3 | 4 | with Sodium.Thin_Binding; 5 | 6 | package Sodium.Functions is 7 | 8 | package Thin renames Sodium.Thin_Binding; 9 | 10 | ------------------ 11 | -- Data Types -- 12 | ------------------ 13 | 14 | subtype Standard_Hash is String (1 .. Positive (Thin.crypto_generichash_BYTES)); 15 | subtype Hash_Size_Range is Positive range Positive (Thin.crypto_generichash_BYTES_MIN) .. 16 | Positive (Thin.crypto_generichash_BYTES_MAX); 17 | subtype Any_Hash is String; 18 | 19 | subtype Standard_Key is String (1 .. Positive (Thin.crypto_generichash_KEYBYTES)); 20 | subtype Key_Size_Range is Positive range Positive (Thin.crypto_generichash_KEYBYTES_MIN) .. 21 | Positive (Thin.crypto_generichash_KEYBYTES_MAX); 22 | subtype Any_Key is String; 23 | 24 | subtype Short_Hash is String (1 .. Positive (Thin.crypto_shorthash_BYTES)); 25 | subtype Short_Key is String (1 .. Positive (Thin.crypto_shorthash_KEYBYTES)); 26 | 27 | subtype Password_Salt is String (1 .. Positive (Thin.crypto_pwhash_SALTBYTES)); 28 | subtype Passkey_Size_Range is Positive range 16 .. 64; 29 | subtype Any_Password_Key is String; 30 | 31 | subtype Public_Sign_Key is String (1 .. Positive (Thin.crypto_sign_PUBLICKEYBYTES)); 32 | subtype Secret_Sign_Key is String (1 .. Positive (Thin.crypto_sign_SECRETKEYBYTES)); 33 | subtype Sign_Key_Seed is String (1 .. Positive (Thin.crypto_sign_SEEDBYTES)); 34 | subtype Signature is String (1 .. Positive (Thin.crypto_sign_BYTES)); 35 | 36 | subtype Public_Box_Key is String (1 .. Positive (Thin.crypto_box_PUBLICKEYBYTES)); 37 | subtype Secret_Box_Key is String (1 .. Positive (Thin.crypto_box_SECRETKEYBYTES)); 38 | subtype Box_Key_Seed is String (1 .. Positive (Thin.crypto_box_SEEDBYTES)); 39 | subtype Box_Nonce is String (1 .. Positive (Thin.crypto_box_NONCEBYTES)); 40 | subtype Box_Shared_Key is String (1 .. Positive (Thin.crypto_box_BEFORENMBYTES)); 41 | 42 | subtype Symmetric_Key is String (1 .. Positive (Thin.crypto_secretbox_KEYBYTES)); 43 | subtype Symmetric_Nonce is String (1 .. Positive (Thin.crypto_secretbox_NONCEBYTES)); 44 | 45 | subtype Auth_Key is String (1 .. Positive (Thin.crypto_auth_KEYBYTES)); 46 | subtype Auth_Tag is String (1 .. Positive (Thin.crypto_auth_BYTES)); 47 | 48 | subtype Encrypted_Data is String; 49 | subtype Sealed_Data is String; 50 | subtype AEAD_Nonce is String; 51 | subtype AEAD_Key is String; 52 | 53 | type Natural32 is mod 2 ** 32; 54 | 55 | type Data_Criticality is (online_interactive, moderate, highly_sensitive); 56 | type AEAD_Construction is (ChaCha20_Poly1305, ChaCha20_Poly1305_IETF, AES256_GCM); 57 | 58 | type Hash_State is private; 59 | 60 | ---------------------- 61 | -- Initialization -- 62 | ---------------------- 63 | 64 | function initialize_sodium_library return Boolean; 65 | 66 | ---------------------- 67 | -- Hash Functions -- 68 | ---------------------- 69 | 70 | function Keyless_Hash (plain_text : String) return Standard_Hash; 71 | function Keyless_Hash (plain_text : String; 72 | output_size : Hash_Size_Range) return Any_Hash; 73 | 74 | function Keyed_Hash (plain_text : String; key : Standard_Key) return Standard_Hash; 75 | function Keyed_Hash (plain_text : String; 76 | key : Any_Key; 77 | output_size : Hash_Size_Range) return Any_Hash; 78 | 79 | function Multipart_Hash_Start (output_size : Hash_Size_Range) return Hash_State; 80 | function Multipart_Keyed_Hash_Start (key : Any_Key; 81 | output_size : Hash_Size_Range) return Hash_State; 82 | procedure Multipart_Append (plain_text : String; state : in out Hash_State); 83 | function Multipart_Hash_Complete (state : in out Hash_State) return Any_Hash; 84 | 85 | function Short_Input_Hash (short_data : String; key : Short_Key) return Short_Hash; 86 | 87 | --------------------- 88 | -- Random Things -- 89 | --------------------- 90 | 91 | function Random_Word return Natural32; 92 | function Random_Limited_Word (upper_bound : Natural32) return Natural32; 93 | 94 | function Random_Salt return Password_Salt; 95 | function Random_Nonce return Box_Nonce; 96 | function Random_Short_Key return Short_Key; 97 | function Random_Standard_Hash_Key return Standard_Key; 98 | function Random_Sign_Key_seed return Sign_Key_Seed; 99 | function Random_Box_Key_seed return Box_Key_Seed; 100 | function Random_Symmetric_Key return Symmetric_Key; 101 | function Random_Symmetric_Nonce return Symmetric_Nonce; 102 | function Random_Auth_Key return Auth_Key; 103 | 104 | function Random_Hash_Key (Key_Size : Key_Size_Range) 105 | return Any_Key; 106 | function Random_AEAD_Key (construction : AEAD_Construction := ChaCha20_Poly1305) 107 | return AEAD_Key; 108 | function Random_AEAD_Nonce (construction : AEAD_Construction := ChaCha20_Poly1305) 109 | return AEAD_Nonce; 110 | 111 | -------------------------- 112 | -- Password Functions -- 113 | -------------------------- 114 | 115 | function Derive_Password_Key 116 | (criticality : Data_Criticality := online_interactive; 117 | passkey_size : Passkey_Size_Range := Positive (Thin.crypto_box_SEEDBYTES); 118 | password : String; 119 | salt : Password_Salt) return Any_Password_Key; 120 | 121 | function Generate_Password_Hash 122 | (criticality : Data_Criticality := online_interactive; 123 | password : String) return Any_Hash; 124 | 125 | function Password_Hash_Matches (hash : Any_Hash; password : String) return Boolean; 126 | 127 | --------------- 128 | -- Helpers -- 129 | --------------- 130 | 131 | function As_Hexidecimal (binary : String) return String; 132 | function As_Binary (hexidecimal : String; ignore : String := "") return String; 133 | procedure increment_nonce (nonce : in out String); 134 | 135 | ----------------------------- 136 | -- Public Key Signatures -- 137 | ----------------------------- 138 | 139 | procedure Generate_Sign_Keys (sign_key_public : out Public_Sign_Key; 140 | sign_key_secret : out Secret_Sign_Key); 141 | 142 | procedure Generate_Sign_Keys (sign_key_public : out Public_Sign_Key; 143 | sign_key_secret : out Secret_Sign_Key; 144 | seed : Sign_Key_Seed); 145 | 146 | function Obtain_Signature (plain_text_message : String; 147 | sign_key_secret : Secret_Sign_Key) return Signature; 148 | 149 | function Signature_Matches (plain_text_message : String; 150 | sender_signature : Signature; 151 | sender_sign_key : Public_Sign_Key) return Boolean; 152 | 153 | ----------------------------- 154 | -- Public Key Encryption -- 155 | ----------------------------- 156 | 157 | procedure Generate_Box_Keys (box_key_public : out Public_Box_Key; 158 | box_key_secret : out Secret_Box_Key); 159 | 160 | procedure Generate_Box_Keys (box_key_public : out Public_Box_Key; 161 | box_key_secret : out Secret_Box_Key; 162 | seed : Box_Key_Seed); 163 | 164 | function Generate_Shared_Key (recipient_public_key : Public_Box_Key; 165 | sender_secret_key : Secret_Box_Key) return Box_Shared_Key; 166 | 167 | function Encrypt_Message (plain_text_message : String; 168 | recipient_public_key : Public_Box_Key; 169 | sender_secret_key : Secret_Box_Key; 170 | unique_nonce : Box_Nonce) return Encrypted_Data; 171 | 172 | function Encrypt_Message (plain_text_message : String; 173 | shared_key : Box_Shared_Key; 174 | unique_nonce : Box_Nonce) return Encrypted_Data; 175 | 176 | function Decrypt_Message (ciphertext : Encrypted_Data; 177 | sender_public_key : Public_Box_Key; 178 | recipient_secret_key : Secret_Box_Key; 179 | unique_nonce : Box_Nonce) return String; 180 | 181 | function Decrypt_Message (ciphertext : Encrypted_Data; 182 | shared_key : Box_Shared_Key; 183 | unique_nonce : Box_Nonce) return String; 184 | 185 | function Cipher_Length (plain_text_message : String) return Positive; 186 | function Clear_Text_Length (ciphertext : Encrypted_Data) return Positive; 187 | 188 | ---------------------------------- 189 | -- Anonymous Private Messages -- 190 | ---------------------------------- 191 | 192 | function Seal_Message (plain_text_message : String; 193 | recipient_public_key : Public_Box_Key) return Sealed_Data; 194 | 195 | function Unseal_Message (ciphertext : Sealed_Data; 196 | recipient_public_key : Public_Box_Key; 197 | recipient_secret_key : Secret_Box_Key) return String; 198 | 199 | function Sealed_Cipher_Length (plain_text : String) return Positive; 200 | function Sealed_Clear_Text_Length (ciphertext : Sealed_Data) return Positive; 201 | 202 | ---------------------------- 203 | -- Symmetric Encryption -- 204 | ---------------------------- 205 | 206 | function Symmetric_Encrypt (clear_text : String; 207 | secret_key : Symmetric_Key; 208 | unique_nonce : Symmetric_Nonce) return Encrypted_Data; 209 | 210 | function Symmetric_Decrypt (ciphertext : Encrypted_Data; 211 | secret_key : Symmetric_Key; 212 | unique_nonce : Symmetric_Nonce) return String; 213 | 214 | function Symmetric_Cipher_Length (plain_text : String) return Positive; 215 | function Symmetric_Clear_Text_Length (ciphertext : Encrypted_Data) return Positive; 216 | 217 | ------------------------------ 218 | -- Message Authentication -- 219 | ------------------------------ 220 | 221 | function Generate_Authentication_Tag (message : String; authentication_key : Auth_Key) 222 | return Auth_Tag; 223 | 224 | function Authentic_Message (message : String; authentication_tag : Auth_Tag; 225 | authentication_key : Auth_Key) return Boolean; 226 | 227 | ----------------------------------------------------- 228 | -- Authenticated Encryption with Additional Data -- 229 | ----------------------------------------------------- 230 | 231 | function AEAD_Encrypt (data_to_encrypt : String; 232 | additional_data : String; 233 | secret_key : AEAD_Key; 234 | unique_nonce : AEAD_Nonce; 235 | construction : AEAD_Construction := ChaCha20_Poly1305) 236 | return Encrypted_Data; 237 | 238 | function AEAD_Decrypt (ciphertext : Encrypted_Data; 239 | additional_data : String; 240 | secret_key : AEAD_Key; 241 | unique_nonce : AEAD_Nonce; 242 | construction : AEAD_Construction := ChaCha20_Poly1305) 243 | return String; 244 | 245 | function AEAD_Cipher_Length (plain_text : String; 246 | construction : AEAD_Construction := ChaCha20_Poly1305) 247 | return Positive; 248 | 249 | function AEAD_Clear_Text_Length (ciphertext : Encrypted_Data; 250 | construction : AEAD_Construction := ChaCha20_Poly1305) 251 | return Positive; 252 | 253 | function AES256_GCM_Available return Boolean; 254 | 255 | ------------------ 256 | -- Exceptions -- 257 | ------------------ 258 | 259 | Sodium_Out_Of_Memory : exception; 260 | Sodium_Already_Initialized : exception; 261 | Sodium_Invalid_Input : exception; 262 | Sodium_Wrong_Recipient : exception; 263 | Sodium_Symmetric_Failed : exception; 264 | Sodium_AEAD_Failed : exception; 265 | 266 | private 267 | 268 | type Hash_State is record 269 | hash_length : Thin.IC.size_t; 270 | state : aliased Thin.crypto_generichash_state; 271 | end record; 272 | 273 | function convert (data : Thin.IC.char_array) return String; 274 | function convert (data : String) return Thin.IC.char_array; 275 | 276 | end Sodium.Functions; 277 | -------------------------------------------------------------------------------- /Binding_Sodium/sodium-thin_binding.ads: -------------------------------------------------------------------------------- 1 | -- This file is covered by the Internet Software Consortium (ISC) License 2 | -- Reference: ../License.txt 3 | 4 | with System; 5 | with Interfaces.C.Strings; 6 | 7 | package Sodium.Thin_Binding is 8 | 9 | package IC renames Interfaces.C; 10 | package ICS renames Interfaces.C.Strings; 11 | 12 | ------------------ 13 | -- Data Types -- 14 | ------------------ 15 | 16 | type NaCl_uint64 is mod 2 ** 64; 17 | type NaCl_uint32 is mod 2 ** 32; 18 | type NaCl_uint8 is mod 2 ** 8; 19 | 20 | type NaCl_block64 is array (Natural range <>) of NaCl_uint64; 21 | type NaCl_block8 is array (Natural range <>) of NaCl_uint8; 22 | 23 | pragma Pack (NaCl_block64); 24 | pragma Pack (NaCl_block8); 25 | 26 | type crypto_generichash_blake2b_state is record 27 | h : NaCl_block64 (0 .. 7); 28 | t : NaCl_block64 (0 .. 1); 29 | f : NaCl_block64 (0 .. 1); 30 | buf : NaCl_block8 (0 .. 255); 31 | buflen : IC.size_t; 32 | last_node : NaCl_uint8; 33 | end record; 34 | 35 | for crypto_generichash_blake2b_state'Alignment use 64; 36 | pragma Pack (crypto_generichash_blake2b_state); 37 | 38 | subtype crypto_generichash_state is crypto_generichash_blake2b_state; 39 | 40 | type crypto_generichash_state_Access is access all crypto_generichash_state; 41 | pragma Convention (C, crypto_generichash_state_Access); 42 | 43 | type crypto_aead_aes256gcm_state is record 44 | state : NaCl_block8 (0 .. 511); 45 | end record; 46 | for crypto_aead_aes256gcm_state'Alignment use 16; 47 | 48 | type crypto_aead_aes256gcm_state_Access is access all crypto_aead_aes256gcm_state; 49 | pragma Convention (C, crypto_aead_aes256gcm_state_Access); 50 | 51 | type NaCl_uint64_Access is access all NaCl_uint64; 52 | pragma Convention (C, NaCl_uint64_Access); 53 | 54 | ----------------- 55 | -- Constants -- 56 | ----------------- 57 | 58 | crypto_generichash_blake2b_BYTES_MIN : constant NaCl_uint8 := 16; 59 | crypto_generichash_blake2b_BYTES : constant NaCl_uint8 := 32; 60 | crypto_generichash_blake2b_BYTES_MAX : constant NaCl_uint8 := 64; 61 | crypto_generichash_blake2b_KEYBYTES_MIN : constant NaCl_uint8 := 16; 62 | crypto_generichash_blake2b_KEYBYTES : constant NaCl_uint8 := 32; 63 | crypto_generichash_blake2b_KEYBYTES_MAX : constant NaCl_uint8 := 64; 64 | crypto_generichash_blake2b_SALTBYTES : constant NaCl_uint8 := 16; 65 | crypto_generichash_blake2b_PERSONALBYTES : constant NaCl_uint8 := 16; 66 | 67 | crypto_generichash_BYTES_MIN : NaCl_uint8 renames crypto_generichash_blake2b_BYTES_MIN; 68 | crypto_generichash_BYTES : NaCl_uint8 renames crypto_generichash_blake2b_BYTES; 69 | crypto_generichash_BYTES_MAX : NaCl_uint8 renames crypto_generichash_blake2b_BYTES_MAX; 70 | crypto_generichash_KEYBYTES_MIN : NaCl_uint8 renames crypto_generichash_blake2b_KEYBYTES_MIN; 71 | crypto_generichash_KEYBYTES : NaCl_uint8 renames crypto_generichash_blake2b_KEYBYTES; 72 | crypto_generichash_KEYBYTES_MAX : NaCl_uint8 renames crypto_generichash_blake2b_KEYBYTES_MAX; 73 | 74 | crypto_shorthash_siphash24_BYTES : constant NaCl_uint8 := 8; 75 | crypto_shorthash_siphash24_KEYBYTES : constant NaCl_uint8 := 16; 76 | 77 | crypto_shorthash_BYTES : NaCl_uint8 renames crypto_shorthash_siphash24_BYTES; 78 | crypto_shorthash_KEYBYTES : NaCl_uint8 renames crypto_shorthash_siphash24_KEYBYTES; 79 | 80 | crypto_pwhash_argon2i_ALG_ARGON2I13 : constant IC.int := 1; 81 | crypto_pwhash_argon2i_SALTBYTES : constant NaCl_uint8 := 16; 82 | crypto_pwhash_argon2i_STRBYTES : constant NaCl_uint8 := 128; 83 | crypto_pwhash_argon2i_STRPREFIX : constant String := "$argon2i$"; 84 | crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE : constant NaCl_uint64 := 4; 85 | crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE : constant IC.size_t := 33554432; 86 | crypto_pwhash_argon2i_OPSLIMIT_MODERATE : constant NaCl_uint64 := 6; 87 | crypto_pwhash_argon2i_MEMLIMIT_MODERATE : constant IC.size_t := 134217728; 88 | crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE : constant NaCl_uint64 := 8; 89 | crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE : constant IC.size_t := 536870912; 90 | 91 | crypto_pwhash_ALG_DEFAULT : IC.int renames crypto_pwhash_argon2i_ALG_ARGON2I13; 92 | crypto_pwhash_SALTBYTES : NaCl_uint8 renames crypto_pwhash_argon2i_SALTBYTES; 93 | crypto_pwhash_STRBYTES : NaCl_uint8 renames crypto_pwhash_argon2i_STRBYTES; 94 | crypto_pwhash_STRPREFIX : String renames crypto_pwhash_argon2i_STRPREFIX; 95 | crypto_pwhash_OPSLIMIT_MODERATE : NaCl_uint64 renames crypto_pwhash_argon2i_OPSLIMIT_MODERATE; 96 | crypto_pwhash_MEMLIMIT_MODERATE : IC.size_t renames crypto_pwhash_argon2i_MEMLIMIT_MODERATE; 97 | crypto_pwhash_OPSLIMIT_SENSITIVE : NaCl_uint64 renames crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE; 98 | crypto_pwhash_MEMLIMIT_SENSITIVE : IC.size_t renames crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE; 99 | crypto_pwhash_OPSLIMIT_INTERACTIVE : NaCl_uint64 100 | renames crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; 101 | crypto_pwhash_MEMLIMIT_INTERACTIVE : IC.size_t 102 | renames crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; 103 | 104 | crypto_box_curve25519xsalsa20poly1305_SEEDBYTES : constant NaCl_uint8 := 32; 105 | crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES : constant NaCl_uint8 := 32; 106 | crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES : constant NaCl_uint8 := 32; 107 | crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES : constant NaCl_uint8 := 32; 108 | crypto_box_curve25519xsalsa20poly1305_NONCEBYTES : constant NaCl_uint8 := 24; 109 | crypto_box_curve25519xsalsa20poly1305_MACBYTES : constant NaCl_uint8 := 16; 110 | crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES : constant NaCl_uint8 := 16; 111 | crypto_box_curve25519xsalsa20poly1305_ZEROBYTES : constant NaCl_uint8 := 112 | crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + 113 | crypto_box_curve25519xsalsa20poly1305_MACBYTES; 114 | 115 | crypto_box_SEEDBYTES : NaCl_uint8 renames crypto_box_curve25519xsalsa20poly1305_SEEDBYTES; 116 | crypto_box_NONCEBYTES : NaCl_uint8 renames crypto_box_curve25519xsalsa20poly1305_NONCEBYTES; 117 | crypto_box_MACBYTES : NaCl_uint8 renames crypto_box_curve25519xsalsa20poly1305_MACBYTES; 118 | crypto_box_ZEROBYTES : NaCl_uint8 renames crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; 119 | crypto_box_BOXZEROBYTES : NaCl_uint8 renames crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; 120 | crypto_box_BEFORENMBYTES : NaCl_uint8 121 | renames crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES; 122 | crypto_box_PUBLICKEYBYTES : NaCl_uint8 123 | renames crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; 124 | crypto_box_SECRETKEYBYTES : NaCl_uint8 125 | renames crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; 126 | crypto_box_SEALBYTES : constant NaCl_uint8 := crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES; 127 | 128 | crypto_sign_ed25519_BYTES : constant NaCl_uint8 := 64; 129 | crypto_sign_ed25519_SEEDBYTES : constant NaCl_uint8 := 32; 130 | crypto_sign_ed25519_PUBLICKEYBYTES : constant NaCl_uint8 := 32; 131 | crypto_sign_ed25519_SECRETKEYBYTES : constant NaCl_uint8 := 32 + 32; 132 | 133 | crypto_sign_BYTES : NaCl_uint8 renames crypto_sign_ed25519_BYTES; 134 | crypto_sign_SEEDBYTES : NaCl_uint8 renames crypto_sign_ed25519_SEEDBYTES; 135 | crypto_sign_PUBLICKEYBYTES : NaCl_uint8 renames crypto_sign_ed25519_PUBLICKEYBYTES; 136 | crypto_sign_SECRETKEYBYTES : NaCl_uint8 renames crypto_sign_ed25519_SECRETKEYBYTES; 137 | 138 | crypto_secretbox_xsalsa20poly1305_KEYBYTES : constant NaCl_uint8 := 32; 139 | crypto_secretbox_xsalsa20poly1305_NONCEBYTES : constant NaCl_uint8 := 24; 140 | crypto_secretbox_xsalsa20poly1305_MACBYTES : constant NaCl_uint8 := 16; 141 | crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES : constant NaCl_uint8 := 16; 142 | crypto_secretbox_xsalsa20poly1305_ZEROBYTES : constant NaCl_uint8 := 143 | crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + 144 | crypto_secretbox_xsalsa20poly1305_MACBYTES; 145 | 146 | crypto_secretbox_KEYBYTES : NaCl_uint8 renames crypto_secretbox_xsalsa20poly1305_KEYBYTES; 147 | crypto_secretbox_MACBYTES : NaCl_uint8 renames crypto_secretbox_xsalsa20poly1305_MACBYTES; 148 | crypto_secretbox_NONCEBYTES : NaCl_uint8 renames crypto_secretbox_xsalsa20poly1305_NONCEBYTES; 149 | crypto_secretbox_ZEROBYTES : NaCl_uint8 renames crypto_secretbox_xsalsa20poly1305_ZEROBYTES; 150 | crypto_secretbox_BOXZEROBYTES : NaCl_uint8 151 | renames crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES; 152 | 153 | crypto_auth_hmacsha512256_BYTES : constant NaCl_uint8 := 32; 154 | crypto_auth_hmacsha512256_KEYBYTES : constant NaCl_uint8 := 32; 155 | 156 | crypto_auth_BYTES : NaCl_uint8 renames crypto_auth_hmacsha512256_BYTES; 157 | crypto_auth_KEYBYTES : NaCl_uint8 renames crypto_auth_hmacsha512256_KEYBYTES; 158 | 159 | crypto_aead_chacha20poly1305_ietf_KEYBYTES : constant NaCl_uint8 := 32; 160 | crypto_aead_chacha20poly1305_ietf_NPUBBYTES : constant NaCl_uint8 := 12; 161 | crypto_aead_chacha20poly1305_ietf_ABYTES : constant NaCl_uint8 := 16; 162 | 163 | crypto_aead_chacha20poly1305_KEYBYTES : constant NaCl_uint8 := 32; 164 | crypto_aead_chacha20poly1305_NPUBBYTES : constant NaCl_uint8 := 8; 165 | crypto_aead_chacha20poly1305_ABYTES : constant NaCl_uint8 := 16; 166 | 167 | crypto_aead_aes256gcm_KEYBYTES : constant NaCl_uint8 := 32; 168 | crypto_aead_aes256gcm_NPUBBYTES : constant NaCl_uint8 := 12; 169 | crypto_aead_aes256gcm_ABYTES : constant NaCl_uint8 := 16; 170 | 171 | ------------------------ 172 | -- New C Data Types -- 173 | ------------------------ 174 | 175 | type Password_Hash_Container is array (1 .. Positive (crypto_pwhash_STRBYTES)) of IC.char; 176 | pragma Convention (C, Password_Hash_Container); 177 | 178 | ----------------- 179 | -- Important -- 180 | ----------------- 181 | 182 | function sodium_init return IC.int; 183 | pragma Import (C, sodium_init); 184 | 185 | --------------- 186 | -- Hashing -- 187 | --------------- 188 | 189 | function crypto_generichash 190 | (text_out : ICS.chars_ptr; 191 | outlen : IC.size_t; 192 | text_in : ICS.chars_ptr; 193 | inlen : NaCl_uint64; 194 | key : ICS.chars_ptr; 195 | keylen : IC.size_t) return IC.int; 196 | pragma Import (C, crypto_generichash); 197 | 198 | function crypto_generichash_init 199 | (state : crypto_generichash_state_Access; 200 | key : ICS.chars_ptr; 201 | keylen : IC.size_t; 202 | outlen : IC.size_t) return IC.int; 203 | pragma Import (C, crypto_generichash_init); 204 | 205 | function crypto_generichash_update 206 | (state : crypto_generichash_state_Access; 207 | text_in : ICS.chars_ptr; 208 | inlen : NaCl_uint64) return IC.int; 209 | pragma Import (C, crypto_generichash_update); 210 | 211 | function crypto_generichash_final 212 | (state : crypto_generichash_state_Access; 213 | text_out : ICS.chars_ptr; 214 | outlen : IC.size_t) return IC.int; 215 | pragma Import (C, crypto_generichash_final); 216 | 217 | function crypto_shorthash 218 | (text_out : ICS.chars_ptr; 219 | text_in : ICS.chars_ptr; 220 | inlen : NaCl_uint64; 221 | k : ICS.chars_ptr) return IC.int; 222 | pragma Import (C, crypto_shorthash); 223 | 224 | function crypto_pwhash 225 | (text_out : ICS.chars_ptr; 226 | outlen : NaCl_uint64; 227 | passwd : ICS.chars_ptr; 228 | passwdlen : NaCl_uint64; 229 | salt : ICS.chars_ptr; 230 | opslimit : NaCl_uint64; 231 | memlimit : IC.size_t; 232 | alg : IC.int) return IC.int; 233 | pragma Import (C, crypto_pwhash); 234 | 235 | function crypto_pwhash_str 236 | (text_out : out Password_Hash_Container; 237 | passwd : ICS.chars_ptr; 238 | passwdlen : NaCl_uint64; 239 | opslimit : NaCl_uint64; 240 | memlimit : IC.size_t) return IC.int; 241 | pragma Import (C, crypto_pwhash_str); 242 | 243 | function crypto_pwhash_str_verify 244 | (text_str : Password_Hash_Container; 245 | passwd : ICS.chars_ptr; 246 | passwdlen : NaCl_uint64) return IC.int; 247 | pragma Import (C, crypto_pwhash_str_verify); 248 | 249 | --------------------- 250 | -- Random Things -- 251 | --------------------- 252 | 253 | procedure randombytes_buf 254 | (buf : System.Address; 255 | size : IC.size_t); 256 | pragma Import (C, randombytes_buf); 257 | 258 | function randombytes_random return NaCl_uint32; 259 | pragma Import (C, randombytes_random); 260 | 261 | function randombytes_uniform (upper_bound : NaCl_uint32) return NaCl_uint32; 262 | pragma Import (C, randombytes_uniform); 263 | 264 | ----------------------------- 265 | -- Public Key Signatures -- 266 | ----------------------------- 267 | 268 | function crypto_sign_keypair 269 | (pk : ICS.chars_ptr; 270 | sk : ICS.chars_ptr) return IC.int; 271 | pragma Import (C, crypto_sign_keypair); 272 | 273 | function crypto_sign_seed_keypair 274 | (pk : ICS.chars_ptr; 275 | sk : ICS.chars_ptr; 276 | seed : ICS.chars_ptr) return IC.int; 277 | pragma Import (C, crypto_sign_seed_keypair); 278 | 279 | function crypto_sign 280 | (sm : ICS.chars_ptr; smlen : NaCl_uint64; 281 | m : ICS.chars_ptr; mlen : NaCl_uint64; 282 | sk : ICS.chars_ptr) return IC.int; 283 | pragma Import (C, crypto_sign); 284 | 285 | function crypto_sign_open 286 | (m : ICS.chars_ptr; mlen : NaCl_uint64; 287 | sm : ICS.chars_ptr; smlen : NaCl_uint64; 288 | pk : ICS.chars_ptr) return IC.int; 289 | pragma Import (C, crypto_sign_open); 290 | 291 | function crypto_sign_detached 292 | (sig : ICS.chars_ptr; siglen : ICS.chars_ptr; 293 | m : ICS.chars_ptr; mlen : NaCl_uint64; 294 | sk : ICS.chars_ptr) return IC.int; 295 | pragma Import (C, crypto_sign_detached); 296 | 297 | function crypto_sign_verify_detached 298 | (sig : ICS.chars_ptr; 299 | m : ICS.chars_ptr; mlen : NaCl_uint64; 300 | pk : ICS.chars_ptr) return IC.int; 301 | pragma Import (C, crypto_sign_verify_detached); 302 | 303 | ----------------------------- 304 | -- Public Key Encryption -- 305 | ----------------------------- 306 | 307 | function crypto_box_keypair 308 | (pk : ICS.chars_ptr; 309 | sk : ICS.chars_ptr) return IC.int; 310 | pragma Import (C, crypto_box_keypair); 311 | 312 | function crypto_box_seed_keypair 313 | (pk : ICS.chars_ptr; 314 | sk : ICS.chars_ptr; 315 | seed : ICS.chars_ptr) return IC.int; 316 | pragma Import (C, crypto_box_seed_keypair); 317 | 318 | function crypto_scalarmult_base 319 | (q : ICS.chars_ptr; 320 | n : ICS.chars_ptr) return IC.int; 321 | pragma Import (C, crypto_scalarmult_base); 322 | 323 | function crypto_box_easy 324 | (c : ICS.chars_ptr; 325 | m : ICS.chars_ptr; mlen : NaCl_uint64; 326 | n : ICS.chars_ptr; 327 | pk : ICS.chars_ptr; 328 | sk : ICS.chars_ptr) return IC.int; 329 | pragma Import (C, crypto_box_easy); 330 | 331 | function crypto_box_open_easy 332 | (m : ICS.chars_ptr; 333 | c : ICS.chars_ptr; clen : NaCl_uint64; 334 | n : ICS.chars_ptr; 335 | pk : ICS.chars_ptr; 336 | sk : ICS.chars_ptr) return IC.int; 337 | pragma Import (C, crypto_box_open_easy); 338 | 339 | function crypto_box_detached 340 | (c : ICS.chars_ptr; 341 | mac : ICS.chars_ptr; 342 | m : ICS.chars_ptr; mlen : NaCl_uint64; 343 | n : ICS.chars_ptr; 344 | pk : ICS.chars_ptr; 345 | sk : ICS.chars_ptr) return IC.int; 346 | pragma Import (C, crypto_box_detached); 347 | 348 | function crypto_box_open_detached 349 | (m : ICS.chars_ptr; 350 | c : ICS.chars_ptr; 351 | mac : ICS.chars_ptr; 352 | clen : NaCl_uint64; 353 | n : ICS.chars_ptr; 354 | pk : ICS.chars_ptr; 355 | sk : ICS.chars_ptr) return IC.int; 356 | pragma Import (C, crypto_box_open_detached); 357 | 358 | function crypto_box_beforenm 359 | (k : ICS.chars_ptr; 360 | pk : ICS.chars_ptr; 361 | sk : ICS.chars_ptr) return IC.int; 362 | pragma Import (C, crypto_box_beforenm); 363 | 364 | function crypto_box_easy_afternm 365 | (c : ICS.chars_ptr; 366 | m : ICS.chars_ptr; mlen : NaCl_uint64; 367 | n : ICS.chars_ptr; 368 | k : ICS.chars_ptr) return IC.int; 369 | pragma Import (C, crypto_box_easy_afternm); 370 | 371 | function crypto_box_open_easy_afternm 372 | (m : ICS.chars_ptr; 373 | c : ICS.chars_ptr; clen : NaCl_uint64; 374 | n : ICS.chars_ptr; 375 | k : ICS.chars_ptr) return IC.int; 376 | pragma Import (C, crypto_box_open_easy_afternm); 377 | 378 | function crypto_box_detached_afternm 379 | (c : ICS.chars_ptr; 380 | mac : ICS.chars_ptr; 381 | m : ICS.chars_ptr; mlen : NaCl_uint64; 382 | n : ICS.chars_ptr; 383 | k : ICS.chars_ptr) return IC.int; 384 | pragma Import (C, crypto_box_detached_afternm); 385 | 386 | function crypto_box_open_detached_afternm 387 | (m : ICS.chars_ptr; 388 | c : ICS.chars_ptr; 389 | mac : ICS.chars_ptr; 390 | clen : NaCl_uint64; 391 | n : ICS.chars_ptr; 392 | k : ICS.chars_ptr) return IC.int; 393 | pragma Import (C, crypto_box_open_detached_afternm); 394 | 395 | ---------------------------------- 396 | -- Anonymous Private Messages -- 397 | ---------------------------------- 398 | 399 | function crypto_box_seal 400 | (c : ICS.chars_ptr; 401 | m : ICS.chars_ptr; mlen : NaCl_uint64; 402 | pk : ICS.chars_ptr) return IC.int; 403 | pragma Import (C, crypto_box_seal); 404 | 405 | function crypto_box_seal_open 406 | (m : ICS.chars_ptr; 407 | c : ICS.chars_ptr; clen : NaCl_uint64; 408 | pk : ICS.chars_ptr; 409 | sk : ICS.chars_ptr) return IC.int; 410 | pragma Import (C, crypto_box_seal_open); 411 | 412 | ---------------------------- 413 | -- Symmetric Encryption -- 414 | ---------------------------- 415 | 416 | function crypto_secretbox_easy 417 | (c : ICS.chars_ptr; 418 | m : ICS.chars_ptr; mlen : NaCl_uint64; 419 | n : ICS.chars_ptr; 420 | k : ICS.chars_ptr) return IC.int; 421 | pragma Import (C, crypto_secretbox_easy); 422 | 423 | function crypto_secretbox_open_easy 424 | (m : ICS.chars_ptr; 425 | c : ICS.chars_ptr; clen : NaCl_uint64; 426 | n : ICS.chars_ptr; 427 | k : ICS.chars_ptr) return IC.int; 428 | pragma Import (C, crypto_secretbox_open_easy); 429 | 430 | function crypto_secretbox_detached 431 | (c : ICS.chars_ptr; 432 | mac : ICS.chars_ptr; 433 | m : ICS.chars_ptr; mlen : NaCl_uint64; 434 | n : ICS.chars_ptr; 435 | k : ICS.chars_ptr) return IC.int; 436 | pragma Import (C, crypto_secretbox_detached); 437 | 438 | function crypto_secretbox_open_detached 439 | (m : ICS.chars_ptr; 440 | c : ICS.chars_ptr; 441 | mac : ICS.chars_ptr; 442 | clen : NaCl_uint64; 443 | n : ICS.chars_ptr; 444 | k : ICS.chars_ptr) return IC.int; 445 | pragma Import (C, crypto_secretbox_open_detached); 446 | 447 | ------------------------------ 448 | -- Message Authentication -- 449 | ------------------------------ 450 | 451 | function crypto_auth 452 | (tag : ICS.chars_ptr; 453 | text_in : ICS.chars_ptr; 454 | inlen : NaCl_uint64; 455 | k : ICS.chars_ptr) return IC.int; 456 | pragma Import (C, crypto_auth); 457 | 458 | function crypto_auth_verify 459 | (tag : ICS.chars_ptr; 460 | text_in : ICS.chars_ptr; 461 | inlen : NaCl_uint64; 462 | k : ICS.chars_ptr) return IC.int; 463 | pragma Import (C, crypto_auth_verify); 464 | 465 | ---------------------------------- 466 | -- original ChaCha20-Poly1305 -- 467 | ---------------------------------- 468 | 469 | function crypto_aead_chacha20poly1305_encrypt 470 | (c : ICS.chars_ptr; clen_p : NaCl_uint64_Access; 471 | m : ICS.chars_ptr; mlen : NaCl_uint64; 472 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 473 | nsec : ICS.chars_ptr; 474 | npub : ICS.chars_ptr; 475 | k : ICS.chars_ptr) return IC.int; 476 | pragma Import (C, crypto_aead_chacha20poly1305_encrypt); 477 | 478 | function crypto_aead_chacha20poly1305_decrypt 479 | (m : ICS.chars_ptr; mlen_p : NaCl_uint64_Access; 480 | nsec : ICS.chars_ptr; 481 | c : ICS.chars_ptr; clen : NaCl_uint64; 482 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 483 | npub : ICS.chars_ptr; 484 | k : ICS.chars_ptr) return IC.int; 485 | pragma Import (C, crypto_aead_chacha20poly1305_decrypt); 486 | 487 | function crypto_aead_chacha20poly1305_encrypt_detached 488 | (c : ICS.chars_ptr; 489 | mac : ICS.chars_ptr; maclen_p : NaCl_uint64_Access; 490 | m : ICS.chars_ptr; mlen : NaCl_uint64; 491 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 492 | nsec : ICS.chars_ptr; 493 | npub : ICS.chars_ptr; 494 | k : ICS.chars_ptr) return IC.int; 495 | pragma Import (C, crypto_aead_chacha20poly1305_encrypt_detached); 496 | 497 | function crypto_aead_chacha20poly1305_decrypt_detached 498 | (m : ICS.chars_ptr; 499 | nsec : ICS.chars_ptr; 500 | c : ICS.chars_ptr; clen : NaCl_uint64; 501 | mac : ICS.chars_ptr; 502 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 503 | npub : ICS.chars_ptr; 504 | k : ICS.chars_ptr) return IC.int; 505 | pragma Import (C, crypto_aead_chacha20poly1305_decrypt_detached); 506 | 507 | ------------------------------ 508 | -- IETF ChaCha20-Poly1305 -- 509 | ------------------------------ 510 | 511 | function crypto_aead_chacha20poly1305_ietf_encrypt 512 | (c : ICS.chars_ptr; clen_p : NaCl_uint64_Access; 513 | m : ICS.chars_ptr; mlen : NaCl_uint64; 514 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 515 | nsec : ICS.chars_ptr; 516 | npub : ICS.chars_ptr; 517 | k : ICS.chars_ptr) return IC.int; 518 | pragma Import (C, crypto_aead_chacha20poly1305_ietf_encrypt); 519 | 520 | function crypto_aead_chacha20poly1305_ietf_decrypt 521 | (m : ICS.chars_ptr; mlen_p : NaCl_uint64_Access; 522 | nsec : ICS.chars_ptr; 523 | c : ICS.chars_ptr; clen : NaCl_uint64; 524 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 525 | npub : ICS.chars_ptr; 526 | k : ICS.chars_ptr) return IC.int; 527 | pragma Import (C, crypto_aead_chacha20poly1305_ietf_decrypt); 528 | 529 | function crypto_aead_chacha20poly1305_ietf_encrypt_detached 530 | (c : ICS.chars_ptr; 531 | mac : ICS.chars_ptr; maclen_p : NaCl_uint64_Access; 532 | m : ICS.chars_ptr; mlen : NaCl_uint64; 533 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 534 | nsec : ICS.chars_ptr; 535 | npub : ICS.chars_ptr; 536 | k : ICS.chars_ptr) return IC.int; 537 | pragma Import (C, crypto_aead_chacha20poly1305_ietf_encrypt_detached); 538 | 539 | function crypto_aead_chacha20poly1305_ietf_decrypt_detached 540 | (m : ICS.chars_ptr; 541 | nsec : ICS.chars_ptr; 542 | c : ICS.chars_ptr; clen : NaCl_uint64; 543 | mac : ICS.chars_ptr; 544 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 545 | npub : ICS.chars_ptr; 546 | k : ICS.chars_ptr) return IC.int; 547 | pragma Import (C, crypto_aead_chacha20poly1305_ietf_decrypt_detached); 548 | 549 | --------------- 550 | -- AES-GCM -- 551 | --------------- 552 | 553 | function crypto_aead_aes256gcm_encrypt 554 | (c : ICS.chars_ptr; clen_p : NaCl_uint64_Access; 555 | m : ICS.chars_ptr; mlen : NaCl_uint64; 556 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 557 | nsec : ICS.chars_ptr; 558 | npub : ICS.chars_ptr; 559 | k : ICS.chars_ptr) return IC.int; 560 | pragma Import (C, crypto_aead_aes256gcm_encrypt); 561 | 562 | function crypto_aead_aes256gcm_decrypt 563 | (m : ICS.chars_ptr; mlen_p : NaCl_uint64_Access; 564 | nsec : ICS.chars_ptr; 565 | c : ICS.chars_ptr; clen : NaCl_uint64; 566 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 567 | npub : ICS.chars_ptr; 568 | k : ICS.chars_ptr) return IC.int; 569 | pragma Import (C, crypto_aead_aes256gcm_decrypt); 570 | 571 | function crypto_aead_aes256gcm_encrypt_detached 572 | (c : ICS.chars_ptr; 573 | mac : ICS.chars_ptr; maclen_p : NaCl_uint64_Access; 574 | m : ICS.chars_ptr; mlen : NaCl_uint64; 575 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 576 | nsec : ICS.chars_ptr; 577 | npub : ICS.chars_ptr; 578 | k : ICS.chars_ptr) return IC.int; 579 | pragma Import (C, crypto_aead_aes256gcm_encrypt_detached); 580 | 581 | function crypto_aead_aes256gcm_decrypt_detached 582 | (m : ICS.chars_ptr; 583 | nsec : ICS.chars_ptr; 584 | c : ICS.chars_ptr; clen : NaCl_uint64; 585 | mac : ICS.chars_ptr; 586 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 587 | npub : ICS.chars_ptr; 588 | k : ICS.chars_ptr) return IC.int; 589 | pragma Import (C, crypto_aead_aes256gcm_decrypt_detached); 590 | 591 | ----------------------------------- 592 | -- AES-GCM with Precalculation -- 593 | ----------------------------------- 594 | 595 | function crypto_aead_aes256gcm_beforenm 596 | (ctx : crypto_aead_aes256gcm_state_Access; 597 | k : ICS.chars_ptr) return IC.int; 598 | pragma Import (C, crypto_aead_aes256gcm_beforenm); 599 | 600 | function crypto_aead_aes256gcm_encrypt_afternm 601 | (c : ICS.chars_ptr; clen_p : NaCl_uint64_Access; 602 | m : ICS.chars_ptr; mlen : NaCl_uint64; 603 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 604 | nsec : ICS.chars_ptr; 605 | npub : ICS.chars_ptr; 606 | ctx : crypto_aead_aes256gcm_state_Access) return IC.int; 607 | pragma Import (C, crypto_aead_aes256gcm_encrypt_afternm); 608 | 609 | function crypto_aead_aes256gcm_decrypt_afternm 610 | (m : ICS.chars_ptr; mlen_p : NaCl_uint64_Access; 611 | nsec : ICS.chars_ptr; 612 | c : ICS.chars_ptr; clen : NaCl_uint64; 613 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 614 | npub : ICS.chars_ptr; 615 | ctx : crypto_aead_aes256gcm_state_Access) return IC.int; 616 | pragma Import (C, crypto_aead_aes256gcm_decrypt_afternm); 617 | 618 | function crypto_aead_aes256gcm_encrypt_detached_afternm 619 | (c : ICS.chars_ptr; 620 | mac : ICS.chars_ptr; maclen_p : NaCl_uint64_Access; 621 | m : ICS.chars_ptr; mlen : NaCl_uint64; 622 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 623 | nsec : ICS.chars_ptr; 624 | npub : ICS.chars_ptr; 625 | ctx : crypto_aead_aes256gcm_state_Access) return IC.int; 626 | pragma Import (C, crypto_aead_aes256gcm_encrypt_detached_afternm); 627 | 628 | function crypto_aead_aes256gcm_decrypt_detached_afternm 629 | (m : ICS.chars_ptr; 630 | nsec : ICS.chars_ptr; 631 | c : ICS.chars_ptr; clen : NaCl_uint64; 632 | mac : ICS.chars_ptr; 633 | ad : ICS.chars_ptr; adlen : NaCl_uint64; 634 | npub : ICS.chars_ptr; 635 | ctx : crypto_aead_aes256gcm_state_Access) return IC.int; 636 | pragma Import (C, crypto_aead_aes256gcm_decrypt_detached_afternm); 637 | 638 | ------------------------ 639 | -- AES Availability -- 640 | ------------------------ 641 | 642 | function crypto_aead_aes256gcm_is_available return IC.int; 643 | pragma Import (C, crypto_aead_aes256gcm_is_available); 644 | 645 | end Sodium.Thin_Binding; 646 | -------------------------------------------------------------------------------- /Binding_Sodium/sodium.ads: -------------------------------------------------------------------------------- 1 | -- This file is covered by the Internet Software Consortium (ISC) License 2 | -- Reference: ../License.txt 3 | 4 | package Sodium is 5 | 6 | pragma Pure; 7 | 8 | end Sodium; 9 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, John R. Marino 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libsodium-ada [![License](http://img.shields.io/badge/license-ISC-green.svg)](https://github.com/jrmarino/libsodium-ada/blob/master/License.txt) 2 | 3 | libsodium-ada is a set of thick Ada bindings to 4 | [libsodium](https://github.com/jedisct1/libsodium) thick bindings to libsodium. 5 | libsodium is a portable and relatively easy to use implementation of 6 | [Daniel Bernstein's](http://cr.yp.to/djb.html) fantastic 7 | [NaCl](http://nacl.cr.yp.to/) library. 8 | 9 | ## Why 10 | 11 | NaCl is a great encryption, hashing, and authentication library that is 12 | designed to make proper implementation easy and straight-forward. By using 13 | it, many of the finer details including speed-optimization are abstracted 14 | away so the programmer doesn't need to worry about them. NaCl itself is less 15 | than portable C, only targeted for *nix systems. libsodium makes the library 16 | portable, and adds additional conveniences to make the library easily 17 | standardized across multiple platforms, operating systems, and languages. 18 | 19 | Crypto is very tricky to implement correctly. With the sodium library, you 20 | are much more likely to get it correct out of the box, by implementing solid 21 | encryption standards and practices without materially effecting performance. 22 | 23 | 24 | ## Documentation 25 | 26 | The testcases in the examples directory also serve to illustrate how the 27 | bindings can be used. The 28 | [original libsodium documentation library](http://doc.libsodium.org/) written 29 | by Frank Denis ([@jedisct1](https://github.com/jedisct1)) is also useful. 30 | 31 | ## Requirements & Versions 32 | 33 | libsodium-ada was tested with the 32-bit libsodium.a library version 1.0.10 34 | built for mingw (since GNAT GPL 2016 is 32-bit). 35 | [Click here for precompiled libsodium DLLs.](https://download.libsodium.org/libsodium/releases/) 36 | It will also work with *nix versions. 37 | 38 | ## License 39 | 40 | NaCl has been released to the public domain to avoid copyright issues. 41 | Both libsodium and these bindings have been released under the 42 | [ISC license](https://en.wikipedia.org/wiki/ISC_license). 43 | -------------------------------------------------------------------------------- /default.gpr: -------------------------------------------------------------------------------- 1 | project Default is 2 | 3 | for Source_Dirs use (".", "Binding_Sodium"); 4 | 5 | package Compiler is 6 | for Switches ("ada") use ("-gnatVa", "-g", "-O2", "-gnat12", "-fstack-check", "-gnatyaAbBcdefiIknOprsthxlM99", "-gnatf"); 7 | end Compiler; 8 | 9 | package Pretty_Printer is 10 | for Default_Switches ("ada") use ("-nL", "-pL", "-M99"); 11 | end Pretty_Printer; 12 | 13 | for Object_Dir use "build"; 14 | 15 | end Default; 16 | 17 | -------------------------------------------------------------------------------- /examples/AEAD/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sodium.h" 3 | 4 | #define MESSAGE (const unsigned char *) "From Russia with love." 5 | #define MESSAGE_LEN 22 6 | #define ADDITIONAL_DATA (const unsigned char *) "22 chars" 7 | #define ADDITIONAL_DATA_LEN 8 8 | 9 | 10 | int main () { 11 | unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES] = {0}; 12 | unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES] = {0}; 13 | unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_ABYTES]; 14 | unsigned long long ciphertext_len; 15 | 16 | if (sodium_init() != 0) { 17 | return -1; 18 | } 19 | 20 | // randombytes_buf(key, sizeof key); 21 | // randombytes_buf(nonce, sizeof nonce); 22 | 23 | crypto_aead_chacha20poly1305_encrypt(ciphertext, &ciphertext_len, 24 | MESSAGE, MESSAGE_LEN, 25 | ADDITIONAL_DATA, ADDITIONAL_DATA_LEN, 26 | NULL, nonce, key); 27 | 28 | size_t hexlen = sizeof ciphertext * 2 + 1; 29 | unsigned char hex[hexlen]; 30 | sodium_bin2hex (hex, hexlen, ciphertext, ciphertext_len); 31 | 32 | printf ("ciphertext: %s\n", hex); 33 | 34 | unsigned char decrypted[MESSAGE_LEN + 1] = {0}; 35 | unsigned long long decrypted_len; 36 | if (crypto_aead_chacha20poly1305_decrypt(decrypted, &decrypted_len, 37 | NULL, 38 | ciphertext, ciphertext_len, 39 | ADDITIONAL_DATA, 40 | ADDITIONAL_DATA_LEN, 41 | nonce, key) == 0) 42 | printf ("From ciphertext to clear: %s\n", decrypted); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /examples/AEAD/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/AEAD/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "From Russia with love."; 7 | metadata : constant String := "22 chars"; 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | declare 15 | secret_key : AEAD_Key := Random_AEAD_Key; 16 | msg_nonce : AEAD_Nonce := Random_AEAD_Nonce; 17 | cipherlen : constant Positive := AEAD_Cipher_Length (message); 18 | cipher_text : Encrypted_Data (1 .. cipherlen); 19 | clear_text : String (1 .. message'Length); 20 | begin 21 | -- Match with C version for comparison's sake 22 | secret_key (1 .. secret_key'Last) := (others => ASCII.NUL); 23 | msg_nonce (1 .. msg_nonce'Last) := (others => ASCII.NUL); 24 | 25 | Put_Line ("Secret Key (ChaCha20): " & As_Hexidecimal (secret_key)); 26 | Put_Line ("Nonce (ChaCha20): " & As_Hexidecimal (msg_nonce)); 27 | 28 | cipher_text := AEAD_Encrypt (data_to_encrypt => message, 29 | additional_data => metadata, 30 | secret_key => secret_key, 31 | unique_nonce => msg_nonce); 32 | 33 | Put_Line ("CipherText (ChaCha20): " & As_Hexidecimal (cipher_text)); 34 | 35 | begin 36 | clear_text := AEAD_Decrypt (ciphertext => cipher_text, 37 | additional_data => metadata, 38 | secret_key => secret_key, 39 | unique_nonce => msg_nonce); 40 | Put_Line ("Back again : " & clear_text); 41 | exception 42 | when others => Put_Line ("Convert to clear text failed"); 43 | end; 44 | end; 45 | 46 | declare 47 | secret_key : AEAD_Key := Random_AEAD_Key (AES256_GCM); 48 | msg_nonce : AEAD_Nonce := Random_AEAD_Nonce (AES256_GCM); 49 | clear_text : String (1 .. message'Length); 50 | begin 51 | Put_Line (""); 52 | Put_Line ("Secret Key (AES256_GCM): " & As_Hexidecimal (secret_key)); 53 | Put_Line ("Nonce (AES256_GCM): " & As_Hexidecimal (msg_nonce)); 54 | 55 | declare 56 | cipher_text : Encrypted_Data := 57 | AEAD_Encrypt (data_to_encrypt => message, 58 | additional_data => metadata, 59 | secret_key => secret_key, 60 | unique_nonce => msg_nonce, 61 | construction => AES256_GCM); 62 | begin 63 | Put_Line ("CipherText (AES256_GCM): " & As_Hexidecimal (cipher_text)); 64 | 65 | clear_text := AEAD_Decrypt (ciphertext => cipher_text, 66 | additional_data => metadata, 67 | secret_key => secret_key, 68 | unique_nonce => msg_nonce, 69 | construction => AES256_GCM); 70 | Put_Line ("Back again : " & clear_text); 71 | exception 72 | when others => Put_Line ("Convert to clear text failed"); 73 | end; 74 | end; 75 | 76 | declare 77 | secret_key : AEAD_Key := Random_AEAD_Key (ChaCha20_Poly1305_IETF); 78 | msg_nonce : AEAD_Nonce := Random_AEAD_Nonce (ChaCha20_Poly1305_IETF); 79 | cipherlen : constant Positive := AEAD_Cipher_Length (message, ChaCha20_Poly1305_IETF); 80 | cipher_text : Encrypted_Data (1 .. cipherlen); 81 | clear_text : String (1 .. message'Length); 82 | begin 83 | Put_Line (""); 84 | if AES256_GCM_Available then 85 | Put_Line ("Secret Key (CC20IETF): " & As_Hexidecimal (secret_key)); 86 | Put_Line ("Nonce (CC20IETF): " & As_Hexidecimal (msg_nonce)); 87 | 88 | cipher_text := AEAD_Encrypt (data_to_encrypt => message, 89 | additional_data => metadata, 90 | secret_key => secret_key, 91 | unique_nonce => msg_nonce, 92 | construction => ChaCha20_Poly1305_IETF); 93 | 94 | Put_Line ("CipherText (CC20IETF): " & As_Hexidecimal (cipher_text)); 95 | 96 | begin 97 | clear_text := AEAD_Decrypt (ciphertext => cipher_text, 98 | additional_data => metadata, 99 | secret_key => secret_key, 100 | unique_nonce => msg_nonce, 101 | construction => ChaCha20_Poly1305_IETF); 102 | Put_Line ("Back again : " & clear_text); 103 | exception 104 | when others => Put_Line ("Convert to clear text failed"); 105 | end; 106 | else 107 | Put_Line ("This CPU cannot perform AES256, skipping test ..."); 108 | end if; 109 | end; 110 | end Demo_Ada; 111 | -------------------------------------------------------------------------------- /examples/common.gpr: -------------------------------------------------------------------------------- 1 | project Common is 2 | 3 | type Os_Type is ("unix", "windows"); 4 | Opsys : Os_Type := external ("opsys", "windows"); 5 | 6 | package Compiler is 7 | case Opsys is 8 | when "windows" => 9 | for Default_Switches ("C") use ("-I", "../../../libsodium-1.0.10-mingw/libsodium-win32/include"); 10 | when "unix" => 11 | for Default_Switches ("C") use ("-I", "/usr/local/include"); 12 | end case; 13 | end Compiler; 14 | 15 | package Linker is 16 | NaCl := ("../../libsodium-1.0.10-mingw/libsodium-win32/lib/libsodium.a"); 17 | NixSalt := ("-L", "/usr/local/lib", "-lsodium"); 18 | case Opsys is 19 | when "windows" => 20 | for Default_Switches ("C") use NaCl; 21 | for Default_Switches ("Ada") use NaCl; 22 | when "unix" => 23 | for Default_Switches ("C") use NixSalt; 24 | for Default_Switches ("Ada") use NixSalt; 25 | end case; 26 | end Linker; 27 | 28 | end Common; 29 | -------------------------------------------------------------------------------- /examples/encryption/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/encryption/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "JRM wrote this note."; 7 | message2 : constant String := "1972 Miami Dolphins"; 8 | cipherlen : constant Positive := Cipher_Length (message); 9 | cipher2len : constant Positive := Cipher_Length (message2); 10 | begin 11 | if not initialize_sodium_library then 12 | Put_Line ("Initialization failed"); 13 | return; 14 | end if; 15 | 16 | declare 17 | alice_public_key : Public_Box_Key; 18 | alice_secret_key : Secret_Box_Key; 19 | bob_public_key : Public_Box_Key; 20 | bob_secret_key : Secret_Box_Key; 21 | shared_key : Box_Shared_Key; 22 | new_nonce : Box_Nonce := Random_Nonce; 23 | cipher_text : Encrypted_Data (1 .. cipherlen); 24 | cipher2_text : Encrypted_Data (1 .. cipher2len); 25 | clear_text : String (1 .. message'Length); 26 | clear_text2 : String (1 .. message2'Length); 27 | new_box_seed : Sign_Key_Seed := Random_Box_Key_seed; 28 | begin 29 | Generate_Box_Keys (alice_public_key, alice_secret_key); 30 | Generate_Box_Keys (bob_public_key, bob_secret_key, new_box_seed); 31 | Put_Line ("Alice Public Key: " & As_Hexidecimal (alice_public_key)); 32 | Put_Line ("Alice Secret Key: " & As_Hexidecimal (alice_secret_key)); 33 | Put_Line ("Bob Public Key: " & As_Hexidecimal (bob_public_key)); 34 | Put_Line ("Bob Secret Key: " & As_Hexidecimal (bob_secret_key)); 35 | 36 | cipher_text := Encrypt_Message (plain_text_message => message, 37 | recipient_public_key => bob_public_key, 38 | sender_secret_key => alice_secret_key, 39 | unique_nonce => new_nonce); 40 | Put_Line ("CipherText (Alice): " & As_Hexidecimal (cipher_text)); 41 | 42 | clear_text := Decrypt_Message (ciphertext => cipher_text, 43 | sender_public_key => alice_public_key, 44 | recipient_secret_key => bob_secret_key, 45 | unique_nonce => new_nonce); 46 | Put_Line ("Back again: " & clear_text); 47 | 48 | shared_key := Generate_Shared_Key (recipient_public_key => alice_public_key, 49 | sender_secret_key => bob_secret_key); 50 | Put_Line (""); 51 | Put_Line ("Shared Key (Bob): " & As_Hexidecimal (shared_key)); 52 | 53 | new_nonce := Random_Nonce; 54 | cipher2_text := Encrypt_Message (plain_text_message => message2, 55 | shared_key => shared_key, 56 | unique_nonce => new_nonce); 57 | Put_Line ("CipherText2 (Bob): " & As_Hexidecimal (cipher2_text)); 58 | clear_text2 := Decrypt_Message (ciphertext => cipher2_text, 59 | shared_key => shared_key, 60 | unique_nonce => new_nonce); 61 | Put_Line ("Back again: " & clear_text2); 62 | end; 63 | end Demo_Ada; 64 | -------------------------------------------------------------------------------- /examples/hash_multipart/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sodium.h" 3 | 4 | #define MESSAGE_PART1 ((const unsigned char *) "Arbitrary data to hash") 5 | #define MESSAGE_PART1_LEN 22 6 | 7 | #define MESSAGE_PART2 ((const unsigned char *) "is longer than expected") 8 | #define MESSAGE_PART2_LEN 23 9 | 10 | int main () { 11 | unsigned char hash[crypto_generichash_BYTES + 1] = {0}; 12 | unsigned char key[crypto_generichash_KEYBYTES] = "123456789 123456789 123456789 12"; 13 | crypto_generichash_state state; 14 | 15 | if (sodium_init() != 0) { 16 | return -1; 17 | } 18 | 19 | printf ("text 1: %s\ntext 2: %s\n", MESSAGE_PART1, MESSAGE_PART2); 20 | crypto_generichash_init(&state, NULL, 0, crypto_generichash_BYTES); 21 | crypto_generichash_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN); 22 | crypto_generichash_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN); 23 | crypto_generichash_final(&state, hash, crypto_generichash_BYTES); 24 | 25 | size_t hex_maxlen = crypto_generichash_BYTES * 2 + 1; 26 | unsigned char hex[hex_maxlen]; 27 | 28 | sodium_bin2hex (hex, hex_maxlen, hash, crypto_generichash_BYTES); 29 | 30 | printf ("hash: %s\n", hex); 31 | crypto_generichash_init(&state, key, sizeof key, crypto_generichash_BYTES); 32 | crypto_generichash_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN); 33 | crypto_generichash_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN); 34 | crypto_generichash_final(&state, hash, crypto_generichash_BYTES); 35 | 36 | sodium_bin2hex (hex, hex_maxlen, hash, crypto_generichash_BYTES); 37 | 38 | printf ("keyed hash: %s\n", hex); 39 | printf ("size of state: %d\n", sizeof state); 40 | printf ("offset t %d\n", offsetof(crypto_generichash_state, t)); 41 | printf ("offset f %d\n", offsetof(crypto_generichash_state, f)); 42 | printf ("offset buf %d\n", offsetof(crypto_generichash_state, buf)); 43 | printf ("offset buflen %d\n", offsetof(crypto_generichash_state, buflen)); 44 | printf ("offset last_node %d\n", offsetof(crypto_generichash_state, last_node)); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /examples/hash_multipart/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/hash_multipart/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message_1 : constant String := "Arbitrary data to hash"; 7 | message_2 : constant String := "is longer than expected"; 8 | key : constant String := "123456789 123456789 123456789 12"; 9 | 10 | state : Hash_State; 11 | hash : Standard_Hash; 12 | hash_len : constant Hash_Size_Range := hash'Length; 13 | begin 14 | if not initialize_sodium_library then 15 | Put_Line ("Initialization failed"); 16 | return; 17 | end if; 18 | 19 | state := Multipart_Hash_Start (hash_len); 20 | Multipart_Append (message_1, state); 21 | Multipart_Append (message_2, state); 22 | hash := Multipart_Hash_Complete (state); 23 | 24 | Put_Line ("text 1: " & message_1); 25 | Put_Line ("text 2: " & message_2); 26 | Put_Line ("hash: " & As_Hexidecimal (hash)); 27 | 28 | state := Multipart_Keyed_Hash_Start (key, hash_len); 29 | Multipart_Append (message_1, state); 30 | Multipart_Append (message_2, state); 31 | hash := Multipart_Hash_Complete (state); 32 | 33 | Put_Line ("keyed hash: " & As_Hexidecimal (hash)); 34 | end Demo_Ada; 35 | -------------------------------------------------------------------------------- /examples/hash_password/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sodium.h" 4 | 5 | #define PASSWORD "Correct Horse Battery Staple" 6 | #define KEY_LEN crypto_box_SEEDBYTES 7 | 8 | int main () { 9 | unsigned char salt[crypto_pwhash_SALTBYTES] = "123456789+123456"; 10 | unsigned char key[KEY_LEN + 1] = {0}; 11 | 12 | if (sodium_init() != 0) { 13 | return -1; 14 | } 15 | 16 | if (crypto_pwhash 17 | (key, KEY_LEN, PASSWORD, strlen(PASSWORD), salt, 18 | crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE, 19 | crypto_pwhash_ALG_DEFAULT) != 0) { 20 | /* out of memory */ 21 | return -1; 22 | } 23 | 24 | size_t hex_maxlen = KEY_LEN * 2 + 1; 25 | unsigned char hex[hex_maxlen]; 26 | 27 | sodium_bin2hex (hex, hex_maxlen, key, KEY_LEN); 28 | 29 | printf ("password: %s\n", PASSWORD); 30 | printf ("pass key: %s\n", hex); 31 | 32 | char hashed_password[crypto_pwhash_STRBYTES + 1] = {0}; 33 | 34 | if (crypto_pwhash_str 35 | (hashed_password, PASSWORD, strlen(PASSWORD), 36 | crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE) != 0) { 37 | /* out of memory */ 38 | return -1; 39 | } 40 | printf ("hash: %s\n", hashed_password); 41 | 42 | if (crypto_pwhash_str_verify 43 | (hashed_password, PASSWORD, strlen(PASSWORD)) == 0) { 44 | printf ("Hash verification passed\n"); 45 | } else { 46 | printf ("Hash verification failed\n"); 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /examples/hash_password/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/hash_password/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | password : constant String := "Correct Horse Battery Staple"; 7 | salt : constant String := "123456789+123456"; 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | Put_Line ("password: " & password); 15 | declare 16 | passkey : constant String := Derive_Password_Key (password => password, salt => salt); 17 | hash : constant Any_Hash := 18 | Generate_Password_Hash (criticality => highly_sensitive, password => password); 19 | begin 20 | Put_Line ("pass key: " & As_Hexidecimal (passkey)); 21 | Put_Line ("hash: " & hash); 22 | if Password_Hash_Matches (hash => hash, password => password) then 23 | Put_Line ("Hash verification passed"); 24 | else 25 | Put_Line ("Hash verification failed"); 26 | end if; 27 | end; 28 | end Demo_Ada; 29 | -------------------------------------------------------------------------------- /examples/hash_short/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sodium.h" 3 | 4 | #define SHORT_DATA ((const unsigned char *) "Sparkling water") 5 | #define SHORT_DATA_LEN 15 6 | 7 | int main () { 8 | unsigned char hash[crypto_shorthash_BYTES + 1] = {0}; 9 | unsigned char key[crypto_shorthash_KEYBYTES] = "123456789 123456"; 10 | 11 | if (sodium_init() != 0) { 12 | return -1; 13 | } 14 | 15 | printf ("text: %s\n", SHORT_DATA); 16 | crypto_shorthash(hash, SHORT_DATA, SHORT_DATA_LEN, key); 17 | 18 | size_t hex_maxlen = crypto_shorthash_BYTES * 2 + 1; 19 | unsigned char hex[hex_maxlen]; 20 | 21 | sodium_bin2hex (hex, hex_maxlen, hash, crypto_shorthash_BYTES); 22 | printf ("hash: %s\n", hex); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /examples/hash_short/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/hash_short/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "Sparkling water"; 7 | key : constant String := "123456789 123456"; 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | declare 15 | hash : constant String := Short_Input_Hash (message, key); 16 | hex : constant String := As_Hexidecimal (hash); 17 | begin 18 | Put_Line ("text: " & message); 19 | Put_Line ("hash: " & As_Hexidecimal (hash)); 20 | Put_Line ("Convert twice successfully: " & Boolean (As_Binary (hex) = hash)'Img); 21 | end; 22 | end Demo_Ada; 23 | -------------------------------------------------------------------------------- /examples/hash_single/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sodium.h" 4 | 5 | #define MESSAGE ((const unsigned char *) "Arbitrary text to hash") 6 | #define MESSAGE_LEN 22 7 | 8 | int main () { 9 | unsigned char hash[crypto_generichash_BYTES + 1] = {0}; 10 | unsigned char minhash[crypto_generichash_BYTES_MIN + 1] = {0}; 11 | unsigned char maxhash[crypto_generichash_BYTES_MAX + 1] = {0}; 12 | unsigned char key[crypto_generichash_KEYBYTES] = "123456789 123456789 123456789 12"; 13 | 14 | if (sodium_init() != 0) { 15 | return -1; 16 | } 17 | 18 | size_t min_hex_maxlen = crypto_generichash_BYTES_MIN * 2 + 1; 19 | size_t std_hex_maxlen = crypto_generichash_BYTES * 2 + 1; 20 | size_t max_hex_maxlen = crypto_generichash_BYTES_MAX * 2 + 1; 21 | unsigned char min_hex[min_hex_maxlen]; 22 | unsigned char std_hex[std_hex_maxlen]; 23 | unsigned char max_hex[max_hex_maxlen]; 24 | 25 | printf ("text: %s\n", MESSAGE); 26 | crypto_generichash(minhash, crypto_generichash_BYTES_MIN, 27 | MESSAGE, MESSAGE_LEN, 28 | NULL, 0); 29 | sodium_bin2hex (min_hex, min_hex_maxlen, minhash, crypto_generichash_BYTES_MIN); 30 | printf ("min hash: %s\n", min_hex); 31 | printf ("hash length is %d\n", strlen (minhash)); 32 | 33 | crypto_generichash(hash, crypto_generichash_BYTES, 34 | MESSAGE, MESSAGE_LEN, 35 | NULL, 0); 36 | sodium_bin2hex (std_hex, std_hex_maxlen, hash, crypto_generichash_BYTES); 37 | printf ("\nstd hash: %s\n", std_hex); 38 | printf ("hash length is %d\n", strlen (hash)); 39 | 40 | crypto_generichash(maxhash, crypto_generichash_BYTES_MAX, 41 | MESSAGE, MESSAGE_LEN, 42 | NULL, 0); 43 | sodium_bin2hex (max_hex, max_hex_maxlen, maxhash, crypto_generichash_BYTES_MAX); 44 | printf ("\nmax hash: %s\n", max_hex); 45 | printf ("hash length is %d\n", strlen (maxhash)); 46 | 47 | crypto_generichash(minhash, crypto_generichash_BYTES_MIN, 48 | MESSAGE, MESSAGE_LEN, 49 | key, sizeof key); 50 | sodium_bin2hex (min_hex, min_hex_maxlen, minhash, crypto_generichash_BYTES_MIN); 51 | printf ("\nkeyed min hash: %s\n", min_hex); 52 | 53 | crypto_generichash(hash, crypto_generichash_BYTES, 54 | MESSAGE, MESSAGE_LEN, 55 | key, sizeof key); 56 | sodium_bin2hex (std_hex, std_hex_maxlen, hash, crypto_generichash_BYTES); 57 | printf ("keyed std hash: %s\n", std_hex); 58 | 59 | crypto_generichash(maxhash, crypto_generichash_BYTES_MAX, 60 | MESSAGE, MESSAGE_LEN, 61 | key, sizeof key); 62 | sodium_bin2hex (max_hex, max_hex_maxlen, maxhash, crypto_generichash_BYTES_MAX); 63 | printf ("keyed max hash: %s\n", max_hex); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /examples/hash_single/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/hash_single/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "Arbitrary text to hash"; 7 | key : constant String := "123456789 123456789 123456789 12"; 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | declare 15 | hash : constant String := Keyless_Hash (message); 16 | minhash : constant String := Keyless_Hash (message, Hash_Size_Range'First); 17 | maxhash : constant String := Keyless_Hash (message, Hash_Size_Range'Last); 18 | keyhash : constant String := Keyed_Hash (message, key); 19 | keyhmin : constant String := Keyed_Hash (message, key, Hash_Size_Range'First); 20 | keyhmax : constant String := Keyed_Hash (message, key, Hash_Size_Range'Last); 21 | begin 22 | Put_Line ("text: " & message); 23 | Put_Line ("min hash: " & As_Hexidecimal (minhash)); 24 | Put_Line ("hash length is" & minhash'Length'Img); 25 | Put_Line (""); 26 | Put_Line ("std hash: " & As_Hexidecimal (hash)); 27 | Put_Line ("hash length is" & hash'Length'Img); 28 | Put_Line (""); 29 | Put_Line ("max hash: " & As_Hexidecimal (maxhash)); 30 | Put_Line ("hash length is" & maxhash'Length'Img); 31 | Put_Line (""); 32 | Put_Line ("keyed min hash: " & As_Hexidecimal (keyhmin)); 33 | Put_Line ("keyed std hash: " & As_Hexidecimal (keyhash)); 34 | Put_Line ("keyed max hash: " & As_Hexidecimal (keyhmax)); 35 | end; 36 | end Demo_Ada; 37 | -------------------------------------------------------------------------------- /examples/msg_authentication/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/msg_authentication/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : String := "Are you sure I wrote this?"; 7 | begin 8 | if not initialize_sodium_library then 9 | Put_Line ("Initialization failed"); 10 | return; 11 | end if; 12 | 13 | declare 14 | tag : Auth_Tag; 15 | my_key : Auth_Key := Random_Auth_Key; 16 | begin 17 | tag := Generate_Authentication_Tag (message => message, 18 | authentication_key => my_key); 19 | Put_Line (" Message: " & message); 20 | Put_Line ("Auth Tag: " & As_Hexidecimal (tag)); 21 | Put ("Test unmodified message and tag ... "); 22 | if Authentic_Message (authentication_tag => tag, 23 | message => message, 24 | authentication_key => my_key) 25 | then 26 | Put_Line ("Authentic"); 27 | else 28 | Put_Line ("It's a fake!"); 29 | end if; 30 | Put_Line (""); 31 | message (14) := 'i'; 32 | Put_Line (" Message: " & message); 33 | Put ("Test modified message and real tag ... "); 34 | 35 | if Authentic_Message (authentication_tag => tag, 36 | message => message, 37 | authentication_key => my_key) 38 | then 39 | Put_Line ("Authentic"); 40 | else 41 | Put_Line ("It's a fake!"); 42 | end if; 43 | end; 44 | end Demo_Ada; 45 | -------------------------------------------------------------------------------- /examples/nonce/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/nonce/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | FF : constant Character := Character'Val (255); 7 | n1 : String (1 .. 3) := (others => ASCII.NUL); 8 | n2 : String (1 .. 3) := (others => FF); 9 | n3 : String (1 .. 3) := (3 => Character'Val (254), others => ASCII.NUL); 10 | n4 : String (1 .. 3) := (3 => FF, others => ASCII.NUL); 11 | n5 : String (1 .. 3) := (1 => Character'Val (5), 2 => FF, 3 => FF); 12 | n6 : Box_Nonce; 13 | n7 : Symmetric_Nonce; 14 | begin 15 | if not initialize_sodium_library then 16 | Put_Line ("Initialization failed"); 17 | return; 18 | end if; 19 | 20 | n6 := Random_Nonce; 21 | n7 := Random_Symmetric_Nonce; 22 | 23 | Put_Line ("N1: " & As_Hexidecimal (n1)); 24 | increment_nonce (n1); 25 | Put_Line ("+1: " & As_Hexidecimal (n1)); 26 | Put_Line (""); 27 | 28 | Put_Line ("N2: " & As_Hexidecimal (n2)); 29 | increment_nonce (n2); 30 | Put_Line ("+1: " & As_Hexidecimal (n2)); 31 | Put_Line (""); 32 | 33 | Put_Line ("N3: " & As_Hexidecimal (n3)); 34 | increment_nonce (n3); 35 | Put_Line ("+1: " & As_Hexidecimal (n3)); 36 | Put_Line (""); 37 | 38 | Put_Line ("N4: " & As_Hexidecimal (n4)); 39 | increment_nonce (n4); 40 | Put_Line ("+1: " & As_Hexidecimal (n4)); 41 | Put_Line (""); 42 | 43 | Put_Line ("N5: " & As_Hexidecimal (n5)); 44 | increment_nonce (n5); 45 | Put_Line ("+1: " & As_Hexidecimal (n5)); 46 | Put_Line (""); 47 | 48 | Put_Line ("N6: " & As_Hexidecimal (n6)); 49 | increment_nonce (n6); 50 | Put_Line ("+1: " & As_Hexidecimal (n6)); 51 | Put_Line (""); 52 | 53 | Put_Line ("N7: " & As_Hexidecimal (n7)); 54 | increment_nonce (n7); 55 | Put_Line ("+1: " & As_Hexidecimal (n7)); 56 | 57 | end Demo_Ada; 58 | -------------------------------------------------------------------------------- /examples/random/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/random/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | upper_bound : Natural32 := 16#FFF#; 7 | Custom_Size : Key_Size_Range := 48; 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | Put_Line (" Full random: " & Random_Word'Img); 15 | Put_Line ("Limited to $FFF: " & Random_Limited_Word (upper_bound)'Img); 16 | Put_Line (" Random salt: " & As_Hexidecimal (Random_Salt)); 17 | Put_Line (" Random short: " & As_Hexidecimal (Random_Short_Key)); 18 | Put_Line (" Random Std key: " & As_Hexidecimal (Random_Standard_Hash_Key)); 19 | Put_LIne ("Rand 48-bit Key: " & As_Hexidecimal (Random_Hash_Key (Custom_Size))); 20 | end Demo_Ada; 21 | -------------------------------------------------------------------------------- /examples/sealed_box/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/sealed_box/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "For your eyes only! XoXo"; 7 | cipherlen : constant Positive := Sealed_Cipher_Length (message); 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | declare 15 | bob_public_key : Public_Box_Key; 16 | bob_secret_key : Secret_Box_Key; 17 | dan_public_key : Public_Box_Key; 18 | dan_secret_key : Secret_Box_Key; 19 | cipher_text : Sealed_Data (1 .. cipherlen); 20 | clear_text : String (1 .. message'Length); 21 | begin 22 | Generate_Box_Keys (bob_public_key, bob_secret_key); 23 | Generate_Box_Keys (dan_public_key, dan_secret_key); 24 | Put_Line ("Bob Public Key: " & As_Hexidecimal (bob_public_key)); 25 | Put_Line ("Bob Secret Key: " & As_Hexidecimal (bob_secret_key)); 26 | Put_Line ("Dan Public Key: " & As_Hexidecimal (dan_public_key)); 27 | 28 | cipher_text := Seal_Message (plain_text_message => message, 29 | recipient_public_key => bob_public_key); 30 | Put_Line ("CipherText (Anonymous): " & As_Hexidecimal (cipher_text)); 31 | 32 | clear_text := Unseal_Message (ciphertext => cipher_text, 33 | recipient_public_key => bob_public_key, 34 | recipient_secret_key => bob_secret_key); 35 | Put_Line ("Back again: " & clear_text); 36 | Put_Line ("Let Dan try to open it ..."); 37 | clear_text := Unseal_Message (ciphertext => cipher_text, 38 | recipient_public_key => dan_public_key, 39 | recipient_secret_key => dan_secret_key); 40 | end; 41 | end Demo_Ada; 42 | -------------------------------------------------------------------------------- /examples/signatures/demo-c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sodium.h" 3 | 4 | #define MESSAGE (const unsigned char *) "JRM wrote this note." 5 | #define MESSAGE_LEN 20 6 | 7 | int main () { 8 | unsigned char pk[crypto_sign_PUBLICKEYBYTES]; 9 | unsigned char sk[crypto_sign_SECRETKEYBYTES]; 10 | 11 | if (sodium_init() != 0) { 12 | return -1; 13 | } 14 | 15 | crypto_sign_keypair(pk, sk); 16 | 17 | unsigned char sig[crypto_sign_BYTES]; 18 | crypto_sign_detached(sig, NULL, MESSAGE, MESSAGE_LEN, sk); 19 | 20 | size_t pk_maxlen = crypto_sign_PUBLICKEYBYTES * 2 + 1; 21 | size_t sk_maxlen = crypto_sign_SECRETKEYBYTES * 2 + 1; 22 | size_t sig_maxlen = crypto_sign_BYTES * 2 + 1; 23 | size_t seed_maxlen = crypto_sign_SEEDBYTES * 2 + 1; 24 | 25 | unsigned char pk_hex[pk_maxlen]; 26 | unsigned char sk_hex[sk_maxlen]; 27 | unsigned char sig_hex[sig_maxlen]; 28 | unsigned char seed_hex[seed_maxlen]; 29 | 30 | sodium_bin2hex (pk_hex, pk_maxlen, pk, crypto_sign_PUBLICKEYBYTES); 31 | sodium_bin2hex (sk_hex, sk_maxlen, sk, crypto_sign_SECRETKEYBYTES); 32 | sodium_bin2hex (sig_hex, sig_maxlen, sig, crypto_sign_BYTES); 33 | 34 | printf ("Public Key: %s\n", pk_hex); 35 | printf ("Secret key: %s\n", sk_hex); 36 | printf ("Signature: %s\n", sig_hex); 37 | 38 | if (crypto_sign_verify_detached(sig, MESSAGE, MESSAGE_LEN, pk) == 0) 39 | printf ("Signature matches.\n"); 40 | else 41 | printf ("Signature does NOT match.\n"); 42 | 43 | printf ("\nAgain, but generate key with a seed.\n"); 44 | unsigned char seed[crypto_sign_SEEDBYTES]; 45 | randombytes_buf (seed, crypto_sign_SEEDBYTES); 46 | 47 | crypto_sign_seed_keypair(pk, sk, seed); 48 | crypto_sign_detached(sig, NULL, MESSAGE, MESSAGE_LEN, sk); 49 | sodium_bin2hex (pk_hex, pk_maxlen, pk, crypto_sign_PUBLICKEYBYTES); 50 | sodium_bin2hex (sk_hex, sk_maxlen, sk, crypto_sign_SECRETKEYBYTES); 51 | sodium_bin2hex (sig_hex, sig_maxlen, sig, crypto_sign_BYTES); 52 | sodium_bin2hex (seed_hex, seed_maxlen, seed, crypto_sign_SEEDBYTES); 53 | 54 | printf ("Seed: %s\n", seed_hex); 55 | printf ("Public Key: %s\n", pk_hex); 56 | printf ("Secret key: %s\n", sk_hex); 57 | printf ("Signature: %s\n", sig_hex); 58 | 59 | if (crypto_sign_verify_detached(sig, MESSAGE, MESSAGE_LEN, pk) == 0) 60 | printf ("Signature matches.\n"); 61 | else 62 | printf ("Signature does NOT match.\n"); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /examples/signatures/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada", "C"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo-c.c", "demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/signatures/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "JRM wrote this note."; 7 | begin 8 | if not initialize_sodium_library then 9 | Put_Line ("Initialization failed"); 10 | return; 11 | end if; 12 | 13 | declare 14 | new_public_sign_key : Public_Sign_Key; 15 | new_secret_sign_key : Secret_Sign_Key; 16 | new_signature_seed : Sign_Key_Seed := Random_Sign_Key_seed; 17 | new_signature : Signature; 18 | begin 19 | Generate_Sign_Keys (new_public_sign_key, new_secret_sign_key); 20 | Put_Line ("Public Key: " & As_Hexidecimal (new_public_sign_key)); 21 | Put_Line ("Secret Key: " & As_Hexidecimal (new_secret_sign_key)); 22 | 23 | new_signature := Obtain_Signature (message, new_secret_sign_key); 24 | Put_Line ("Signature: " & As_Hexidecimal (new_signature)); 25 | 26 | if Signature_Matches (message, new_signature, new_public_sign_key) then 27 | Put_Line ("Signature matches."); 28 | else 29 | Put_Line ("Signature does NOT match."); 30 | end if; 31 | 32 | Put_Line (""); 33 | Put_Line ("Again, but generate key with a seed"); 34 | Generate_Sign_Keys (new_public_sign_key, new_secret_sign_key, new_signature_seed); 35 | Put_Line ("Seed: " & As_Hexidecimal (new_signature_seed)); 36 | Put_Line ("Public Key: " & As_Hexidecimal (new_public_sign_key)); 37 | Put_Line ("Secret Key: " & As_Hexidecimal (new_secret_sign_key)); 38 | 39 | new_signature := Obtain_Signature (message, new_secret_sign_key); 40 | Put_Line ("Signature: " & As_Hexidecimal (new_signature)); 41 | 42 | if Signature_Matches (message, new_signature, new_public_sign_key) then 43 | Put_Line ("Signature matches."); 44 | else 45 | Put_Line ("Signature does NOT match."); 46 | end if; 47 | end; 48 | 49 | end Demo_Ada; 50 | -------------------------------------------------------------------------------- /examples/symmetric_encryption/demo.gpr: -------------------------------------------------------------------------------- 1 | with "../common.gpr"; 2 | 3 | project Demo is 4 | 5 | for Languages use ("Ada"); 6 | for Object_Dir use "build"; 7 | for Exec_Dir use "run"; 8 | for Main use ("demo_ada.adb"); 9 | for Source_Dirs use (".", "../../Binding_Sodium"); 10 | 11 | package Compiler renames Common.Compiler; 12 | package Linker renames Common.Linker; 13 | 14 | end Demo; 15 | -------------------------------------------------------------------------------- /examples/symmetric_encryption/demo_ada.adb: -------------------------------------------------------------------------------- 1 | with Sodium.Functions; use Sodium.Functions; 2 | with Ada.Text_IO; use Ada.Text_IO; 3 | 4 | procedure Demo_Ada 5 | is 6 | message : constant String := "From Russia with love."; 7 | cipherlen : constant Positive := Symmetric_Cipher_Length (message); 8 | begin 9 | if not initialize_sodium_library then 10 | Put_Line ("Initialization failed"); 11 | return; 12 | end if; 13 | 14 | declare 15 | secret_key : Symmetric_Key := Random_Symmetric_Key; 16 | second_key : Symmetric_Key := Random_Symmetric_Key; 17 | first_nonce : Symmetric_Nonce := Random_Symmetric_Nonce; 18 | cipher_text : Encrypted_Data (1 .. cipherlen); 19 | clear_text : String (1 .. message'Length); 20 | begin 21 | Put_Line ("Secret Key: " & As_Hexidecimal (secret_key)); 22 | Put_Line ("Second Key: " & As_Hexidecimal (second_key)); 23 | 24 | cipher_text := Symmetric_Encrypt (clear_text => message, 25 | secret_key => secret_key, 26 | unique_nonce => first_nonce); 27 | 28 | Put_Line ("CipherText: " & As_Hexidecimal (cipher_text)); 29 | 30 | clear_text := Symmetric_Decrypt (ciphertext => cipher_text, 31 | secret_key => secret_key, 32 | unique_nonce => first_nonce); 33 | 34 | Put_Line ("Back again: " & clear_text); 35 | Put ("Let another key try to open it ... "); 36 | begin 37 | clear_text := Symmetric_Decrypt (ciphertext => cipher_text, 38 | secret_key => second_key, 39 | unique_nonce => first_nonce); 40 | exception 41 | when others => Put_Line ("That failed as expected."); 42 | end; 43 | Put_Line ("Now use the original key after slightly altering the cipher text ..."); 44 | cipher_text (10) := 'Z'; 45 | clear_text := Symmetric_Decrypt (ciphertext => cipher_text, 46 | secret_key => secret_key, 47 | unique_nonce => first_nonce); 48 | end; 49 | end Demo_Ada; 50 | --------------------------------------------------------------------------------