File: | lib/nettle/ecc_verify_hash.c |
Location: | line 67, column 8 |
Description: | Although the value stored to 'err' is used in the enclosing expression, the value is never actually read from 'err' |
1 | /* |
2 | * Copyright (C) 2011-2012 Free Software Foundation, Inc. |
3 | * |
4 | * This file is part of GNUTLS. |
5 | * |
6 | * The GNUTLS library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public License |
8 | * as published by the Free Software Foundation; either version 3 of |
9 | * the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, but |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License |
17 | * along with this program. If not, see <http://www.gnu.org/licenses/> |
18 | * |
19 | */ |
20 | |
21 | /* Based on public domain code of LibTomCrypt by Tom St Denis. |
22 | * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. |
23 | */ |
24 | |
25 | #include "ecc.h" |
26 | |
27 | /* |
28 | @file ecc_verify_hash.c |
29 | ECC Crypto, Tom St Denis |
30 | */ |
31 | |
32 | /* verify |
33 | * |
34 | * w = s^-1 mod n |
35 | * u1 = xw |
36 | * u2 = rw |
37 | * X = u1*G + u2*Q |
38 | * v = X_x1 mod n |
39 | * accept if v == r |
40 | */ |
41 | |
42 | /* |
43 | Verify an ECC signature |
44 | @param signature The signature to verify |
45 | @param hash The hash (message digest) that was signed |
46 | @param hashlen The length of the hash (octets) |
47 | @param stat Result of signature, 1==valid, 0==invalid |
48 | @param key The corresponding public ECC key |
49 | @return 0 if successful (even if the signature is not valid) |
50 | */ |
51 | int |
52 | ecc_verify_hash (struct dsa_signature *signature, |
53 | const unsigned char *hash, unsigned long hashlen, |
54 | int *stat, ecc_key * key) |
55 | { |
56 | ecc_point *mG, *mQ; |
57 | mpz_t v, w, u1, u2, e; |
58 | int err; |
59 | |
60 | if (signature == NULL((void*)0) || hash == NULL((void*)0) || stat == NULL((void*)0) || key == NULL((void*)0)) |
61 | return -1; |
62 | |
63 | /* default to invalid signature */ |
64 | *stat = 0; |
65 | |
66 | /* allocate ints */ |
67 | if ((err = mp_init_multi (&v, &w, &u1, &u2, &e, NULL((void*)0))) != 0) |
Although the value stored to 'err' is used in the enclosing expression, the value is never actually read from 'err' | |
68 | { |
69 | return -1; |
70 | } |
71 | |
72 | /* allocate points */ |
73 | mG = ecc_new_point (); |
74 | mQ = ecc_new_point (); |
75 | if (mQ == NULL((void*)0) || mG == NULL((void*)0)) |
76 | { |
77 | err = -1; |
78 | goto error; |
79 | } |
80 | |
81 | /* check for (0) */ |
82 | if (mpz_cmp_ui (signature->r, 0)(__builtin_constant_p (0) && (0) == 0 ? ((signature-> r)->_mp_size < 0 ? -1 : (signature->r)->_mp_size > 0) : __gmpz_cmp_ui (signature->r,0)) == 0 || mpz_cmp_ui (signature->s, 0)(__builtin_constant_p (0) && (0) == 0 ? ((signature-> s)->_mp_size < 0 ? -1 : (signature->s)->_mp_size > 0) : __gmpz_cmp_ui (signature->s,0)) == 0 |
83 | || mpz_cmp__gmpz_cmp (signature->r, key->order) >= 0 |
84 | || mpz_cmp__gmpz_cmp (signature->s, key->order) >= 0) |
85 | { |
86 | err = -1; |
87 | goto error; |
88 | } |
89 | |
90 | /* read hash */ |
91 | nettle_mpz_set_str_256_u (e, hashlen, hash); |
92 | |
93 | /* w = s^-1 mod n */ |
94 | mpz_invert__gmpz_invert (w, signature->s, key->order); |
95 | |
96 | /* u1 = ew */ |
97 | mpz_mul__gmpz_mul (u1, e, w); |
98 | mpz_mod__gmpz_mod (u1, u1, key->order); |
99 | |
100 | /* u2 = rw */ |
101 | mpz_mul__gmpz_mul (u2, signature->r, w); |
102 | mpz_mod__gmpz_mod (u2, u2, key->order); |
103 | |
104 | /* find mG and mQ */ |
105 | mpz_set__gmpz_set (mG->x, key->Gx); |
106 | mpz_set__gmpz_set (mG->y, key->Gy); |
107 | mpz_set_ui__gmpz_set_ui (mG->z, 1); |
108 | |
109 | mpz_set__gmpz_set (mQ->x, key->pubkey.x); |
110 | mpz_set__gmpz_set (mQ->y, key->pubkey.y); |
111 | mpz_set__gmpz_set (mQ->z, key->pubkey.z); |
112 | |
113 | /* compute u1*mG + u2*mQ = mG */ |
114 | if ((err = ecc_mulmod (u1, mG, mG, key->A, key->prime, 0)) != 0) |
115 | { |
116 | goto error; |
117 | } |
118 | if ((err = ecc_mulmod (u2, mQ, mQ, key->A, key->prime, 0)) != 0) |
119 | { |
120 | goto error; |
121 | } |
122 | |
123 | /* add them */ |
124 | if ((err = |
125 | ecc_projective_add_point (mQ, mG, mG, key->A, key->prime)) != 0) |
126 | { |
127 | goto error; |
128 | } |
129 | |
130 | /* reduce */ |
131 | if ((err = ecc_map (mG, key->prime)) != 0) |
132 | { |
133 | goto error; |
134 | } |
135 | |
136 | /* v = X_x1 mod n */ |
137 | mpz_mod__gmpz_mod (v, mG->x, key->order); |
138 | |
139 | /* does v == r */ |
140 | if (mpz_cmp__gmpz_cmp (v, signature->r) == 0) |
141 | { |
142 | *stat = 1; |
143 | } |
144 | |
145 | /* clear up and return */ |
146 | err = 0; |
147 | error: |
148 | ecc_del_point (mG); |
149 | ecc_del_point (mQ); |
150 | mp_clear_multi (&v, &w, &u1, &u2, &e, NULL((void*)0)); |
151 | return err; |
152 | } |
153 | |
154 | /* $Source: /webcvs/gnutls/gnutls/clang/report-1ds23z.html,v $ */ |
155 | /* $Revision: 1.1 $ */ |
156 | /* $Date: 2012/01/20 14:01:16 $ */ |