1 // Written in the D programming language.
2 
3 module wrapper.sodium.crypto_auth_hmacsha512;
4 
5 import wrapper.sodium.core; // assure sodium got initialized
6 
7 public
8 import  deimos.sodium.crypto_auth_hmacsha512 : crypto_auth_hmacsha512_BYTES,
9                                                crypto_auth_hmacsha512_bytes,
10                                                crypto_auth_hmacsha512_KEYBYTES,
11                                                crypto_auth_hmacsha512_keybytes,
12 /*                                             crypto_auth_hmacsha512,
13                                                crypto_auth_hmacsha512_verify,  */
14                                                crypto_auth_hmacsha512_state,
15                                                crypto_auth_hmacsha512_statebytes,
16 /*                                             crypto_auth_hmacsha512_init,
17                                                crypto_auth_hmacsha512_update,
18                                                crypto_auth_hmacsha512_final,   */
19                                                crypto_auth_hmacsha512_keygen;
20 
21 
22 // overloading some functions between module deimos.sodium.crypto_auth_hmacsha512 and this module
23 
24 alias  crypto_auth_hmacsha512        = deimos.sodium.crypto_auth_hmacsha512.crypto_auth_hmacsha512;
25 alias  crypto_auth_hmacsha512_verify = deimos.sodium.crypto_auth_hmacsha512.crypto_auth_hmacsha512_verify;
26 alias  crypto_auth_hmacsha512_init   = deimos.sodium.crypto_auth_hmacsha512.crypto_auth_hmacsha512_init;
27 alias  crypto_auth_hmacsha512_update = deimos.sodium.crypto_auth_hmacsha512.crypto_auth_hmacsha512_update;
28 alias  crypto_auth_hmacsha512_final  = deimos.sodium.crypto_auth_hmacsha512.crypto_auth_hmacsha512_final;
29 
30 
31 pragma(inline, true)  @nogc pure @trusted
32 {
33 /**
34  * The crypto_auth_hmacsha512() function authenticates a message `message` using the secret	key skey,
35  * and puts the	authenticator	into mac.
36  * Returns 0? on success.
37  */
38 bool crypto_auth_hmacsha512(out ubyte[crypto_auth_hmacsha512_BYTES] mac,
39                            scope const ubyte[] message,
40                            const ubyte[crypto_auth_hmacsha512_KEYBYTES] skey)
41 {
42   return  crypto_auth_hmacsha512(mac.ptr, message.ptr, message.length, skey.ptr) == 0;
43 }
44 
45 /**
46  * The crypto_auth_hmacsha512_verify() function	verifies in constant time that h is a correct
47  * authenticator for the message in whose length is inlen under a secret key k.
48  * It returns -1  if the verification fails, and 0 on success.
49  */
50 bool crypto_auth_hmacsha512_verify(const ubyte[crypto_auth_hmacsha512_BYTES] mac,
51                                    scope const ubyte[] message,
52                                    const ubyte[crypto_auth_hmacsha512_KEYBYTES] skey) nothrow
53 {
54   return  crypto_auth_hmacsha512_verify(mac.ptr, message.ptr, message.length, skey.ptr) == 0;
55 }
56 
57 /**
58  * This alternative API supports a key of arbitrary length
59  */
60 bool crypto_auth_hmacsha512_init(out crypto_auth_hmacsha512_state state,
61                                  scope const ubyte[] skey)
62 {
63   return  crypto_auth_hmacsha512_init(&state, skey.ptr, skey.length) == 0;
64 }
65 
66 bool crypto_auth_hmacsha512_update(ref crypto_auth_hmacsha512_state state,
67                                    scope const ubyte[] in_)
68 {
69   return  crypto_auth_hmacsha512_update(&state, in_.ptr, in_.length) == 0;
70 }
71 
72 bool crypto_auth_hmacsha512_final(ref crypto_auth_hmacsha512_state state,
73                                   out ubyte[crypto_auth_hmacsha512_BYTES] out_)
74 {
75   return  crypto_auth_hmacsha512_final(&state, out_.ptr) == 0;
76 }
77 } //pragma(inline, true)  pure @nogc @trusted
78 
79 
80 @safe
81 unittest
82 {
83   import std.stdio : writeln;
84   import std..string : representation;
85   import wrapper.sodium.randombytes : randombytes;
86 
87   debug writeln("unittest block 1 from sodium.crypto_auth_hmacsha512.d");
88 
89   assert(crypto_auth_hmacsha512_bytes()      == crypto_auth_hmacsha512_BYTES);
90   assert(crypto_auth_hmacsha512_keybytes()   == crypto_auth_hmacsha512_KEYBYTES);
91   assert(crypto_auth_hmacsha512_statebytes() == crypto_auth_hmacsha512_state.sizeof);   // 416
92 //  writeln("crypto_auth_hmacsha512_statebytes(): ", crypto_auth_hmacsha512_statebytes());   // 416
93 //  writeln("crypto_auth_hmacsha512_state.sizeof: ", crypto_auth_hmacsha512_state.sizeof);   // 416 = 2*crypto_hash_sha512_state.sizeof
94 
95   auto                                   message  = representation("test some more text");
96   auto                                   message2 = representation(" some more text");
97   ubyte[crypto_auth_hmacsha512_KEYBYTES] skey;
98   ubyte[crypto_auth_hmacsha512_BYTES]    mac;
99 
100   randombytes(skey);
101   assert(crypto_auth_hmacsha512(mac, message, skey));
102   assert(crypto_auth_hmacsha512_verify(mac, message, skey));
103   ubyte[crypto_auth_hmacsha512_BYTES]    mac_saved = mac;
104 
105   message  = representation("test");
106   crypto_auth_hmacsha512_state state;
107   assert(crypto_auth_hmacsha512_init  (state, skey));
108   assert(crypto_auth_hmacsha512_update(state, message));
109   assert(crypto_auth_hmacsha512_update(state, message2));
110   assert(crypto_auth_hmacsha512_final (state, mac));
111   message  = representation("test some more text");
112   assert(crypto_auth_hmacsha512_verify(mac, message, skey));
113   assert(mac == mac_saved);
114   ubyte[crypto_auth_hmacsha512_KEYBYTES] k;
115   crypto_auth_hmacsha512_keygen(k);
116 }