diff options
Diffstat (limited to 'src/libstrongswan/plugins/bliss/bliss_signature.c')
-rw-r--r-- | src/libstrongswan/plugins/bliss/bliss_signature.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.c b/src/libstrongswan/plugins/bliss/bliss_signature.c new file mode 100644 index 000000000..e603da399 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_signature.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "bliss_signature.h" +#include "bliss_bitpacker.h" +#include "bliss_huffman_coder.h" + + +typedef struct private_bliss_signature_t private_bliss_signature_t; + +/** + * Private data of a bliss_signature_t object. + */ +struct private_bliss_signature_t { + /** + * Public interface for this signer. + */ + bliss_signature_t public; + + /** + * BLISS signature parameter set + */ + bliss_param_set_t *set; + + /** + * BLISS signature vector z1 of size n + */ + int32_t *z1; + + /** + * BLISS signature vector z2d of size n + */ + int16_t *z2d; + + /** + * Indices of sparse BLISS challenge vector c of size kappa + */ + uint16_t *c_indices; + +}; + +METHOD(bliss_signature_t, get_encoding, chunk_t, + private_bliss_signature_t *this) +{ + bliss_bitpacker_t *packer; + bliss_huffman_coder_t *coder; + bliss_huffman_code_t *code; + int32_t z1; + uint32_t z1_sign; + uint16_t z2d_bits; + chunk_t encoding = chunk_empty; + int i; + + z2d_bits = this->set->z1_bits - this->set->d; + + /* Get Huffman code for this BLISS parameter set */ + code = bliss_huffman_code_get_by_id(this->set->id); + if (!code) + { + DBG1(DBG_LIB, "no Huffman code found for parameter set %N", + bliss_param_set_id_names, this->set->id); + return chunk_empty; + } + + packer = bliss_bitpacker_create(this->set->n * this->set->z1_bits + + this->set->n * z2d_bits + + this->set->kappa * this->set->n_bits); + coder = bliss_huffman_coder_create(code, packer); + + for (i = 0; i < this->set->n; i++) + { + /* determine and remove the sign of z1[i]*/ + z1_sign = this->z1[i] < 0; + z1 = z1_sign ? -this->z1[i] : this->z1[i]; + + if (!packer->write_bits(packer, z1_sign, 1) || + !packer->write_bits(packer, z1 & 0xff, 8) || + !coder->encode(coder, z1 >> 8, this->z2d[i])) + { + goto end; + } + } + for (i = 0; i < this->set->kappa; i++) + { + if (!packer->write_bits(packer, this->c_indices[i], this->set->n_bits)) + { + goto end; + } + } + encoding = packer->extract_buf(packer); + + DBG2(DBG_LIB, "efficiency of Huffman coder is %6.4f bits/tuple (%u bits)", + coder->get_bits(coder)/(double)(this->set->n), + coder->get_bits(coder)); + DBG2(DBG_LIB, "generated BLISS signature (%u bits encoded in %u bytes)", + packer->get_bits(packer), encoding.len); + + end: + coder->destroy(coder); + packer->destroy(packer); + return encoding; +} + +METHOD(bliss_signature_t, get_parameters, void, + private_bliss_signature_t *this, int32_t **z1, int16_t **z2d, + uint16_t **c_indices) +{ + *z1 = this->z1; + *z2d = this->z2d; + *c_indices = this->c_indices; +} + +METHOD(bliss_signature_t, destroy, void, + private_bliss_signature_t *this) +{ + free(this->z1); + free(this->z2d); + free(this->c_indices); + free(this); +} + +/** + * See header. + */ +bliss_signature_t *bliss_signature_create(bliss_param_set_t *set) +{ + private_bliss_signature_t *this; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .get_parameters = _get_parameters, + .destroy = _destroy, + }, + .set = set, + .z1 = malloc(set->n * sizeof(int32_t)), + .z2d = malloc(set->n * sizeof(int16_t)), + .c_indices = malloc(set->n * sizeof(uint16_t)), + ); + + return &this->public; +} + +/** + * See header. + */ +bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set, + chunk_t encoding) +{ + private_bliss_signature_t *this; + bliss_bitpacker_t *packer; + bliss_huffman_coder_t *coder; + bliss_huffman_code_t *code; + uint32_t z1_sign, z1_low, value; + int32_t z1; + int16_t z2; + int i; + + /* Get Huffman code for this BLISS parameter set */ + code = bliss_huffman_code_get_by_id(set->id); + if (!code) + { + DBG1(DBG_LIB, "no Huffman code found for parameter set %N", + bliss_param_set_id_names, set->id); + return NULL; + } + + if (encoding.len == 0) + { + DBG1(DBG_LIB, "zero length BLISS signature"); + return NULL; + } + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .get_parameters = _get_parameters, + .destroy = _destroy, + }, + .set = set, + .z1 = malloc(set->n * sizeof(int32_t)), + .z2d = malloc(set->n * sizeof(int16_t)), + .c_indices = malloc(set->n * sizeof(uint16_t)), + ); + + packer = bliss_bitpacker_create_from_data(encoding); + coder = bliss_huffman_coder_create(code, packer); + + for (i = 0; i < set->n; i++) + { + if (!packer->read_bits(packer, &z1_sign, 1) || + !packer->read_bits(packer, &z1_low, 8) || + !coder->decode(coder, &z1, &z2)) + { + DBG1(DBG_LIB, "truncated BLISS signature encoding of z1/z2"); + coder->destroy(coder); + packer->destroy(packer); + destroy(this); + return NULL; + } + z1 = (z1 << 8) + z1_low; + this->z1[i] = z1_sign ? -z1 : z1; + this->z2d[i] = z2; + } + coder->destroy(coder); + + for (i = 0; i < set->kappa; i++) + { + if (!packer->read_bits(packer, &value, set->n_bits)) + { + DBG1(DBG_LIB, "truncated BLISS signature encoding of c_indices"); + packer->destroy(packer); + destroy(this); + return NULL; + } + this->c_indices[i] = value; + } + packer->destroy(packer); + + return &this->public; +} |