1 // Written in the D programming language.
2 
3 module wrapper.sodium.crypto_auth_hmacsha256;
4 
5 import wrapper.sodium.core; // assure sodium got initialized
6 
7 public
8 import  deimos.sodium.crypto_auth_hmacsha256 : crypto_auth_hmacsha256_BYTES,
9                                                crypto_auth_hmacsha256_bytes,
10                                                crypto_auth_hmacsha256_KEYBYTES,
11                                                crypto_auth_hmacsha256_keybytes,
12 /*                                             crypto_auth_hmacsha256,
13                                                crypto_auth_hmacsha256_verify,  */
14                                                crypto_auth_hmacsha256_state,
15                                                crypto_auth_hmacsha256_statebytes,
16 /*                                             crypto_auth_hmacsha256_init,
17                                                crypto_auth_hmacsha256_update,
18                                                crypto_auth_hmacsha256_final,     */
19                                                crypto_auth_hmacsha256_keygen;
20 
21 
22 // overloading some functions between module deimos.sodium.crypto_auth_hmacsha256 and this module
23 
24 alias  crypto_auth_hmacsha256        = deimos.sodium.crypto_auth_hmacsha256.crypto_auth_hmacsha256;
25 alias  crypto_auth_hmacsha256_verify = deimos.sodium.crypto_auth_hmacsha256.crypto_auth_hmacsha256_verify;
26 alias  crypto_auth_hmacsha256_init   = deimos.sodium.crypto_auth_hmacsha256.crypto_auth_hmacsha256_init;
27 alias  crypto_auth_hmacsha256_update = deimos.sodium.crypto_auth_hmacsha256.crypto_auth_hmacsha256_update;
28 alias  crypto_auth_hmacsha256_final  = deimos.sodium.crypto_auth_hmacsha256.crypto_auth_hmacsha256_final;
29 
30 
31 pragma(inline, true)  @nogc pure @trusted
32 {
33 
34 /**
35  * The crypto_auth_hmacsha256() function authenticates a message `message` using the secret key `skey`,
36  * and puts the authenticator into `mac`.
37  * It returns true on success.
38  */
39 bool crypto_auth_hmacsha256(out ubyte[crypto_auth_hmacsha256_BYTES] mac,
40                             scope const ubyte[] message,
41                             const ubyte[crypto_auth_hmacsha256_KEYBYTES] skey)
42 {
43   return  crypto_auth_hmacsha256(mac.ptr, message.ptr, message.length, skey.ptr) == 0;
44 }
45 
46 /**
47  * The crypto_auth_hmacsha256_verify() function verifies in constant time that `mac` is a correct
48  * authenticator for the message `message` under a secret key `skey`.
49  * It returns true on success of verification.
50 
51  */
52 bool crypto_auth_hmacsha256_verify(const ubyte[crypto_auth_hmacsha256_BYTES] mac,
53                                    scope const ubyte[] message,
54                                    const ubyte[crypto_auth_hmacsha256_KEYBYTES] skey) nothrow
55 {
56   return  crypto_auth_hmacsha256_verify(mac.ptr, message.ptr, message.length, skey.ptr) == 0;
57 }
58 
59 /** This alternative API supports a key of arbitrary length */
60 bool crypto_auth_hmacsha256_init(out crypto_auth_hmacsha256_state state,
61                                  scope const ubyte[] skey)
62 {
63   return  crypto_auth_hmacsha256_init(&state, skey.ptr, skey.length) == 0;
64 }
65 
66 bool crypto_auth_hmacsha256_update(ref crypto_auth_hmacsha256_state state,
67                                    scope const ubyte[] in_)
68 {
69   return  crypto_auth_hmacsha256_update(&state, in_.ptr, in_.length) == 0;
70 }
71 
72 bool crypto_auth_hmacsha256_final(ref crypto_auth_hmacsha256_state state,
73                                   out ubyte[crypto_auth_hmacsha256_BYTES] out_)
74 {
75   return  crypto_auth_hmacsha256_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_hmacsha256.d");
88 
89   assert(crypto_auth_hmacsha256_bytes()      == crypto_auth_hmacsha256_BYTES);
90   assert(crypto_auth_hmacsha256_keybytes()   == crypto_auth_hmacsha256_KEYBYTES);
91 //  assert(crypto_auth_hmacsha256_statebytes() == crypto_auth_hmacsha256_state.sizeof);
92 //  writeln("crypto_auth_hmacsha256_statebytes(): ", crypto_auth_hmacsha256_statebytes());   // 208
93 //  writeln("crypto_auth_hmacsha256_state.sizeof: ", crypto_auth_hmacsha256_state.sizeof); // 224 = 2*crypto_hash_sha256_state.sizeof
94 
95   auto                                   message  = representation("test some more text");
96   auto                                   message2 = representation(" some more text");
97   ubyte[crypto_auth_hmacsha256_KEYBYTES] skey;
98   ubyte[crypto_auth_hmacsha256_BYTES]    mac;
99 
100   randombytes(skey);
101   assert(crypto_auth_hmacsha256(mac, message, skey));
102   assert(crypto_auth_hmacsha256_verify(mac, message, skey));
103   ubyte[crypto_auth_hmacsha256_BYTES]    mac_saved = mac;
104 
105   message  = representation("test");
106   crypto_auth_hmacsha256_state state;
107   assert(crypto_auth_hmacsha256_init  (state, skey));
108   assert(crypto_auth_hmacsha256_update(state, message));
109   assert(crypto_auth_hmacsha256_update(state, message2));
110   assert(crypto_auth_hmacsha256_final (state, mac));
111   message  = representation("test some more text");
112   assert(crypto_auth_hmacsha256_verify(mac, message, skey));
113   assert(mac == mac_saved);
114   ubyte[crypto_auth_hmacsha256_KEYBYTES] k;
115   crypto_auth_hmacsha256_keygen(k);
116 }