Annotation of embedaddon/strongswan/src/libstrongswan/plugins/bliss/bliss_sampler.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "bliss_sampler.h"
17:
18: typedef struct private_bliss_sampler_t private_bliss_sampler_t;
19:
20: #include <crypto/xofs/xof_bitspender.h>
21:
22: /**
23: * Private data of a bliss_sampler_t object.
24: */
25: struct private_bliss_sampler_t {
26:
27: /**
28: * Public interface.
29: */
30: bliss_sampler_t public;
31:
32: /**
33: * BLISS parameter the rejection sampling is to be based on
34: */
35: const bliss_param_set_t *set;
36:
37: /**
38: * Bitspender used for random rejection sampling
39: */
40: xof_bitspender_t *bitspender;
41:
42: };
43:
44: METHOD(bliss_sampler_t, bernoulli_exp, bool,
45: private_bliss_sampler_t *this, uint32_t x, bool *accepted)
46: {
47: uint32_t x_mask;
48: uint8_t u;
49: const uint8_t *c;
50: int i;
51:
52: x_mask = 1 << (this->set->c_rows - 1);
53: c = this->set->c;
54: c += (this->set->c_rows - 1) * this->set->c_cols;
55:
56: while (x_mask > 0)
57: {
58: if (x & x_mask)
59: {
60: for (i = 0; i < this->set->c_cols; i++)
61: {
62: if (!this->bitspender->get_byte(this->bitspender, &u))
63: {
64: return FALSE;
65: }
66: if (u < c[i])
67: {
68: break;
69: }
70: else if (u > c[i])
71: {
72: *accepted = FALSE;
73: return TRUE;
74: }
75: }
76: }
77: x_mask >>= 1;
78: c -= this->set->c_cols;
79: }
80:
81: *accepted = TRUE;
82: return TRUE;
83: }
84:
85: METHOD(bliss_sampler_t, bernoulli_cosh, bool,
86: private_bliss_sampler_t *this, int32_t x, bool *accepted)
87: {
88: uint32_t u;
89:
90: x = 2 * (x < 0 ? -x : x);
91:
92: while (TRUE)
93: {
94: if (!bernoulli_exp(this, x, accepted))
95: {
96: return FALSE;
97: }
98: if (*accepted)
99: {
100: return TRUE;
101: }
102: if (!this->bitspender->get_bits(this->bitspender, 1, &u))
103: {
104: return FALSE;
105: }
106: if (u)
107: {
108: continue;
109: }
110: if (!bernoulli_exp(this, x, accepted))
111: {
112: return FALSE;
113: }
114: if (!(*accepted))
115: {
116: return TRUE;
117: }
118: }
119: }
120:
121: #define MAX_SAMPLE_INDEX 16
122:
123: METHOD(bliss_sampler_t, pos_binary, bool,
124: private_bliss_sampler_t *this, uint32_t *x)
125: {
126: uint32_t u, i;
127:
128: while (TRUE)
129: {
130: for (i = 0; i <= MAX_SAMPLE_INDEX; i++)
131: {
132: if (!this->bitspender->get_bits(this->bitspender,
133: i ? (2*i - 1) : 1, &u))
134: {
135: return FALSE;
136: }
137: if (u == 0)
138: {
139: *x = i;
140: return TRUE;
141: }
142: if ((u >> 1) != 0)
143: {
144: break;
145: }
146: }
147: if (i > MAX_SAMPLE_INDEX)
148: {
149: return FALSE;
150: }
151: }
152: }
153:
154: METHOD(bliss_sampler_t, gaussian, bool,
155: private_bliss_sampler_t *this, int32_t *z)
156: {
157: uint32_t u, x, y, z_pos;
158: bool accepted;
159:
160: while (TRUE)
161: {
162: if (!pos_binary(this, &x))
163: {
164: return FALSE;
165: }
166:
167: do
168: {
169: if (!this->bitspender->get_bits(this->bitspender,
170: this->set->k_sigma_bits, &y))
171: {
172: return FALSE;
173: }
174: }
175: while (y >= this->set->k_sigma);
176:
177: if (!bernoulli_exp(this, y * (y + 2*this->set->k_sigma * x), &accepted))
178: {
179: return FALSE;
180: }
181: if (accepted)
182: {
183: if (!this->bitspender->get_bits(this->bitspender, 1, &u))
184: {
185: return FALSE;
186: }
187: if (x || y || u)
188: {
189: break;
190: }
191: }
192: }
193:
194: z_pos = this->set->k_sigma * x + y;
195: *z = u ? z_pos : -z_pos;
196:
197: return TRUE;
198: }
199:
200: METHOD(bliss_sampler_t, sign, bool,
201: private_bliss_sampler_t *this, bool *positive)
202: {
203: uint32_t u;
204:
205: if (!this->bitspender->get_bits(this->bitspender, 1, &u))
206: {
207: return FALSE;
208: }
209: *positive = u;
210:
211: return TRUE;
212: }
213:
214: METHOD(bliss_sampler_t, destroy, void,
215: private_bliss_sampler_t *this)
216: {
217: this->bitspender->destroy(this->bitspender);
218: free(this);
219: }
220:
221:
222: /**
223: * See header.
224: */
225: bliss_sampler_t *bliss_sampler_create(ext_out_function_t alg, chunk_t seed,
226: const bliss_param_set_t *set)
227: {
228: private_bliss_sampler_t *this;
229: xof_bitspender_t *bitspender;
230:
231: bitspender = xof_bitspender_create(alg, seed, FALSE);
232: if (!bitspender)
233: {
234: return NULL;
235: }
236:
237: INIT(this,
238: .public = {
239: .bernoulli_exp = _bernoulli_exp,
240: .bernoulli_cosh = _bernoulli_cosh,
241: .pos_binary = _pos_binary,
242: .gaussian = _gaussian,
243: .sign = _sign,
244: .destroy = _destroy,
245: },
246: .set = set,
247: .bitspender = bitspender,
248: );
249:
250: return &this->public;
251: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>