2 * Copyright (C) 2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "bliss_sampler.h"
18 typedef struct private_bliss_sampler_t private_bliss_sampler_t
;
20 #include <crypto/xofs/xof_bitspender.h>
23 * Private data of a bliss_sampler_t object.
25 struct private_bliss_sampler_t
{
30 bliss_sampler_t
public;
33 * BLISS parameter the rejection sampling is to be based on
35 const bliss_param_set_t
*set
;
38 * Bitspender used for random rejection sampling
40 xof_bitspender_t
*bitspender
;
44 METHOD(bliss_sampler_t
, bernoulli_exp
, bool,
45 private_bliss_sampler_t
*this, uint32_t x
, bool *accepted
)
52 x_mask
= 1 << (this->set
->c_rows
- 1);
54 c
+= (this->set
->c_rows
- 1) * this->set
->c_cols
;
60 for (i
= 0; i
< this->set
->c_cols
; i
++)
62 if (!this->bitspender
->get_byte(this->bitspender
, &u
))
78 c
-= this->set
->c_cols
;
85 METHOD(bliss_sampler_t
, bernoulli_cosh
, bool,
86 private_bliss_sampler_t
*this, int32_t x
, bool *accepted
)
90 x
= 2 * (x
< 0 ? -x
: x
);
94 if (!bernoulli_exp(this, x
, accepted
))
102 if (!this->bitspender
->get_bits(this->bitspender
, 1, &u
))
110 if (!bernoulli_exp(this, x
, accepted
))
121 #define MAX_SAMPLE_INDEX 16
123 METHOD(bliss_sampler_t
, pos_binary
, bool,
124 private_bliss_sampler_t
*this, uint32_t *x
)
130 for (i
= 0; i
<= MAX_SAMPLE_INDEX
; i
++)
132 if (!this->bitspender
->get_bits(this->bitspender
,
133 i
? (2*i
- 1) : 1, &u
))
147 if (i
> MAX_SAMPLE_INDEX
)
154 METHOD(bliss_sampler_t
, gaussian
, bool,
155 private_bliss_sampler_t
*this, int32_t *z
)
157 uint32_t u
, x
, y
, z_pos
;
162 if (!pos_binary(this, &x
))
169 if (!this->bitspender
->get_bits(this->bitspender
,
170 this->set
->k_sigma_bits
, &y
))
175 while (y
>= this->set
->k_sigma
);
177 if (!bernoulli_exp(this, y
* (y
+ 2*this->set
->k_sigma
* x
), &accepted
))
183 if (!this->bitspender
->get_bits(this->bitspender
, 1, &u
))
194 z_pos
= this->set
->k_sigma
* x
+ y
;
195 *z
= u
? z_pos
: -z_pos
;
200 METHOD(bliss_sampler_t
, sign
, bool,
201 private_bliss_sampler_t
*this, bool *positive
)
205 if (!this->bitspender
->get_bits(this->bitspender
, 1, &u
))
214 METHOD(bliss_sampler_t
, destroy
, void,
215 private_bliss_sampler_t
*this)
217 this->bitspender
->destroy(this->bitspender
);
225 bliss_sampler_t
*bliss_sampler_create(ext_out_function_t alg
, chunk_t seed
,
226 const bliss_param_set_t
*set
)
228 private_bliss_sampler_t
*this;
229 xof_bitspender_t
*bitspender
;
231 bitspender
= xof_bitspender_create(alg
, seed
, FALSE
);
239 .bernoulli_exp
= _bernoulli_exp
,
240 .bernoulli_cosh
= _bernoulli_cosh
,
241 .pos_binary
= _pos_binary
,
242 .gaussian
= _gaussian
,
247 .bitspender
= bitspender
,
250 return &this->public;