Annotation of embedaddon/strongswan/src/libstrongswan/plugins/bliss/bliss_sampler.c, revision 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>