Return to bliss_sampler.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / bliss |
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: }