Corrected bugs in record parsing.
[gnutls.git] / lib / nettle / ecc_sign_hash.c
blob2adc7a2e9aff8c4481cde6b22db5e9549bf8b2d5
1 /*
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.
25 #include "ecc.h"
26 #include <nettle/dsa.h>
29 @file ecc_sign_hash.c
30 ECC Crypto, Tom St Denis
34 Sign a message digest
35 @param in The message digest to sign
36 @param inlen The length of the digest
37 @param sign The destination for the signature
38 @param prng An active PRNG state
39 @param wprng The index of the PRNG you wish to use
40 @param key A private ECC key
41 @param curve_id The id of the curve we are working with
42 @return 0 if successful
44 int
45 ecc_sign_hash (const unsigned char *in, unsigned long inlen,
46 struct dsa_signature *sig,
47 void *random_ctx, nettle_random_func random,
48 ecc_key * key, gnutls_ecc_curve_t curve_id)
50 ecc_key pubkey;
51 mpz_t e;
52 int err;
54 if (in == NULL || sig == NULL || key == NULL)
55 return -1;
57 /* is this a private key? */
58 if (key->type != PK_PRIVATE)
60 return -1;
63 /* get the hash and load it as a bignum into 'e' */
64 /* init the bignums */
65 if ((err = mp_init_multi (&e, NULL)) != 0)
67 return err;
70 nettle_mpz_set_str_256_u (e, inlen, in);
72 /* make up a key and export the public copy */
73 for (;;)
75 if ((err =
76 ecc_make_key_ex (random_ctx, random, &pubkey, key->prime,
77 key->order, key->A, key->B, key->Gx, key->Gy, curve_id, 1)) != 0)
79 goto errnokey;
82 /* find r = x1 mod n */
83 mpz_mod (sig->r, pubkey.pubkey.x, pubkey.order);
85 if (mpz_cmp_ui (sig->r, 0) == 0)
87 ecc_free (&pubkey);
89 else
91 /* find s = (e + xr)/k */
92 mpz_invert (pubkey.k, pubkey.k, pubkey.order);
94 /* mulmod */
95 mpz_mul (sig->s, key->k, sig->r);
96 mpz_mod (sig->s, sig->s, pubkey.order);
97 mpz_add (sig->s, e, sig->s);
98 mpz_mod (sig->s, sig->s, pubkey.order);
100 mpz_mul (sig->s, sig->s, pubkey.k);
101 mpz_mod (sig->s, sig->s, pubkey.order);
102 ecc_free (&pubkey);
103 if (mpz_cmp_ui (sig->s, 0) != 0)
105 break;
110 errnokey:
111 mp_clear_multi (&e, NULL);
112 return err;
115 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */
116 /* $Revision: 1.11 $ */
117 /* $Date: 2007/05/12 14:32:35 $ */