Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/libecc/src/examples/sig/sdsa/sdsa.c
2066 views
1
/*
2
* Copyright (C) 2021 - This file is part of libecc project
3
*
4
* Authors:
5
* Ryad BENADJILA <[email protected]>
6
* Arnaud EBALARD <[email protected]>
7
*
8
* This software is licensed under a dual BSD and GPL v2 license.
9
* See LICENSE file at the root folder of the project.
10
*/
11
#include "sdsa.h"
12
13
14
/* We include the rand external dependency because we have to generate
15
* some random data for the nonces.
16
*/
17
#include <libecc/external_deps/rand.h>
18
/* We include the printf external dependency for printf output */
19
#include <libecc/external_deps/print.h>
20
/* We include our common helpers */
21
#include "../common/common.h"
22
23
/*
24
* The purpose of this example is to implement the Schnorr signature
25
* scheme (aka SDSA for Schnorr DSA) based on libecc arithmetic primitives.
26
* Many "variants" of Schnorr signature schemes exist, we implement here the
27
* one corresponding to SDSA as described in the ISO14888-3 standard.
28
*
29
* XXX: Please be aware that libecc has been designed for Elliptic
30
* Curve cryptography, and as so the arithmetic primitives are
31
* not optimized for big numbers >= 1024 bits usually used for SDSA.
32
* Additionnaly, a hard limit of our NN values makes it impossible
33
* to exceed ~5300 bits in the best case (words of size 64 bits).
34
*
35
* All in all, please see this as a proof of concept.
36
* Use it at your own risk!
37
*
38
* !! DISCLAIMER !!
39
* ================
40
*
41
* Althoug some efforts have been made to secure this implementation
42
* of Schnorr DSA (e.g. by protecting the private key and nonces using constant
43
* time and blinding WHEN activated with BLINDING=1), please consider this
44
* code as a proof of concept and use it at your own risk.
45
*
46
* All-in-all, this piece of code can be useful in some contexts, or risky to
47
* use in other sensitive ones where advanced side-channels or fault attacks
48
* have to be considered. Use this SDSA code knowingly and at your own risk!
49
*
50
*/
51
52
/* NOTE: since SDSA is very similar to DSA, we reuse some of our DSA
53
* primitives to factorize some code. Also, SDSA private and public keys
54
* have the exact same type as DSA keys.
55
*/
56
57
/* Import a SDSA private key from buffers */
58
int sdsa_import_priv_key(sdsa_priv_key *priv, const u8 *p, u16 plen,
59
const u8 *q, u16 qlen,
60
const u8 *g, u16 glen,
61
const u8 *x, u16 xlen)
62
{
63
return dsa_import_priv_key(priv, p, plen, q, qlen, g, glen, x, xlen);
64
}
65
66
/* Import a SDSA public key from buffers */
67
int sdsa_import_pub_key(sdsa_pub_key *pub, const u8 *p, u16 plen,
68
const u8 *q, u16 qlen,
69
const u8 *g, u16 glen,
70
const u8 *y, u16 ylen)
71
{
72
return dsa_import_pub_key(pub, p, plen, q, qlen, g, glen, y, ylen);
73
}
74
75
76
77
/* Compute a SDSA public key from a private key.
78
* The public key is computed using modular exponentiation of the generator
79
* with the private key.
80
*/
81
int sdsa_compute_pub_from_priv(sdsa_pub_key *pub, const sdsa_priv_key *priv)
82
{
83
return dsa_compute_pub_from_priv(pub, priv);
84
}
85
86
/* Generate a SDSA signature
87
*/
88
int sdsa_sign(const sdsa_priv_key *priv, const u8 *msg, u32 msglen,
89
const u8 *nonce, u16 noncelen,
90
u8 *sig, u16 siglen, gen_hash_alg_type sdsa_hash)
91
{
92
int ret, iszero;
93
/* alpha is the bit length of p, beta is the bit length of q */
94
bitcnt_t alpha, beta;
95
/* Length of the hash function (hlen is "gamma") */
96
u8 hlen, block_size;
97
nn_src_t p, q, g, x;
98
/* The nonce and its protected version */
99
nn k, k_;
100
/* r, s, pi */
101
nn r, s;
102
nn_t pi;
103
/* This is a bit too much for stack space, but we need it for
104
* the computation of "pi" I2BS representation ...
105
*/
106
u8 pi_buf[NN_USABLE_MAX_BYTE_LEN];
107
/* hash context */
108
gen_hash_context hash_ctx;
109
#ifdef USE_SIG_BLINDING
110
/* b is the blinding mask */
111
nn b;
112
b.magic = WORD(0);
113
#endif /* USE_SIG_BLINDING */
114
k.magic = k_.magic = r.magic = s.magic = WORD(0);
115
116
/* Sanity checks */
117
MUST_HAVE((priv != NULL) && (msg != NULL) && (sig != NULL), ret, err);
118
119
ret = local_memset(pi_buf, 0, sizeof(pi_buf)); EG(ret, err);
120
121
/* Make things more readable */
122
p = &(priv->p);
123
q = &(priv->q);
124
g = &(priv->g);
125
x = &(priv->x);
126
127
/* Sanity checks */
128
ret = nn_check_initialized(p); EG(ret, err);
129
ret = nn_check_initialized(q); EG(ret, err);
130
ret = nn_check_initialized(g); EG(ret, err);
131
ret = nn_check_initialized(x); EG(ret, err);
132
133
/* Let alpha be the bit length of p */
134
ret = nn_bitlen(p, &alpha); EG(ret, err);
135
/* Let beta be the bit length of q */
136
ret = nn_bitlen(q, &beta); EG(ret, err);
137
/* Get the hash sizes (8*"gamma") */
138
ret = gen_hash_get_hash_sizes(sdsa_hash, &hlen, &block_size); EG(ret, err);
139
MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
140
141
/* Sanity check on the signature length:
142
* the signature is of size hash function plus an integer modulo q
143
* "gamma" + beta
144
*/
145
MUST_HAVE((siglen == (hlen + BYTECEIL(beta))), ret, err);
146
147
restart:
148
/* If the nonce is imposed, use it. Else get a random modulo q */
149
if(nonce != NULL){
150
ret = _os2ip(&k, nonce, noncelen); EG(ret, err);
151
}
152
else{
153
ret = nn_get_random_mod(&k, q); EG(ret, err);
154
}
155
156
/* Fix the MSB of our scalar */
157
ret = nn_copy(&k_, &k); EG(ret, err);
158
#ifdef USE_SIG_BLINDING
159
/* Blind the scalar */
160
ret = _blind_scalar(&k_, q, &k_); EG(ret, err);
161
#endif /* USE_SIG_BLINDING */
162
ret = _fix_scalar_msb(&k_, q, &k_); EG(ret, err);
163
/* Use r as aliasing for pi to save some space */
164
pi = &r;
165
/* pi = (g**k mod p) */
166
ret = nn_init(pi, 0); EG(ret, err);
167
/* Exponentiation modulo p */
168
ret = nn_mod_pow(pi, g, &k_, p); EG(ret, err);
169
170
/* Compute I2BS(alpha, pi)
171
*/
172
ret = _i2osp(pi, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
173
174
/* r = h(I2BS(alpha, pi) || M) */
175
ret = gen_hash_init(&hash_ctx, sdsa_hash); EG(ret, err);
176
ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), sdsa_hash); EG(ret, err);
177
ret = gen_hash_update(&hash_ctx, msg, msglen, sdsa_hash); EG(ret, err);
178
/* Export r result of the hash function in sig */
179
ret = gen_hash_final(&hash_ctx, sig, sdsa_hash); EG(ret, err);
180
181
/* Import r as an integer modulo q */
182
ret = _os2ip(&r, sig, hlen); EG(ret, err);
183
ret = nn_mod(&r, &r, q); EG(ret, err);
184
185
/* If r is 0, restart the process */
186
ret = nn_iszero(&r, &iszero); EG(ret, err);
187
if (iszero) {
188
IGNORE_RET_VAL(local_memset(sig, 0, hlen));
189
goto restart;
190
}
191
192
#ifdef USE_SIG_BLINDING
193
/* Note: if we use blinding, r and k are multiplied by
194
* a random value b in ]0,q[ */
195
ret = nn_get_random_mod(&b, q); EG(ret, err);
196
/* Blind r with b */
197
ret = nn_mod_mul(&r, &r, &b, q); EG(ret, err);
198
/* Blind k with b */
199
ret = nn_mod_mul(&k, &k, &b, q); EG(ret, err);
200
/*
201
* In case of blinding, we compute b^-1 with
202
* little Fermat theorem. This will be used to
203
* unblind s.
204
*/
205
ret = nn_modinv_fermat(&b, &b, q); EG(ret, err);
206
#endif /* USE_SIG_BLINDING */
207
208
/* Compute s = (k + r x) mod q */
209
ret = nn_mod_mul(&s, &r, x, q); EG(ret, err);
210
ret = nn_mod_add(&s, &s, &k, q); EG(ret, err);
211
212
#ifdef USE_SIG_BLINDING
213
/* In case of blinding, unblind s */
214
ret = nn_mod_mul(&s, &s, &b, q); EG(ret, err);
215
#endif /* USE_SIG_BLINDING */
216
/* If s is 0, restart the process */
217
ret = nn_iszero(&s, &iszero); EG(ret, err);
218
if (iszero) {
219
goto restart;
220
}
221
222
/* Export s */
223
ret = _i2osp(&s, sig + hlen, (u16)(siglen - hlen)); EG(ret, err);
224
225
err:
226
if(ret && (sig != NULL)){
227
IGNORE_RET_VAL(local_memset(sig, 0, siglen));
228
}
229
230
nn_uninit(&k);
231
nn_uninit(&k_);
232
#ifdef USE_SIG_BLINDING
233
nn_uninit(&b);
234
#endif
235
nn_uninit(&r);
236
nn_uninit(&s);
237
238
PTR_NULLIFY(pi);
239
240
PTR_NULLIFY(p);
241
PTR_NULLIFY(q);
242
PTR_NULLIFY(g);
243
PTR_NULLIFY(x);
244
245
return ret;
246
}
247
248
249
250
/* Verify a SDSA signature
251
*/
252
int sdsa_verify(const sdsa_pub_key *pub, const u8 *msg, u32 msglen,
253
const u8 *sig, u16 siglen, gen_hash_alg_type sdsa_hash)
254
{
255
int ret, iszero, cmp;
256
/* alpha is the bit length of p, beta is the bit length of q */
257
bitcnt_t alpha, beta;
258
/* Length of the hash function */
259
u8 hlen, block_size;
260
nn_src_t p, q, g, y;
261
/* r, s */
262
nn r, s;
263
/* u, and pi */
264
nn u, pi;
265
/* This is a bit too much for stack space, but we need it for
266
* the computation of "pi" I2BS representation ...
267
*/
268
u8 pi_buf[NN_USABLE_MAX_BYTE_LEN];
269
/* Hash */
270
u8 hash[MAX_DIGEST_SIZE];
271
/* hash context */
272
gen_hash_context hash_ctx;
273
r.magic = s.magic = u.magic = pi.magic = WORD(0);
274
275
/* Sanity checks */
276
MUST_HAVE((pub != NULL) && (msg != NULL) && (sig != NULL), ret, err);
277
278
ret = local_memset(pi_buf, 0, sizeof(pi_buf)); EG(ret, err);
279
ret = local_memset(hash, 0, sizeof(hash)); EG(ret, err);
280
281
/* Make things more readable */
282
p = &(pub->p);
283
q = &(pub->q);
284
g = &(pub->g);
285
y = &(pub->y);
286
287
/* Sanity checks */
288
ret = nn_check_initialized(p); EG(ret, err);
289
ret = nn_check_initialized(q); EG(ret, err);
290
ret = nn_check_initialized(g); EG(ret, err);
291
ret = nn_check_initialized(y); EG(ret, err);
292
293
/* Let alpha be the bit length of p */
294
ret = nn_bitlen(p, &alpha); EG(ret, err);
295
/* Let beta be the bit length of q */
296
ret = nn_bitlen(q, &beta); EG(ret, err);
297
/* Get the hash sizes (8*"gamma") */
298
ret = gen_hash_get_hash_sizes(sdsa_hash, &hlen, &block_size); EG(ret, err);
299
MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
300
301
/* Sanity check on the signature length */
302
MUST_HAVE((siglen == (hlen + BYTECEIL(beta))), ret, err);
303
304
/* Extract r and s */
305
ret = _os2ip(&r, sig, hlen); EG(ret, err);
306
ret = _os2ip(&s, sig + hlen, (u16)(siglen - hlen)); EG(ret, err);
307
308
/* Return an error if r = 0 or s = 0 */
309
ret = nn_iszero(&r, &iszero); EG(ret, err);
310
MUST_HAVE((!iszero), ret, err);
311
ret = nn_iszero(&s, &iszero); EG(ret, err);
312
MUST_HAVE((!iszero), ret, err);
313
/* Check that 0 < s < q */
314
ret = nn_cmp(&s, q, &cmp); EG(ret, err);
315
MUST_HAVE((cmp < 0), ret, err);
316
317
/* Take r modulo q */
318
ret = nn_mod(&r, &r, q); EG(ret, err);
319
320
/* Initialize internal variables */
321
ret = nn_init(&u, 0); EG(ret, err);
322
ret = nn_init(&pi, 0); EG(ret, err);
323
324
/* NOTE: no need to use a secure exponentiation here as we only
325
* manipulate public data.
326
*/
327
/* Compute (y ** -r) mod (p) */
328
ret = nn_sub(&r, q, &r); EG(ret, err); /* compute -r = (q - r) mod q */
329
ret = _nn_mod_pow_insecure(&u, y, &r, p); EG(ret, err);
330
/* Compute (g ** s) mod (p) */
331
ret = _nn_mod_pow_insecure(&pi, g, &s, p); EG(ret, err);
332
/* Compute (y ** -r) * (g ** s) mod (p) */
333
ret = nn_mod_mul(&pi, &pi, &u, p); EG(ret, err);
334
335
/* Compute r' */
336
/* I2BS(alpha, pi)
337
*/
338
ret = _i2osp(&pi, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
339
/* r' = h(I2BS(alpha, pi) || M) */
340
ret = gen_hash_init(&hash_ctx, sdsa_hash); EG(ret, err);
341
ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), sdsa_hash); EG(ret, err);
342
ret = gen_hash_update(&hash_ctx, msg, msglen, sdsa_hash); EG(ret, err);
343
ret = gen_hash_final(&hash_ctx, hash, sdsa_hash); EG(ret, err);
344
345
/* Check that hash values r' == r */
346
ret = are_equal(sig, hash, hlen, &cmp); EG(ret, err);
347
ret = (cmp != 1) ? -1 : 0;
348
349
err:
350
nn_uninit(&r);
351
nn_uninit(&s);
352
nn_uninit(&u);
353
nn_uninit(&pi);
354
355
PTR_NULLIFY(p);
356
PTR_NULLIFY(q);
357
PTR_NULLIFY(g);
358
PTR_NULLIFY(y);
359
360
return ret;
361
}
362
363
#ifdef SDSA
364
#include <libecc/utils/print_buf.h>
365
int main(int argc, char *argv[])
366
{
367
int ret = 0;
368
369
/* This example is taken from ISO14888-3 SDSA (Appendix F "Numerical examples" */
370
const u8 p[] = {
371
0x87, 0xA8, 0xE6, 0x1D, 0xB4, 0xB6, 0x66, 0x3C, 0xFF, 0xBB, 0xD1, 0x9C, 0x65, 0x19, 0x59, 0x99, 0x8C, 0xEE, 0xF6, 0x08, 0x66, 0x0D, 0xD0, 0xF2,
372
0x5D, 0x2C, 0xEE, 0xD4, 0x43, 0x5E, 0x3B, 0x00, 0xE0, 0x0D, 0xF8, 0xF1, 0xD6, 0x19, 0x57, 0xD4, 0xFA, 0xF7, 0xDF, 0x45, 0x61, 0xB2, 0xAA, 0x30,
373
0x16, 0xC3, 0xD9, 0x11, 0x34, 0x09, 0x6F, 0xAA, 0x3B, 0xF4, 0x29, 0x6D, 0x83, 0x0E, 0x9A, 0x7C, 0x20, 0x9E, 0x0C, 0x64, 0x97, 0x51, 0x7A, 0xBD,
374
0x5A, 0x8A, 0x9D, 0x30, 0x6B, 0xCF, 0x67, 0xED, 0x91, 0xF9, 0xE6, 0x72, 0x5B, 0x47, 0x58, 0xC0, 0x22, 0xE0, 0xB1, 0xEF, 0x42, 0x75, 0xBF, 0x7B,
375
0x6C, 0x5B, 0xFC, 0x11, 0xD4, 0x5F, 0x90, 0x88, 0xB9, 0x41, 0xF5, 0x4E, 0xB1, 0xE5, 0x9B, 0xB8, 0xBC, 0x39, 0xA0, 0xBF, 0x12, 0x30, 0x7F, 0x5C,
376
0x4F, 0xDB, 0x70, 0xC5, 0x81, 0xB2, 0x3F, 0x76, 0xB6, 0x3A, 0xCA, 0xE1, 0xCA, 0xA6, 0xB7, 0x90, 0x2D, 0x52, 0x52, 0x67, 0x35, 0x48, 0x8A, 0x0E,
377
0xF1, 0x3C, 0x6D, 0x9A, 0x51, 0xBF, 0xA4, 0xAB, 0x3A, 0xD8, 0x34, 0x77, 0x96, 0x52, 0x4D, 0x8E, 0xF6, 0xA1, 0x67, 0xB5, 0xA4, 0x18, 0x25, 0xD9,
378
0x67, 0xE1, 0x44, 0xE5, 0x14, 0x05, 0x64, 0x25, 0x1C, 0xCA, 0xCB, 0x83, 0xE6, 0xB4, 0x86, 0xF6, 0xB3, 0xCA, 0x3F, 0x79, 0x71, 0x50, 0x60, 0x26,
379
0xC0, 0xB8, 0x57, 0xF6, 0x89, 0x96, 0x28, 0x56, 0xDE, 0xD4, 0x01, 0x0A, 0xBD, 0x0B, 0xE6, 0x21, 0xC3, 0xA3, 0x96, 0x0A, 0x54, 0xE7, 0x10, 0xC3,
380
0x75, 0xF2, 0x63, 0x75, 0xD7, 0x01, 0x41, 0x03, 0xA4, 0xB5, 0x43, 0x30, 0xC1, 0x98, 0xAF, 0x12, 0x61, 0x16, 0xD2, 0x27, 0x6E, 0x11, 0x71, 0x5F,
381
0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9, 0x1E, 0x1A, 0x15, 0x97,
382
};
383
384
const u8 q[] = {
385
0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76, 0x40, 0x12, 0x9D, 0xA2, 0x99, 0xB1, 0xA4, 0x7D, 0x1E, 0xB3, 0x75, 0x0B,
386
0xA3, 0x08, 0xB0, 0xFE, 0x64, 0xF5, 0xFB, 0xD3,
387
};
388
389
const u8 g[] = {
390
0x3F, 0xB3, 0x2C, 0x9B, 0x73, 0x13, 0x4D, 0x0B, 0x2E, 0x77, 0x50, 0x66, 0x60, 0xED, 0xBD, 0x48, 0x4C, 0xA7, 0xB1, 0x8F, 0x21, 0xEF, 0x20, 0x54,
391
0x07, 0xF4, 0x79, 0x3A, 0x1A, 0x0B, 0xA1, 0x25, 0x10, 0xDB, 0xC1, 0x50, 0x77, 0xBE, 0x46, 0x3F, 0xFF, 0x4F, 0xED, 0x4A, 0xAC, 0x0B, 0xB5, 0x55,
392
0xBE, 0x3A, 0x6C, 0x1B, 0x0C, 0x6B, 0x47, 0xB1, 0xBC, 0x37, 0x73, 0xBF, 0x7E, 0x8C, 0x6F, 0x62, 0x90, 0x12, 0x28, 0xF8, 0xC2, 0x8C, 0xBB, 0x18,
393
0xA5, 0x5A, 0xE3, 0x13, 0x41, 0x00, 0x0A, 0x65, 0x01, 0x96, 0xF9, 0x31, 0xC7, 0x7A, 0x57, 0xF2, 0xDD, 0xF4, 0x63, 0xE5, 0xE9, 0xEC, 0x14, 0x4B,
394
0x77, 0x7D, 0xE6, 0x2A, 0xAA, 0xB8, 0xA8, 0x62, 0x8A, 0xC3, 0x76, 0xD2, 0x82, 0xD6, 0xED, 0x38, 0x64, 0xE6, 0x79, 0x82, 0x42, 0x8E, 0xBC, 0x83,
395
0x1D, 0x14, 0x34, 0x8F, 0x6F, 0x2F, 0x91, 0x93, 0xB5, 0x04, 0x5A, 0xF2, 0x76, 0x71, 0x64, 0xE1, 0xDF, 0xC9, 0x67, 0xC1, 0xFB, 0x3F, 0x2E, 0x55,
396
0xA4, 0xBD, 0x1B, 0xFF, 0xE8, 0x3B, 0x9C, 0x80, 0xD0, 0x52, 0xB9, 0x85, 0xD1, 0x82, 0xEA, 0x0A, 0xDB, 0x2A, 0x3B, 0x73, 0x13, 0xD3, 0xFE, 0x14,
397
0xC8, 0x48, 0x4B, 0x1E, 0x05, 0x25, 0x88, 0xB9, 0xB7, 0xD2, 0xBB, 0xD2, 0xDF, 0x01, 0x61, 0x99, 0xEC, 0xD0, 0x6E, 0x15, 0x57, 0xCD, 0x09, 0x15,
398
0xB3, 0x35, 0x3B, 0xBB, 0x64, 0xE0, 0xEC, 0x37, 0x7F, 0xD0, 0x28, 0x37, 0x0D, 0xF9, 0x2B, 0x52, 0xC7, 0x89, 0x14, 0x28, 0xCD, 0xC6, 0x7E, 0xB6,
399
0x18, 0x4B, 0x52, 0x3D, 0x1D, 0xB2, 0x46, 0xC3, 0x2F, 0x63, 0x07, 0x84, 0x90, 0xF0, 0x0E, 0xF8, 0xD6, 0x47, 0xD1, 0x48, 0xD4, 0x79, 0x54, 0x51,
400
0x5E, 0x23, 0x27, 0xCF, 0xEF, 0x98, 0xC5, 0x82, 0x66, 0x4B, 0x4C, 0x0F, 0x6C, 0xC4, 0x16, 0x59,
401
};
402
403
const u8 x[] = {
404
0x73, 0x01, 0x88, 0x95, 0x20, 0xD4, 0x7A, 0xA0, 0x55, 0x99, 0x5B, 0xA1, 0xD8, 0xFC, 0xD7, 0x01, 0x6E, 0xA6, 0x2E, 0x09, 0x18, 0x89, 0x2E, 0x07,
405
0xB7, 0xDC, 0x23, 0xAF, 0x69, 0x00, 0x6B, 0x88,
406
};
407
408
const u8 y[] = {
409
0x57, 0xA1, 0x72, 0x58, 0xD4, 0xA3, 0xF4, 0x7C, 0x45, 0x45, 0xAD, 0x51, 0xF3, 0x10, 0x9C, 0x5D, 0xB4, 0x1B, 0x78, 0x78, 0x79, 0xFC, 0xFE, 0x53,
410
0x8D, 0xC1, 0xDD, 0x5D, 0x35, 0xCE, 0x42, 0xFF, 0x3A, 0x9F, 0x22, 0x5E, 0xDE, 0x65, 0x02, 0x12, 0x64, 0x08, 0xFC, 0xB1, 0x3A, 0xEA, 0x22, 0x31,
411
0x80, 0xB1, 0x49, 0xC4, 0x64, 0xE1, 0x76, 0xEB, 0xF0, 0x3B, 0xA6, 0x51, 0x0D, 0x82, 0x06, 0xC9, 0x20, 0xF6, 0xB1, 0xE0, 0x93, 0x92, 0xE6, 0xC8,
412
0x40, 0xA0, 0x5B, 0xDB, 0x9D, 0x68, 0x75, 0xAB, 0x3F, 0x48, 0x17, 0xEC, 0x3A, 0x65, 0xA6, 0x65, 0xB7, 0x88, 0xEC, 0xBB, 0x44, 0x71, 0x88, 0xC7,
413
0xDF, 0x2E, 0xB4, 0xD3, 0xD9, 0x42, 0x4E, 0x57, 0xD9, 0x64, 0x39, 0x8D, 0xBE, 0x1C, 0x63, 0x62, 0x65, 0x9C, 0x6B, 0xD8, 0x55, 0xC1, 0xD3, 0xE5,
414
0x1D, 0x64, 0x79, 0x6C, 0xA5, 0x98, 0x48, 0x0D, 0xFD, 0xD9, 0x58, 0x0E, 0x55, 0x08, 0x53, 0x45, 0xC1, 0x5E, 0x34, 0xD6, 0xA3, 0x3A, 0x2F, 0x43,
415
0xE2, 0x22, 0x40, 0x7A, 0xCE, 0x05, 0x89, 0x72, 0xD3, 0x49, 0x52, 0xAE, 0x2B, 0x70, 0x5C, 0x53, 0x22, 0x43, 0xBE, 0x39, 0x4B, 0x22, 0x23, 0x29,
416
0x61, 0x61, 0x14, 0x5E, 0xF2, 0x92, 0x7C, 0xDB, 0xC5, 0x5B, 0xBD, 0x56, 0x4A, 0xAE, 0x8D, 0xE4, 0xBA, 0x45, 0x00, 0xA7, 0xFA, 0x43, 0x2F, 0xE7,
417
0x8B, 0x0F, 0x06, 0x89, 0x1E, 0x40, 0x80, 0x83, 0x7E, 0x76, 0x10, 0x57, 0xBC, 0x6C, 0xB8, 0xAC, 0x18, 0xFD, 0x43, 0x20, 0x75, 0x82, 0x03, 0x2A,
418
0xFB, 0x63, 0xC6, 0x24, 0xF3, 0x2E, 0x66, 0xB0, 0x5F, 0xC3, 0x1C, 0x5D, 0xFF, 0xB2, 0x5F, 0xA9, 0x2D, 0x4D, 0x00, 0xE2, 0xB0, 0xD4, 0xF7, 0x21,
419
0xE8, 0x8C, 0x41, 0x7D, 0x2E, 0x57, 0x79, 0x7B, 0x8F, 0x55, 0xA2, 0xFF, 0xC6, 0xEE, 0x4D, 0xDB,
420
};
421
422
const u8 msg[] = "abc";
423
424
const u8 nonce[] = {
425
0x2B, 0x73, 0xE8, 0xFF, 0x3A, 0x7C, 0x01, 0x68, 0x6C, 0xA5, 0x56, 0xE0, 0xFA, 0xBF, 0xD7, 0x4A, 0xC8, 0xD1, 0xFD, 0xA4, 0xAD, 0x3D, 0x50, 0x3F,
426
0x23, 0xB8, 0xEB, 0x8A, 0xEE, 0xC6, 0x33, 0x05,
427
};
428
429
sdsa_priv_key priv;
430
sdsa_pub_key pub;
431
sdsa_pub_key pub2;
432
u8 sig[32*2] = { 0 };
433
434
FORCE_USED_VAR(argc);
435
FORCE_USED_VAR(argv);
436
437
/* Sanity check on size for DSA.
438
* NOTE: the double parentheses are here to handle -Wunreachable-code
439
*/
440
if((NN_USABLE_MAX_BIT_LEN) < (4096)){
441
ext_printf("Error: you seem to have compiled libecc with usable NN size < 4096, not suitable for DSA.\n");
442
ext_printf(" => Please recompile libecc with EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\"\n");
443
ext_printf(" This will increase usable NN for proper DSA up to 4096 bits.\n");
444
ext_printf(" Then recompile the current examples with the same EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\" flag and execute again!\n");
445
/* NOTE: ret = 0 here to pass self tests even if the library is not compatible */
446
ret = 0;
447
goto err;
448
}
449
450
451
ret = sdsa_import_priv_key(&priv, p, sizeof(p), q, sizeof(q), g, sizeof(g), x, sizeof(x)); EG(ret, err);
452
ret = sdsa_import_pub_key(&pub, p, sizeof(p), q, sizeof(q), g, sizeof(g), y, sizeof(y)); EG(ret, err);
453
ret = sdsa_compute_pub_from_priv(&pub2, &priv); EG(ret, err);
454
455
nn_print("y", &(pub2.y));
456
457
ret = sdsa_sign(&priv, msg, sizeof(msg)-1, nonce, sizeof(nonce), sig, sizeof(sig), HASH_SHA256); EG(ret, err);
458
459
buf_print("sig", sig, sizeof(sig));
460
461
ret = sdsa_verify(&pub, msg, sizeof(msg)-1, sig, sizeof(sig), HASH_SHA256);
462
ext_printf("Signature result %d\n", ret);
463
464
err:
465
return ret;
466
}
467
#endif
468
469