2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * This file is part of GNUTLS.
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.
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.
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/>
21 /* Based on public domain code of LibTomCrypt by Tom St Denis.
22 * Adapted to gmp and nettle by Nikos Mavrogiannopoulos.
28 @file ecc_verify_hash.c
29 ECC Crypto, Tom St Denis
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 @param curve_id The id of the curve we are working with
50 @return 0 if successful (even if the signature is not valid)
53 ecc_verify_hash (struct dsa_signature
*signature
,
54 const unsigned char *hash
, unsigned long hashlen
,
55 int *stat
, ecc_key
* key
, gnutls_ecc_curve_t curve_id
)
58 mpz_t v
, w
, u1
, u2
, e
;
61 if (signature
== NULL
|| hash
== NULL
|| stat
== NULL
|| key
== NULL
)
64 /* default to invalid signature */
68 if ((err
= mp_init_multi (&v
, &w
, &u1
, &u2
, &e
, NULL
)) != 0)
74 mG
= ecc_new_point ();
75 mQ
= ecc_new_point ();
76 if (mQ
== NULL
|| mG
== NULL
)
83 if (mpz_cmp_ui (signature
->r
, 0) == 0 || mpz_cmp_ui (signature
->s
, 0) == 0
84 || mpz_cmp (signature
->r
, key
->order
) >= 0
85 || mpz_cmp (signature
->s
, key
->order
) >= 0)
92 nettle_mpz_set_str_256_u (e
, hashlen
, hash
);
95 mpz_invert (w
, signature
->s
, key
->order
);
99 mpz_mod (u1
, u1
, key
->order
);
102 mpz_mul (u2
, signature
->r
, w
);
103 mpz_mod (u2
, u2
, key
->order
);
106 mpz_set (mG
->x
, key
->Gx
);
107 mpz_set (mG
->y
, key
->Gy
);
108 mpz_set_ui (mG
->z
, 1);
110 mpz_set (mQ
->x
, key
->pubkey
.x
);
111 mpz_set (mQ
->y
, key
->pubkey
.y
);
112 mpz_set (mQ
->z
, key
->pubkey
.z
);
114 /* compute u1*mG + u2*mQ = mG */
115 if ((err
= ecc_mulmod_cached (u1
, curve_id
, mG
, key
->A
, key
->prime
, 0)) != 0)
119 if ((err
= ecc_mulmod (u2
, mQ
, mQ
, key
->A
, key
->prime
, 0)) != 0)
126 ecc_projective_add_point (mQ
, mG
, mG
, key
->A
, key
->prime
)) != 0)
132 if ((err
= ecc_map (mG
, key
->prime
)) != 0)
138 mpz_mod (v
, mG
->x
, key
->order
);
141 if (mpz_cmp (v
, signature
->r
) == 0)
146 /* clear up and return */
151 mp_clear_multi (&v
, &w
, &u1
, &u2
, &e
, NULL
);
155 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */
156 /* $Revision: 1.14 $ */
157 /* $Date: 2007/05/12 14:32:35 $ */