*** empty log message ***
[gnutls.git] / lib / gnutls_dh.c
blobbce4157e8fcde2f7891ef19daf15fc221c1410f4
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
5 * someday was part of gsti
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
27 /*
28 --Example--
29 you: X = g ^ x mod p;
30 peer:Y = g ^ y mod p;
32 your_key = Y ^ x mod p;
33 his_key = X ^ y mod p;
35 // generate our secret and the public value (X) for it
36 X = gnutls_calc_dh_secret(&x, g, p);
37 // now we can calculate the shared secret
38 key = gnutls_calc_dh_key(Y, x, g, p);
39 _gnutls_mpi_release(x);
40 _gnutls_mpi_release(g);
43 #define MAX_BITS 12000
45 /* returns the public value (X), and the secret (ret_x).
47 GNUTLS_MPI gnutls_calc_dh_secret(GNUTLS_MPI * ret_x, GNUTLS_MPI g, GNUTLS_MPI prime)
49 GNUTLS_MPI e, x;
50 int x_size = _gnutls_mpi_get_nbits(prime) - 1;
51 /* The size of the secret key is less than
52 * prime/2
55 if (x_size > MAX_BITS || x_size <= 0) {
56 gnutls_assert();
57 return NULL;
60 x = _gnutls_mpi_new(x_size);
61 if (x == NULL) {
62 gnutls_assert();
63 if (ret_x)
64 *ret_x = NULL;
66 return NULL;
69 /* (x_size/8)*8 is there to overcome a bug in libgcrypt
70 * which does not really check the bits given but the bytes.
72 _gnutls_mpi_randomize(x, (x_size/8)*8, GCRY_STRONG_RANDOM);
74 e = _gnutls_mpi_alloc_like(prime);
75 if (e == NULL) {
76 gnutls_assert();
77 if (ret_x)
78 *ret_x = NULL;
80 _gnutls_mpi_release( &x);
81 return NULL;
84 _gnutls_mpi_powm(e, g, x, prime);
86 if (ret_x)
87 *ret_x = x;
88 else
89 _gnutls_mpi_release(&x);
90 return e;
94 GNUTLS_MPI gnutls_calc_dh_key(GNUTLS_MPI f, GNUTLS_MPI x, GNUTLS_MPI prime)
96 GNUTLS_MPI k;
97 int bits;
99 bits = _gnutls_mpi_get_nbits(prime);
100 if (bits <= 0 || bits > MAX_BITS) {
101 gnutls_assert();
102 return NULL;
105 k = _gnutls_mpi_alloc_like(prime);
106 if (k == NULL)
107 return NULL;
108 _gnutls_mpi_powm(k, f, x, prime);
109 return k;