provide accurate value to select
[gnutls.git] / lib / nettle / ecc_make_key.c
blob6886846b2bc19c5d2eb412decd227cc36ae16a09
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"
28 @file ecc_make_key.c
29 ECC Crypto, Tom St Denis
33 Make a new ECC key
34 @param prng An active PRNG state
35 @param wprng The index of the PRNG you wish to use
36 @param prime The prime of curve's field
37 @param order The order of the G point
38 @param A The "a" parameter of the curve
39 @param Gx The x coordinate of the base point
40 @param Gy The y coordinate of the base point
41 @timing_res If non zero the function will try to return in constant time.
42 @return 0 if successful, upon error all allocated memory will be freed
45 int
46 ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key,
47 mpz_t prime, mpz_t order, mpz_t A, mpz_t B, mpz_t Gx, mpz_t Gy,
48 int timing_res)
50 int err;
51 ecc_point *base;
52 unsigned char *buf;
53 int keysize;
55 if (key == NULL || random == NULL)
56 return -1;
58 keysize = nettle_mpz_sizeinbase_256_u (order);
60 /* allocate ram */
61 base = NULL;
62 buf = malloc (keysize);
63 if (buf == NULL)
64 return -1;
66 /* make up random string */
67 random (random_ctx, keysize, buf);
69 /* setup the key variables */
70 if ((err =
71 mp_init_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
72 &key->prime, &key->order, &key->A, &key->B, &key->Gx, &key->Gy,
73 NULL)) != 0)
75 goto ERR_BUF;
77 base = ecc_new_point ();
78 if (base == NULL)
80 err = -1;
81 goto errkey;
84 /* read in the specs for this key */
85 mpz_set (key->prime, prime);
86 mpz_set (key->order, order);
87 mpz_set (key->Gx, Gx);
88 mpz_set (key->Gy, Gy);
89 mpz_set (key->A, A);
90 mpz_set (key->B, B);
92 mpz_set (base->x, key->Gx);
93 mpz_set (base->y, key->Gy);
94 mpz_set_ui (base->z, 1);
96 nettle_mpz_set_str_256_u (key->k, keysize, buf);
98 /* the key should be smaller than the order of base point */
99 if (mpz_cmp (key->k, key->order) >= 0)
101 mpz_mod (key->k, key->k, key->order);
103 /* make the public key */
104 if (timing_res)
105 err = ecc_mulmod_timing (key->k, base, &key->pubkey, key->A, key->prime, 1);
106 else
107 err = ecc_mulmod (key->k, base, &key->pubkey, key->A, key->prime, 1);
109 if (err != 0)
110 goto errkey;
112 key->type = PK_PRIVATE;
114 /* free up ram */
115 err = 0;
116 goto cleanup;
117 errkey:
118 mp_clear_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
119 &key->order, &key->prime, &key->Gx, &key->Gy, &key->A, &key->B,
120 NULL);
121 cleanup:
122 ecc_del_point (base);
123 ERR_BUF:
124 free (buf);
125 return err;
129 ecc_make_key (void *random_ctx, nettle_random_func random, ecc_key * key,
130 const ecc_set_type * dp)
132 mpz_t prime, order, Gx, Gy, A, B;
133 int err;
135 /* setup the key variables */
136 if ((err = mp_init_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL)) != 0)
138 goto cleanup;
141 /* read in the specs for this key */
142 mpz_set_str (prime, (char *) dp->prime, 16);
143 mpz_set_str (order, (char *) dp->order, 16);
144 mpz_set_str (Gx, (char *) dp->Gx, 16);
145 mpz_set_str (Gy, (char *) dp->Gy, 16);
146 mpz_set_str (A, (char *) dp->A, 16);
147 mpz_set_str (B, (char *) dp->B, 16);
149 err = ecc_make_key_ex (random_ctx, random, key, prime, order, A, B, Gx, Gy, 0);
151 mp_clear_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL);
152 cleanup:
153 return err;
156 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */
157 /* $Revision: 1.13 $ */
158 /* $Date: 2007/05/12 14:32:35 $ */