1 // This file is dual-licensed.  Choose whichever licence you want from
2 // the two licences listed below.
3 //
4 // The first licence is a regular 2-clause BSD licence.  The second licence
5 // is the CC-0 from Creative Commons. It is intended to release Monocypher
6 // to the public domain.  The BSD licence serves as a fallback option.
7 //
8 // SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
9 //
10 // ------------------------------------------------------------------------
11 //
12 // Copyright (c) 2020, Loup Vaillant
13 // All rights reserved.
14 //
15 //
16 // Redistribution and use in source and binary forms, with or without
17 // modification, are permitted provided that the following conditions are
18 // met:
19 //
20 // 1. Redistributions of source code must retain the above copyright
21 //    notice, this list of conditions and the following disclaimer.
22 //
23 // 2. Redistributions in binary form must reproduce the above copyright
24 //    notice, this list of conditions and the following disclaimer in the
25 //    documentation and/or other materials provided with the
26 //    distribution.
27 //
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 //
40 // ------------------------------------------------------------------------
41 //
42 // Written in 2020 by Loup Vaillant
43 //
44 // To the extent possible under law, the author(s) have dedicated all copyright
45 // and related neighboring rights to this software to the public domain
46 // worldwide.  This software is distributed without any warranty.
47 //
48 // You should have received a copy of the CC0 Public Domain Dedication along
49 // with this software.  If not, see
50 // <https://creativecommons.org/publicdomain/zero/1.0/>
51 
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include "monocypher.h"
56 #include "monocypher-ed25519.h"
57 #include "utils.h"
58 
verify16()59 static void verify16()
60 {
61     u8 a[16];
62     u8 b[16];
63     crypto_verify16(a, b);
64 }
65 
verify32()66 static void verify32()
67 {
68     u8 a[32];
69     u8 b[32];
70     crypto_verify32(a, b);
71 }
72 
verify64()73 static void verify64()
74 {
75     u8 a[64];
76     u8 b[64];
77     crypto_verify64(a, b);
78 }
79 
wipe()80 static void wipe()
81 {
82     FOR (i, 0, 128) {
83         u8 secret[128];
84         crypto_wipe(secret, i);
85     }
86 }
87 
lock_aead()88 static void lock_aead()
89 {
90     FOR(i, 0, 128) {
91         u8 mac        [ 16];
92         u8 cipher_text[128];
93         u8 key        [ 32];
94         u8 nonce      [ 24];
95         u8 ad         [128];
96         u8 plain_text [128];
97         crypto_lock_aead(mac, cipher_text, key, nonce, ad, i, plain_text, i);
98     }
99 }
100 
unlock_aead()101 static void unlock_aead()
102 {
103     FOR(i, 0, 128) {
104         u8 plain_text [128];
105         u8 key        [ 32];
106         u8 nonce      [ 24];
107         u8 mac        [ 16];
108         u8 ad         [128];
109         u8 cipher_text[128];
110         crypto_unlock_aead(plain_text, key, nonce, mac, ad, i, cipher_text, i);
111     }
112 }
113 
blake2b_general()114 static void blake2b_general()
115 {
116     FOR (i, 0, 256) {
117         u8 hash   [ 64];
118         u8 key    [ 64];
119         u8 message[256];
120         crypto_blake2b_general(hash, 64, key, 0, message, i);
121     }
122     FOR (i, 0, 64) {
123         u8 hash   [ 64];
124         u8 key    [ 64];
125         u8 message[256];
126         crypto_blake2b_general(hash, 64, key, i, message, 128);
127     }
128     FOR (i, 0, 64) {
129         u8 hash   [ 64];
130         u8 key    [ 64];
131         u8 message[256];
132         crypto_blake2b_general(hash, i, key, 0, message, 0);
133     }
134 }
135 
argon2i_general()136 static void argon2i_general()
137 {
138     void *work_area = alloc(1024 * 600);
139     u8    hash    [ 32];
140     u8    password[ 16];
141     u8    salt    [ 16];
142     u8    key     [ 32];
143     u8    ad      [128];
144     crypto_argon2i_general(hash, 32, work_area, 600, 3,
145                            password, 16, salt, 16, key, 32, ad, 128);
146     free(work_area);
147 }
148 
key_exchange()149 static void key_exchange()
150 {
151     u8 shared_key      [32];
152     u8 your_secret_key [32];
153     u8 their_public_key[32];
154     crypto_key_exchange(shared_key, your_secret_key, their_public_key);
155 }
156 
sign_public_key()157 static void sign_public_key()
158 {
159     u8  public_key[32];
160     u8  secret_key[32];
161     crypto_sign_public_key(public_key, secret_key);
162 }
163 
sign()164 static void sign()
165 {
166     u8  signature [64];
167     u8  secret_key[32];
168     u8  public_key[32];
169     u8  message   [64];
170     crypto_sign(signature, secret_key, public_key, message, 64);
171 }
172 
from_eddsa_private()173 static void from_eddsa_private()
174 {
175     u8 x25519[32];
176     u8 eddsa [32];
177     crypto_from_eddsa_private(x25519, eddsa);
178 }
from_eddsa_public()179 static void from_eddsa_public()
180 {
181     u8 x25519[32];
182     u8 eddsa [32];
183     crypto_from_eddsa_public(x25519, eddsa);
184 }
185 
hidden_to_curve()186 static void hidden_to_curve()
187 {
188     u8 curve [32];
189     u8 hidden[32];
190     crypto_hidden_to_curve(curve, hidden);
191 }
192 
curve_to_hidden()193 static void curve_to_hidden()
194 {
195     u8 hidden[32];
196     u8 curve [32];
197     u8 tweak; // The compiler notices this one is used uninitialised
198     crypto_curve_to_hidden(hidden, curve, tweak);
199 }
200 
hidden_key_pair()201 static void hidden_key_pair()
202 {
203     u8 hidden    [32];
204     u8 secret_key[32];
205     u8 seed      [32];
206     crypto_hidden_key_pair(hidden, secret_key,seed);
207 }
208 
h_chacha20()209 static void h_chacha20()
210 {
211     u8 out[32], key[32], in[16];
212     crypto_hchacha20(out, key, in);
213 }
214 
chacha20()215 static void chacha20()
216 {
217     FOR (i, 0, 128) {
218         u8 cipher_text[128];
219         u8 plain_text [128];
220         u8 key        [ 32];
221         u8 nonce      [  8];
222         crypto_chacha20(cipher_text, plain_text, i,  key, nonce);
223     }
224 }
xchacha20()225 static void xchacha20()
226 {
227     FOR (i, 0, 128) {
228         u8 cipher_text[128];
229         u8 plain_text [128];
230         u8 key        [ 32];
231         u8 nonce      [ 24];
232         crypto_xchacha20(cipher_text, plain_text, i,  key, nonce);
233     }
234 }
ietf_chacha20()235 static void ietf_chacha20()
236 {
237     FOR (i, 0, 128) {
238         u8 cipher_text[128];
239         u8 plain_text [128];
240         u8 key        [ 32];
241         u8 nonce      [ 12];
242         crypto_ietf_chacha20(cipher_text, plain_text, i,  key, nonce);
243     }
244 }
245 
poly1305()246 static void poly1305()
247 {
248     FOR (i, 0, 32) {
249         u8 mac     [16];
250         u8 message [32];
251         u8 key     [32];
252         crypto_poly1305(mac, message, i, key);
253     }
254 }
255 
x25519_dirty_small()256 static void x25519_dirty_small()
257 {
258     u8 pk[32];
259     u8 sk[32];
260     crypto_x25519_dirty_small(pk, sk);
261 }
x25519_dirty_fast()262 static void x25519_dirty_fast()
263 {
264     u8 pk[32];
265     u8 sk[32];
266     crypto_x25519_dirty_fast(pk, sk);
267 }
268 
x25519_inverse()269 static void x25519_inverse()
270 {
271     u8 blind_salt [32];
272     u8 private_key[32];
273     u8 curve_point[32];
274     crypto_x25519_inverse(blind_salt, private_key, curve_point);
275 }
276 
277 
278 #define RUN(f, s) printf("%s: crypto_"#f"\n", s); f()
279 
main()280 int main()
281 {
282     RUN(verify16          , "constant time");
283     RUN(verify32          , "constant time");
284     RUN(verify64          , "constant time");
285     RUN(wipe              , "constant time");
286     RUN(lock_aead         , "constant time");
287     RUN(unlock_aead       , "1 conditional");
288     RUN(blake2b_general   , "constant time");
289     RUN(argon2i_general   , "constant time");
290     RUN(key_exchange      , "constant time");
291     RUN(sign_public_key   , "constant time");
292     RUN(sign              , "constant time");
293     printf(                 "skipped      : crypto_check.\n");
294     RUN(from_eddsa_private, "constant time");
295     RUN(from_eddsa_public , "constant time");
296     RUN(hidden_to_curve   , "constant time");
297     RUN(curve_to_hidden   , "1 conditional");
298     RUN(hidden_key_pair   , "1 conditional"); // shouldn't that be 2?
299     RUN(h_chacha20        , "constant time");
300     RUN(chacha20          , "constant time");
301     RUN(xchacha20         , "constant time");
302     RUN(ietf_chacha20     , "constant time");
303     RUN(poly1305          , "constant time");
304     RUN(x25519_dirty_small, "constant time");
305     RUN(x25519_dirty_fast , "constant time");
306     RUN(x25519_inverse    , "constant time");
307 
308     return 0;
309 }
310