/src/nettle/ecc-gostdsa-sign.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* ecc-gostdsa-sign.c |
2 | | |
3 | | Copyright (C) 2015 Dmitry Eremin-Solenikov |
4 | | Copyright (C) 2013, 2014 Niels Möller |
5 | | |
6 | | This file is part of GNU Nettle. |
7 | | |
8 | | GNU Nettle is free software: you can redistribute it and/or |
9 | | modify it under the terms of either: |
10 | | |
11 | | * the GNU Lesser General Public License as published by the Free |
12 | | Software Foundation; either version 3 of the License, or (at your |
13 | | option) any later version. |
14 | | |
15 | | or |
16 | | |
17 | | * the GNU General Public License as published by the Free |
18 | | Software Foundation; either version 2 of the License, or (at your |
19 | | option) any later version. |
20 | | |
21 | | or both in parallel, as here. |
22 | | |
23 | | GNU Nettle is distributed in the hope that it will be useful, |
24 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
25 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
26 | | General Public License for more details. |
27 | | |
28 | | You should have received copies of the GNU General Public License and |
29 | | the GNU Lesser General Public License along with this program. If |
30 | | not, see http://www.gnu.org/licenses/. |
31 | | */ |
32 | | |
33 | | #if HAVE_CONFIG_H |
34 | | # include "config.h" |
35 | | #endif |
36 | | |
37 | | #include <assert.h> |
38 | | #include <stdlib.h> |
39 | | |
40 | | #include "gostdsa.h" |
41 | | #include "ecc-internal.h" |
42 | | |
43 | | /* Low-level GOST DSA signing */ |
44 | | |
45 | | mp_size_t |
46 | | ecc_gostdsa_sign_itch (const struct ecc_curve *ecc) |
47 | 0 | { |
48 | | /* Needs 3*ecc->p.size + scratch for ecc_mul_g. */ |
49 | 0 | return ECC_GOSTDSA_SIGN_ITCH (ecc->p.size); |
50 | 0 | } |
51 | | |
52 | | /* NOTE: Caller should check if r or s is zero. */ |
53 | | void |
54 | | ecc_gostdsa_sign (const struct ecc_curve *ecc, |
55 | | const mp_limb_t *zp, |
56 | | const mp_limb_t *kp, |
57 | | size_t length, const uint8_t *digest, |
58 | | mp_limb_t *rp, mp_limb_t *sp, |
59 | | mp_limb_t *scratch) |
60 | 0 | { |
61 | 0 | #define P scratch |
62 | 0 | #define hp (scratch + 4*ecc->p.size) |
63 | 0 | #define tp (scratch + 2*ecc->p.size) |
64 | 0 | #define t2p scratch |
65 | | /* Procedure, according to GOST 34.10. q denotes the group |
66 | | order. |
67 | | |
68 | | 1. k <-- uniformly random, 0 < k < q |
69 | | |
70 | | 2. C <-- (c_x, c_y) = k g |
71 | | |
72 | | 3. r <-- c_x mod q |
73 | | |
74 | | 4. s <-- (r*z + k*h) mod q. |
75 | | */ |
76 | |
|
77 | 0 | ecc_mul_g (ecc, P, kp, P + 3*ecc->p.size); |
78 | | /* x coordinate only, modulo q */ |
79 | 0 | ecc_j_to_a (ecc, 2, rp, P, P + 3*ecc->p.size); |
80 | | |
81 | | /* Process hash digest */ |
82 | 0 | gost_hash (&ecc->q, hp, length, digest); |
83 | 0 | if (mpn_zero_p (hp, ecc->p.size)) |
84 | 0 | mpn_add_1 (hp, hp, ecc->p.size, 1); |
85 | |
|
86 | 0 | ecc_mod_mul (&ecc->q, tp, rp, zp, tp); |
87 | 0 | ecc_mod_mul (&ecc->q, t2p, kp, hp, t2p); |
88 | 0 | ecc_mod_add (&ecc->q, sp, tp, t2p); |
89 | | |
90 | | /* Also reduce mod ecc->q. It should already be < 2*ecc->q, |
91 | | * so one subtraction should suffice. */ |
92 | |
|
93 | 0 | *scratch = mpn_sub_n (tp, sp, ecc->q.m, ecc->p.size); |
94 | 0 | cnd_copy (*scratch == 0, sp, tp, ecc->p.size); |
95 | |
|
96 | 0 | #undef P |
97 | 0 | #undef hp |
98 | 0 | #undef tp |
99 | 0 | #undef t2p |
100 | 0 | } |