- started to implement diffie hellman class
[strongswan.git] / Source / charon / utils / gmp_helper.c
1 /**
2 * @file gmp_helper.c
3 *
4 * @brief Class with helper functions for gmp operations
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "gmp_helper.h"
24
25 #include "allocator.h"
26 #include "randomizer.h"
27
28 /**
29 * Private data of an gmp_helper_t object.
30 *
31 */
32 typedef struct private_gmp_helper_s private_gmp_helper_t;
33
34 struct private_gmp_helper_s {
35 /**
36 * public gmp_helper_t interface
37 */
38 gmp_helper_t public;
39
40 };
41
42
43 /**
44 * Implements private_gmp_helper_t's chunk_to_mpz function.
45 * See #private_gmp_helper_t.chunk_to_mpz for description.
46 */
47 static void chunk_to_mpz(private_gmp_helper_t *this, mpz_t *mpz_value, chunk_t data)
48 {
49 size_t i;
50
51 mpz_init_set_ui(*(mpz_value), 0);
52
53 for (i = 0; i < data.len; i++)
54 {
55 mpz_mul_ui(*(mpz_value),*(mpz_value), 1 << 8);
56 mpz_add_ui(*(mpz_value),*(mpz_value), data.ptr[i]);
57 }
58 }
59
60 /**
61 * Implements private_gmp_helper_t's mpz_to_chunk function.
62 * See #private_gmp_helper_t.mpz_to_chunk for description.
63 */
64 static status_t mpz_to_chunk (private_gmp_helper_t *this,mpz_t *mpz_value, chunk_t *data,size_t bytes)
65 {
66 mpz_t temp1, temp2;
67 status_t status = SUCCESS;
68 int i;
69
70 data->len = bytes;
71 data->ptr = allocator_alloc(data->len);
72
73 if (data->ptr == NULL)
74 {
75 return OUT_OF_RES;
76 }
77
78 /* free memory */
79 memset(data->ptr,0,data->len);
80
81 mpz_init(temp1);
82 mpz_init(temp2);
83
84 mpz_set(temp1, *mpz_value);
85
86 for (i = data->len-1; i >= 0; i--)
87 {
88 data->ptr[i] = mpz_mdivmod_ui(temp2, NULL, temp1, 1 << 8);
89 mpz_set(temp1, temp2);
90
91 }
92
93 if (mpz_sgn(temp1) != 0)
94 {
95 status = FAILED;
96 }
97 mpz_clear(temp1);
98 mpz_clear(temp2);
99 return status;
100 }
101
102 /**
103 * Implements gmp_helper_t's init_prime function.
104 * See #gmp_helper_t.init_prime for description.
105 */
106 static status_t init_prime (private_gmp_helper_t *this, mpz_t *prime, int bytes)
107 {
108 randomizer_t *randomizer;
109 chunk_t random_bytes;
110 status_t status;
111 randomizer = randomizer_create();
112
113 if (randomizer == NULL)
114 {
115 return OUT_OF_RES;
116 }
117
118 status = randomizer->allocate_random_bytes(randomizer,bytes, &random_bytes);
119 /* not needed anymore */
120 randomizer->destroy(randomizer);
121 if (status != SUCCESS)
122 {
123 return status;
124 }
125
126 /* convert chunk to mpz value */
127 this->public.chunk_to_mpz(&(this->public),prime, random_bytes);
128
129 /* chunk is not used anymore */
130 allocator_free(random_bytes.ptr);
131 random_bytes.ptr = NULL;
132
133 mpz_nextprime (*(prime),*(prime));
134
135 return SUCCESS;
136 }
137
138
139
140 /**
141 * Implements gmp_helper_t's destroy function.
142 * See #gmp_helper_t.destroy for description.
143 */
144 static status_t destroy(private_gmp_helper_t *this)
145 {
146 allocator_free(this);
147 return SUCCESS;
148 }
149
150 /*
151 * Described in header
152 */
153 gmp_helper_t *gmp_helper_create()
154 {
155 private_gmp_helper_t *this = allocator_alloc_thing(private_gmp_helper_t);
156 if ((this == NULL))
157 {
158 return NULL;
159 }
160
161 /* public functions */
162 this->public.destroy = (status_t (*)(gmp_helper_t *)) destroy;
163 this->public.init_prime = (status_t (*) (gmp_helper_t *, mpz_t *, int)) init_prime;
164
165 /* private functions */
166 this->public.chunk_to_mpz = (void (*) (gmp_helper_t *,mpz_t *, chunk_t )) chunk_to_mpz;
167 this->public.mpz_to_chunk = (status_t (*) (gmp_helper_t *,mpz_t *, chunk_t *,size_t )) mpz_to_chunk;
168
169 return &(this->public);
170 }