1 // Written in the D programming language. 2 3 module wrapper.sodium.crypto_kdf; 4 5 import wrapper.sodium.core; // assure sodium got initialized 6 7 public 8 import deimos.sodium.crypto_kdf : crypto_kdf_BYTES_MIN, 9 crypto_kdf_bytes_min, 10 crypto_kdf_BYTES_MAX, 11 crypto_kdf_bytes_max, 12 crypto_kdf_CONTEXTBYTES, 13 crypto_kdf_contextbytes, 14 crypto_kdf_KEYBYTES, 15 crypto_kdf_keybytes, 16 crypto_kdf_PRIMITIVE, 17 /* crypto_kdf_primitive, 18 crypto_kdf_derive_from_key, */ 19 crypto_kdf_keygen; 20 21 22 string crypto_kdf_primitive() pure nothrow @nogc @trusted 23 { 24 import std..string : fromStringz; 25 static import deimos.sodium.crypto_kdf; 26 return fromStringz(deimos.sodium.crypto_kdf.crypto_kdf_primitive()); // strips terminating \0 27 } 28 29 /* overload */ 30 31 alias crypto_kdf_derive_from_key = deimos.sodium.crypto_kdf.crypto_kdf_derive_from_key; 32 33 pragma(inline, true) 34 bool crypto_kdf_derive_from_key(scope ubyte[] subkey, 35 const ulong subkey_id, 36 const char[crypto_kdf_CONTEXTBYTES] ctx, 37 const ubyte[crypto_kdf_KEYBYTES] key) @nogc @trusted 38 { 39 import nogc.exception: enforce; 40 // enforce(subkey.length>=crypto_kdf_BYTES_MIN && subkey.length<=crypto_kdf_BYTES_MAX, 41 // "Expected subkey.length: ", subkey.length, " to be greater-equal to crypto_kdf_BYTES_MIN: ", crypto_kdf_BYTES_MIN, " and less-equal to crypto_kdf_BYTES_MAX: ", crypto_kdf_BYTES_MAX); 42 enforce(subkey.length>=crypto_kdf_BYTES_MIN && subkey.length<=crypto_kdf_BYTES_MAX, 43 "Expected subkey.length is not greater-equal to crypto_kdf_BYTES_MIN and not less-equal to crypto_kdf_BYTES_MAX"); 44 return crypto_kdf_derive_from_key(subkey.ptr, subkey.length, subkey_id, ctx, key) == 0; 45 } 46 47 @safe 48 unittest { 49 import std.stdio : writeln; 50 debug writeln("unittest block 1 from sodium.crypto_kdf.d"); 51 } 52 53 @nogc @safe 54 unittest { 55 assert(crypto_kdf_bytes_min() == crypto_kdf_BYTES_MIN); 56 assert(crypto_kdf_bytes_max() == crypto_kdf_BYTES_MAX); 57 assert(crypto_kdf_contextbytes() == crypto_kdf_CONTEXTBYTES); 58 assert(crypto_kdf_keybytes() == crypto_kdf_keybytes); 59 assert(crypto_kdf_primitive() == crypto_kdf_PRIMITIVE); 60 61 char[crypto_kdf_CONTEXTBYTES] context = "Examples"; 62 ubyte[crypto_kdf_KEYBYTES] master_key; 63 ubyte[32] subkey1; 64 ubyte[32] subkey2; 65 ubyte[64] subkey3; 66 crypto_kdf_keygen(master_key); 67 assert(crypto_kdf_derive_from_key(subkey1, 1, context, master_key)); 68 assert(crypto_kdf_derive_from_key(subkey2, 2, context, master_key)); 69 assert(crypto_kdf_derive_from_key(subkey3, 3, context, master_key)); 70 } 71 72 @safe 73 unittest { 74 import std.exception : assertThrown; 75 76 char[crypto_kdf_CONTEXTBYTES] context = "Examples"; 77 ubyte[crypto_kdf_KEYBYTES] master_key; 78 crypto_kdf_keygen(master_key); 79 ubyte[15] subkey4; 80 ubyte[65] subkey5; 81 assertThrown(crypto_kdf_derive_from_key(subkey4, 4, context, master_key)); 82 assertThrown(crypto_kdf_derive_from_key(subkey5, 5, context, master_key)); 83 ubyte[crypto_kdf_KEYBYTES] master_key2; 84 crypto_kdf_keygen(master_key2); 85 assert(master_key != master_key2); 86 ubyte[32] subkey1; 87 ubyte[32] subkey2; 88 assert(crypto_kdf_derive_from_key(subkey1, 1, context, master_key)); 89 assert(crypto_kdf_derive_from_key(subkey2, 1, context, master_key)); 90 assert(subkey1 == subkey2); 91 assert(crypto_kdf_derive_from_key(subkey2, 2, context, master_key)); 92 assert(subkey1 != subkey2); 93 }