mgf1: Refactored MGF1 as an XOF
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
#include "ntt_fft.h"
|
||||
#include "ntt_fft_reduce.h"
|
||||
|
||||
#include <crypto/mgf1/mgf1_bitspender.h>
|
||||
#include <crypto/xofs/xof_bitspender.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
@@ -174,7 +174,8 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
|
||||
bliss_sampler_t *sampler = NULL;
|
||||
rng_t *rng;
|
||||
hasher_t *hasher;
|
||||
hash_algorithm_t mgf1_alg, oracle_alg;
|
||||
hash_algorithm_t mgf1_alg;
|
||||
ext_out_function_t oracle_alg;
|
||||
size_t mgf1_seed_len;
|
||||
uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
|
||||
chunk_t mgf1_seed, data_hash;
|
||||
@@ -226,7 +227,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
|
||||
}
|
||||
|
||||
/* MGF1 hash algorithm to be used for random oracle */
|
||||
oracle_alg = HASH_SHA512;
|
||||
oracle_alg = XOF_MGF1_SHA512;
|
||||
|
||||
/* Initialize a couple of needed variables */
|
||||
n = this->set->n;
|
||||
@@ -834,14 +835,14 @@ static uint32_t invert(private_bliss_private_key_t *this, uint32_t x)
|
||||
* Create a vector with sparse and small coefficients from seed
|
||||
*/
|
||||
static int8_t* create_vector_from_seed(private_bliss_private_key_t *this,
|
||||
hash_algorithm_t alg, chunk_t seed)
|
||||
ext_out_function_t alg, chunk_t seed)
|
||||
{
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
uint32_t index, sign;
|
||||
int8_t *vector;
|
||||
int non_zero;
|
||||
|
||||
bitspender = mgf1_bitspender_create(alg, seed, FALSE);
|
||||
bitspender = xof_bitspender_create(alg, seed, FALSE);
|
||||
if (!bitspender)
|
||||
{
|
||||
return NULL;
|
||||
@@ -910,7 +911,7 @@ static bool create_secret(private_bliss_private_key_t *this, rng_t *rng,
|
||||
int i, n;
|
||||
chunk_t seed;
|
||||
size_t seed_len;
|
||||
hash_algorithm_t alg;
|
||||
ext_out_function_t alg;
|
||||
|
||||
n = this->set->n;
|
||||
*s1 = NULL;
|
||||
@@ -919,12 +920,12 @@ static bool create_secret(private_bliss_private_key_t *this, rng_t *rng,
|
||||
/* Set MGF1 hash algorithm and seed length based on security strength */
|
||||
if (this->set->strength > 160)
|
||||
{
|
||||
alg = HASH_SHA256;
|
||||
alg = XOF_MGF1_SHA256;
|
||||
seed_len = HASH_SIZE_SHA256;
|
||||
}
|
||||
else
|
||||
{
|
||||
alg = HASH_SHA1;
|
||||
alg = XOF_MGF1_SHA1;
|
||||
seed_len = HASH_SIZE_SHA1;
|
||||
}
|
||||
seed = chunk_create(seed_buf, seed_len);
|
||||
|
||||
@@ -76,7 +76,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
|
||||
uint8_t data_hash_buf[HASH_SIZE_SHA512];
|
||||
chunk_t data_hash;
|
||||
hasher_t *hasher;
|
||||
hash_algorithm_t oracle_alg;
|
||||
ext_out_function_t oracle_alg;
|
||||
ntt_fft_t *fft;
|
||||
bliss_signature_t *sig;
|
||||
bool success = FALSE;
|
||||
@@ -110,7 +110,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
|
||||
}
|
||||
|
||||
/* MGF1 hash algorithm to be used for random oracle */
|
||||
oracle_alg = HASH_SHA512;
|
||||
oracle_alg = XOF_MGF1_SHA512;
|
||||
|
||||
/* Initialize a couple of needed variables */
|
||||
n = this->set->n;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
typedef struct private_bliss_sampler_t private_bliss_sampler_t;
|
||||
|
||||
#include <crypto/mgf1/mgf1_bitspender.h>
|
||||
#include <crypto/xofs/xof_bitspender.h>
|
||||
|
||||
/**
|
||||
* Private data of a bliss_sampler_t object.
|
||||
@@ -37,7 +37,7 @@ struct private_bliss_sampler_t {
|
||||
/**
|
||||
* Bitspender used for random rejection sampling
|
||||
*/
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
|
||||
};
|
||||
|
||||
@@ -222,13 +222,13 @@ METHOD(bliss_sampler_t, destroy, void,
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
|
||||
bliss_sampler_t *bliss_sampler_create(ext_out_function_t alg, chunk_t seed,
|
||||
const bliss_param_set_t *set)
|
||||
{
|
||||
private_bliss_sampler_t *this;
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
|
||||
bitspender = mgf1_bitspender_create(alg, seed, FALSE);
|
||||
bitspender = xof_bitspender_create(alg, seed, FALSE);
|
||||
if (!bitspender)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -84,11 +84,11 @@ struct bliss_sampler_t {
|
||||
/**
|
||||
* Create a bliss_sampler_t object.
|
||||
*
|
||||
* @param alg Hash algorithm to be used for the internal bitspender
|
||||
* @param alg XOF to be used for the internal bitspender
|
||||
* @param seed Seed used to initialize the internal bitspender
|
||||
* @param set BLISS parameter set to be used
|
||||
*/
|
||||
bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
|
||||
bliss_sampler_t *bliss_sampler_create(ext_out_function_t alg, chunk_t seed,
|
||||
const bliss_param_set_t *set);
|
||||
|
||||
#endif /** BLISS_SAMPLER_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andreas Steffen
|
||||
* Copyright (C) 2014-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <asn1/asn1.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/mgf1/mgf1_bitspender.h>
|
||||
#include <crypto/xofs/xof_bitspender.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ void bliss_utils_round_and_drop(const bliss_param_set_t *set,
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
|
||||
bool bliss_utils_generate_c(ext_out_function_t alg, chunk_t data_hash,
|
||||
uint16_t *ud, const bliss_param_set_t *set,
|
||||
uint16_t *c_indices)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
|
||||
uint32_t index;
|
||||
uint8_t *seed_pos;
|
||||
chunk_t seed;
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
|
||||
seed = chunk_alloca(data_hash.len + set->n * sizeof(uint16_t));
|
||||
|
||||
@@ -80,7 +80,7 @@ bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
|
||||
seed_pos += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
bitspender = mgf1_bitspender_create(alg, seed, FALSE);
|
||||
bitspender = xof_bitspender_create(alg, seed, FALSE);
|
||||
if (!bitspender)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -48,23 +48,23 @@ void bliss_utils_round_and_drop(const bliss_param_set_t *set,
|
||||
/**
|
||||
* Generate the binary challenge vector c as an array of kappa indices
|
||||
*
|
||||
* @param alg hash algorithm to be used for the internal oracle
|
||||
* @param data_hash hash of the data to be signed
|
||||
* @param ud input vector ud of size n
|
||||
* @param set BLISS parameter set to be used (n, n_bits, kappa)
|
||||
* @param c_indices indexes of non-zero challenge coefficients
|
||||
* @param alg XOF to be used for the internal oracle
|
||||
* @param data_hash hash of the data to be signed
|
||||
* @param ud input vector ud of size n
|
||||
* @param set BLISS parameter set to be used (n, n_bits, kappa)
|
||||
* @param c_indices indexes of non-zero challenge coefficients
|
||||
*/
|
||||
bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
|
||||
bool bliss_utils_generate_c(ext_out_function_t alg, chunk_t data_hash,
|
||||
uint16_t *ud, const bliss_param_set_t *set,
|
||||
uint16_t *c_indices);
|
||||
|
||||
/**
|
||||
* Check the infinity and l2 norms of the vectors z1 and z2d << d
|
||||
*
|
||||
* @param set BLISS parameter set
|
||||
* @param z1 input vector
|
||||
* @param z2d input vector
|
||||
* @result TRUE if infinite and l2 norms do not exceed boundaries
|
||||
* @param set BLISS parameter set
|
||||
* @param z1 input vector
|
||||
* @param z2d input vector
|
||||
* @result TRUE if infinite and l2 norms do not exceed boundaries
|
||||
*/
|
||||
bool bliss_utils_check_norms(const bliss_param_set_t *set,
|
||||
int32_t *z1, int16_t *z2d);
|
||||
|
||||
@@ -44,6 +44,12 @@ struct private_chapoly_xof_t {
|
||||
chapoly_drv_t *drv;
|
||||
};
|
||||
|
||||
METHOD(xof_t, get_type, ext_out_function_t,
|
||||
private_chapoly_xof_t *this)
|
||||
{
|
||||
return XOF_CHACHA20;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_bytes, bool,
|
||||
private_chapoly_xof_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
@@ -53,7 +59,7 @@ METHOD(xof_t, get_bytes, bool,
|
||||
len = min(out_len, CHACHA_BLOCK_SIZE - this->stream_index);
|
||||
if (len)
|
||||
{
|
||||
memcpy(buffer + index, this->stream + this->stream_index, len);
|
||||
memcpy(buffer, this->stream + this->stream_index, len);
|
||||
index += len;
|
||||
this->stream_index += len;
|
||||
}
|
||||
@@ -151,6 +157,7 @@ chapoly_xof_t *chapoly_xof_create(ext_out_function_t algorithm)
|
||||
INIT(this,
|
||||
.public = {
|
||||
.xof_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.get_block_size = _get_block_size,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-mgf1.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-mgf1.la
|
||||
endif
|
||||
|
||||
libstrongswan_mgf1_la_SOURCES = \
|
||||
mgf1_plugin.h mgf1_plugin.c \
|
||||
mgf1_xof.h mgf1_xof.c
|
||||
|
||||
libstrongswan_mgf1_la_LDFLAGS = -module -avoid-version
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 "mgf1_plugin.h"
|
||||
#include "mgf1_xof.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct private_mgf1_plugin_t private_mgf1_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of mgf1_plugin
|
||||
*/
|
||||
struct private_mgf1_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
mgf1_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_mgf1_plugin_t *this)
|
||||
{
|
||||
return "mgf1";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_mgf1_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(XOF, mgf1_xof_create),
|
||||
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA1),
|
||||
PLUGIN_DEPENDS(HASHER, HASH_SHA1),
|
||||
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA256),
|
||||
PLUGIN_DEPENDS(HASHER, HASH_SHA256),
|
||||
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA512),
|
||||
PLUGIN_DEPENDS(HASHER, HASH_SHA512),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_mgf1_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *mgf1_plugin_create()
|
||||
{
|
||||
private_mgf1_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mgf1_p mgf1
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup mgf1_plugin mgf1_plugin
|
||||
* @{ @ingroup mgf1_p
|
||||
*/
|
||||
|
||||
#ifndef MGF1_PLUGIN_H_
|
||||
#define MGF1_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct mgf1_plugin_t mgf1_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing the MGF1 Mask Generator Function in software.
|
||||
*/
|
||||
struct mgf1_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** MGF1_PLUGIN_H_ @}*/
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2016 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 "mgf1_xof.h"
|
||||
|
||||
#include "crypto/hashers/hasher.h"
|
||||
#include "utils/debug.h"
|
||||
|
||||
typedef struct private_mgf1_xof_t private_mgf1_xof_t;
|
||||
|
||||
/**
|
||||
* Private data of an mgf1_xof_t object.
|
||||
*/
|
||||
struct private_mgf1_xof_t {
|
||||
|
||||
/**
|
||||
* Public mgf1_xof_t interface.
|
||||
*/
|
||||
mgf1_xof_t public;
|
||||
|
||||
/**
|
||||
* XOF type of the MGF1 Mask Generation Function
|
||||
*/
|
||||
ext_out_function_t type;
|
||||
|
||||
/**
|
||||
* Hasher the MGF1 Mask Generation Function is based on
|
||||
*/
|
||||
hasher_t *hasher;
|
||||
|
||||
/**
|
||||
* Is the seed hashed before using it as a seed for MGF1 ?
|
||||
*/
|
||||
bool hash_seed;
|
||||
|
||||
/**
|
||||
* Counter
|
||||
*/
|
||||
uint32_t counter;
|
||||
|
||||
/**
|
||||
* Set if counter has reached 2^32
|
||||
*/
|
||||
bool overflow;
|
||||
|
||||
/**
|
||||
* Current state to be hashed
|
||||
*/
|
||||
chunk_t state;
|
||||
|
||||
/**
|
||||
* Position of the 4 octet counter string
|
||||
*/
|
||||
uint8_t *ctr_str;
|
||||
|
||||
/**
|
||||
* Latest hash block
|
||||
*/
|
||||
uint8_t buf[HASH_SIZE_SHA512];
|
||||
|
||||
/**
|
||||
* Index pointing to the current position in the hash block
|
||||
*/
|
||||
size_t buf_index;
|
||||
|
||||
};
|
||||
|
||||
METHOD(xof_t, get_type, ext_out_function_t,
|
||||
private_mgf1_xof_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
static bool get_next_block(private_mgf1_xof_t *this, uint8_t *buffer)
|
||||
{
|
||||
/* detect overflow, set counter string and increment counter */
|
||||
if (this->overflow)
|
||||
{
|
||||
DBG1(DBG_LIB, "MGF1 overflow occurred");
|
||||
return FALSE;
|
||||
}
|
||||
htoun32(this->ctr_str, this->counter++);
|
||||
if (this->counter == 0)
|
||||
{
|
||||
this->overflow = TRUE;
|
||||
}
|
||||
|
||||
/* get the next block from the hash function */
|
||||
if (!this->hasher->get_hash(this->hasher, this->state, buffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_bytes, bool,
|
||||
private_mgf1_xof_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
size_t index = 0, blocks, len, hash_size;
|
||||
|
||||
hash_size = this->hasher->get_hash_size(this->hasher);
|
||||
|
||||
/* empty the current hash block buffer first */
|
||||
len = min(out_len, hash_size - this->buf_index);
|
||||
if (len)
|
||||
{
|
||||
memcpy(buffer, this->buf + this->buf_index, len);
|
||||
index += len;
|
||||
this->buf_index += len;
|
||||
}
|
||||
|
||||
/* copy whole hash blocks directly to output buffer */
|
||||
blocks = (out_len - index) / hash_size;
|
||||
while (blocks--)
|
||||
{
|
||||
if (!get_next_block(this, buffer + index))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
index += hash_size;
|
||||
}
|
||||
|
||||
/* get another hash block if some more output bytes are needed */
|
||||
len = out_len - index;
|
||||
if (len)
|
||||
{
|
||||
if (!get_next_block(this, this->buf))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(buffer + index, this->buf, len);
|
||||
this->buf_index = len;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(xof_t, allocate_bytes, bool,
|
||||
private_mgf1_xof_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(out_len);
|
||||
|
||||
if (!get_bytes(this, out_len, chunk->ptr))
|
||||
{
|
||||
chunk_free(chunk);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_block_size, size_t,
|
||||
private_mgf1_xof_t *this)
|
||||
{
|
||||
return this->hasher->get_hash_size(this->hasher);
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_seed_size, size_t,
|
||||
private_mgf1_xof_t *this)
|
||||
{
|
||||
return this->hasher->get_hash_size(this->hasher);
|
||||
}
|
||||
|
||||
METHOD(xof_t, set_seed, bool,
|
||||
private_mgf1_xof_t *this, chunk_t seed)
|
||||
{
|
||||
size_t hash_size, state_len;
|
||||
|
||||
if (seed.len == 0)
|
||||
{
|
||||
DBG1(DBG_LIB, "empty seed for MGF1");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* determine state size and allocate space accordingly */
|
||||
hash_size = this->hasher->get_hash_size(this->hasher);
|
||||
state_len = (this->hash_seed ? hash_size : seed.len) + 4;
|
||||
chunk_clear(&this->state);
|
||||
this->state = chunk_alloc(state_len);
|
||||
|
||||
/* hash block buffer is empty */
|
||||
this->buf_index = hash_size;
|
||||
|
||||
/* reset counter */
|
||||
this->counter = 0;
|
||||
|
||||
/* determine position of the 4 octet counter string */
|
||||
this->ctr_str = this->state.ptr + state_len - 4;
|
||||
|
||||
if (this->hash_seed)
|
||||
{
|
||||
if (!this->hasher->get_hash(this->hasher, seed, this->state.ptr))
|
||||
{
|
||||
DBG1(DBG_LIB, "failed to hash seed for MGF1");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(this->state.ptr, seed.ptr, seed.len);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(xof_t, destroy, void,
|
||||
private_mgf1_xof_t *this)
|
||||
{
|
||||
this->hasher->destroy(this->hasher);
|
||||
chunk_clear(&this->state);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(mgf1_t, set_hash_seed, void,
|
||||
private_mgf1_xof_t *this, bool yes)
|
||||
{
|
||||
this->hash_seed = yes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm)
|
||||
{
|
||||
private_mgf1_xof_t *this;
|
||||
hash_algorithm_t hash_alg;
|
||||
hasher_t *hasher;
|
||||
|
||||
switch (algorithm)
|
||||
{
|
||||
case XOF_MGF1_SHA1:
|
||||
hash_alg = HASH_SHA1;
|
||||
break;
|
||||
case XOF_MGF1_SHA256:
|
||||
hash_alg = HASH_SHA256;
|
||||
break;
|
||||
case XOF_MGF1_SHA512:
|
||||
hash_alg = HASH_SHA512;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
|
||||
if (!hasher)
|
||||
{
|
||||
DBG1(DBG_LIB, "failed to create %N hasher for MGF1",
|
||||
hash_algorithm_names, hash_alg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.mgf1_interface = {
|
||||
.xof_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.get_block_size = _get_block_size,
|
||||
.get_seed_size = _get_seed_size,
|
||||
.set_seed = _set_seed,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.set_hash_seed = _set_hash_seed,
|
||||
},
|
||||
},
|
||||
.type = algorithm,
|
||||
.hasher = hasher,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mgf1_xof mgf1_xof
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef MGF1_XOF_H_
|
||||
#define MGF1_XOF_H_
|
||||
|
||||
typedef struct mgf1_xof_t mgf1_xof_t;
|
||||
|
||||
#include <crypto/xofs/mgf1.h>
|
||||
|
||||
/**
|
||||
* Implements the PKCS#1 MGF1_XOF Mask Generation Function based on a hash
|
||||
* function defined in section 10.2.1 of RFC 2437
|
||||
*/
|
||||
struct mgf1_xof_t {
|
||||
|
||||
/**
|
||||
* mgf1_t interface for this Extended Output Function (XOF).
|
||||
*/
|
||||
mgf1_t mgf1_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an mgf1_xof_t object
|
||||
*
|
||||
* @param algorithm XOF_MGF1_SHA1, XOF_MGF1_SHA256 or XOF_MGF1_SHA512
|
||||
* @return mgf1_xof_t object, NULL if not supported
|
||||
*/
|
||||
mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm);
|
||||
|
||||
#endif /** MGF1_XOF_H_ @}*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andreas Steffen
|
||||
* Copyright (C) 2014-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "ntru_poly.h"
|
||||
|
||||
#include <crypto/mgf1/mgf1_bitspender.h>
|
||||
#include <crypto/xofs/xof_bitspender.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/test.h>
|
||||
|
||||
@@ -290,8 +290,9 @@ static private_ntru_poly_t* ntru_poly_create(uint16_t N, uint16_t q,
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
|
||||
uint8_t c_bits, uint16_t N, uint16_t q,
|
||||
ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t mgf1_type,
|
||||
chunk_t seed, uint8_t c_bits,
|
||||
uint16_t N, uint16_t q,
|
||||
uint32_t indices_len_p,
|
||||
uint32_t indices_len_m,
|
||||
bool is_product_form)
|
||||
@@ -300,9 +301,9 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
|
||||
int n, num_indices, index_i = 0;
|
||||
uint32_t index, limit;
|
||||
uint8_t *used;
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
|
||||
bitspender = mgf1_bitspender_create(alg, seed, TRUE);
|
||||
bitspender = xof_bitspender_create(mgf1_type, seed, TRUE);
|
||||
if (!bitspender)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andreas Steffen
|
||||
* Copyright (C) 2014-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -24,6 +24,7 @@
|
||||
typedef struct ntru_poly_t ntru_poly_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/xofs/xof.h>
|
||||
|
||||
/**
|
||||
* Implements a trinary polynomial storing the indices of non-zero coefficients
|
||||
@@ -63,9 +64,9 @@ struct ntru_poly_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a trits polynomial from a seed using MGF1 with a base hash function
|
||||
* Create a trits polynomial from a seed using MGF1
|
||||
*
|
||||
* @param alg hash algorithm to be used by MGF1
|
||||
* @param alg MGF1 algorithm used(XOF_MGF1_SHA1 or XOF_MGF_SHA256)
|
||||
* @param seed seed used by MGF1 to generate trits from
|
||||
* @param N ring dimension, number of polynomial coefficients
|
||||
* @param q large modulus
|
||||
@@ -74,7 +75,7 @@ struct ntru_poly_t {
|
||||
* @param indices_len_m number of indices for -1 coefficients
|
||||
* @param is_product_form generate multiple polynomials
|
||||
*/
|
||||
ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
|
||||
ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t alg, chunk_t seed,
|
||||
uint8_t c_bits, uint16_t N, uint16_t q,
|
||||
uint32_t indices_len_p,
|
||||
uint32_t indices_len_m,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andreas Steffen
|
||||
* Copyright (C) 2014-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
@@ -178,7 +178,7 @@ bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
|
||||
METHOD(ntru_private_key_t, decrypt, bool,
|
||||
private_ntru_private_key_t *this, chunk_t ciphertext, chunk_t *plaintext)
|
||||
{
|
||||
hash_algorithm_t hash_algid;
|
||||
ext_out_function_t alg;
|
||||
size_t t_len, seed1_len, seed2_len;
|
||||
uint16_t *t1, *t2, *t = NULL;
|
||||
uint16_t mod_q_mask, q_mod_p, cmprime_len, cm_len = 0, num_zeros;
|
||||
@@ -206,9 +206,9 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
||||
Mtrin = (uint8_t *)t1;
|
||||
M = Mtrin + this->params->N;
|
||||
|
||||
/* set hash algorithm based on security strength */
|
||||
hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 :
|
||||
HASH_SHA256;
|
||||
/* set MGF1 algorithm type based on security strength */
|
||||
alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
|
||||
XOF_MGF1_SHA256;
|
||||
|
||||
/* set constants */
|
||||
mod_q_mask = this->params->q - 1;
|
||||
@@ -307,7 +307,7 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
||||
ntru_coeffs_mod4_2_octets(this->params->N, t2, seed.ptr);
|
||||
|
||||
/* form mask */
|
||||
mask = ntru_trits_create(this->params->N, hash_algid, seed);
|
||||
mask = ntru_trits_create(this->params->N, alg, seed);
|
||||
if (!mask)
|
||||
{
|
||||
DBG1(DBG_LIB, "mask creation failed");
|
||||
@@ -390,9 +390,8 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
||||
|
||||
/* generate cr */
|
||||
DBG2(DBG_LIB, "generate polynomial r");
|
||||
r_poly = ntru_poly_create_from_seed(hash_algid, seed,
|
||||
this->params->c_bits, this->params->N,
|
||||
this->params->q, this->params->dF_r,
|
||||
r_poly = ntru_poly_create_from_seed(alg, seed, this->params->c_bits,
|
||||
this->params->N, this->params->q, this->params->dF_r,
|
||||
this->params->dF_r, this->params->is_product_form);
|
||||
if (!r_poly)
|
||||
{
|
||||
@@ -648,7 +647,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
|
||||
size_t t_len;
|
||||
uint16_t *t1, *t2, *t = NULL;
|
||||
uint16_t mod_q_mask;
|
||||
hash_algorithm_t hash_algid;
|
||||
ext_out_function_t alg;
|
||||
ntru_poly_t *g_poly;
|
||||
chunk_t seed;
|
||||
int i;
|
||||
@@ -667,14 +666,8 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
|
||||
);
|
||||
|
||||
/* set hash algorithm and seed length based on security strength */
|
||||
if (params->sec_strength_len <= 20)
|
||||
{
|
||||
hash_algid = HASH_SHA1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_algid = HASH_SHA256;
|
||||
}
|
||||
alg = (params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
|
||||
XOF_MGF1_SHA256;
|
||||
seed =chunk_alloc(params->sec_strength_len + 8);
|
||||
|
||||
/* get random seed for generating trinary F as a list of indices */
|
||||
@@ -685,7 +678,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
|
||||
}
|
||||
|
||||
DBG2(DBG_LIB, "generate polynomial F");
|
||||
this->privkey = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
|
||||
this->privkey = ntru_poly_create_from_seed(alg, seed, params->c_bits,
|
||||
params->N, params->q,
|
||||
params->dF_r, params->dF_r,
|
||||
params->is_product_form);
|
||||
@@ -729,7 +722,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
|
||||
}
|
||||
|
||||
DBG2(DBG_LIB, "generate polynomial g");
|
||||
g_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
|
||||
g_poly = ntru_poly_create_from_seed(alg, seed, params->c_bits,
|
||||
params->N, params->q, params->dg + 1,
|
||||
params->dg, FALSE);
|
||||
if (!g_poly)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andreas Steffen
|
||||
* Copyright (C) 2014-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
@@ -102,7 +102,7 @@ extern bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt);
|
||||
METHOD(ntru_public_key_t, encrypt, bool,
|
||||
private_ntru_public_key_t *this, chunk_t plaintext, chunk_t *ciphertext)
|
||||
{
|
||||
hash_algorithm_t hash_algid;
|
||||
ext_out_function_t alg;
|
||||
size_t t_len, seed1_len, seed2_len;
|
||||
uint16_t *t1, *t = NULL;
|
||||
uint8_t b[MAX_SEC_STRENGTH_LEN];
|
||||
@@ -139,8 +139,8 @@ METHOD(ntru_public_key_t, encrypt, bool,
|
||||
M = Mtrin + this->params->N;
|
||||
|
||||
/* set hash algorithm based on security strength */
|
||||
hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 :
|
||||
HASH_SHA256;
|
||||
alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
|
||||
XOF_MGF1_SHA256;
|
||||
/* set constants */
|
||||
mod_q_mask = this->params->q - 1;
|
||||
|
||||
@@ -173,7 +173,7 @@ METHOD(ntru_public_key_t, encrypt, bool,
|
||||
seed.len = seed2_len;
|
||||
|
||||
DBG2(DBG_LIB, "generate polynomial r");
|
||||
r_poly = ntru_poly_create_from_seed(hash_algid, seed, this->params->c_bits,
|
||||
r_poly = ntru_poly_create_from_seed(alg, seed, this->params->c_bits,
|
||||
this->params->N, this->params->q,
|
||||
this->params->dF_r, this->params->dF_r,
|
||||
this->params->is_product_form);
|
||||
@@ -191,7 +191,7 @@ METHOD(ntru_public_key_t, encrypt, bool,
|
||||
seed.len = seed1_len;
|
||||
|
||||
/* form mask */
|
||||
mask = ntru_trits_create(this->params->N, hash_algid, seed);
|
||||
mask = ntru_trits_create(this->params->N, alg, seed);
|
||||
if (!mask)
|
||||
{
|
||||
DBG1(DBG_LIB, "mask creation failed");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Andreas Steffen
|
||||
* Copyright (C) 2013-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "ntru_trits.h"
|
||||
#include "ntru_convert.h"
|
||||
|
||||
#include <crypto/mgf1/mgf1_bitspender.h>
|
||||
#include <crypto/xofs/xof_bitspender.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/test.h>
|
||||
|
||||
@@ -67,14 +67,15 @@ METHOD(ntru_trits_t, destroy, void,
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
|
||||
ntru_trits_t *ntru_trits_create(size_t len, ext_out_function_t alg,
|
||||
chunk_t seed)
|
||||
{
|
||||
private_ntru_trits_t *this;
|
||||
uint8_t octet, buf[5], *trits;
|
||||
size_t trits_needed;
|
||||
mgf1_bitspender_t *bitspender;
|
||||
xof_bitspender_t *bitspender;
|
||||
|
||||
bitspender = mgf1_bitspender_create(alg, seed, TRUE);
|
||||
bitspender = xof_bitspender_create(alg, seed, TRUE);
|
||||
if (!bitspender)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* Copyright (C) 2013-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -24,6 +24,7 @@
|
||||
typedef struct ntru_trits_t ntru_trits_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/xofs/xof.h>
|
||||
|
||||
/**
|
||||
* Implements an array of trinary elements (trits)
|
||||
@@ -52,10 +53,11 @@ struct ntru_trits_t {
|
||||
* Create a trits array from a seed using MGF1 with a base hash function
|
||||
*
|
||||
* @param size size of the trits array
|
||||
* @param alg hash algorithm to be used by MGF1
|
||||
* @param alg MGF1 algorithm used (XOF_MGF1_SHA1 or XOF_MGF_SHA256)
|
||||
* @param seed seed used by MGF1 to generate trits from
|
||||
*/
|
||||
ntru_trits_t *ntru_trits_create(size_t size, hash_algorithm_t alg, chunk_t seed);
|
||||
ntru_trits_t *ntru_trits_create(size_t size, ext_out_function_t alg,
|
||||
chunk_t seed);
|
||||
|
||||
#endif /** NTRU_TRITS_H_ @}*/
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ struct private_sha3_shake_t {
|
||||
|
||||
};
|
||||
|
||||
METHOD(xof_t, get_type, ext_out_function_t,
|
||||
private_sha3_shake_t *this)
|
||||
{
|
||||
return this->algorithm;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_bytes, bool,
|
||||
private_sha3_shake_t *this, size_t out_len, uint8_t *buffer)
|
||||
@@ -114,6 +119,7 @@ sha3_shake_t* sha3_shake_create(ext_out_function_t algorithm)
|
||||
INIT(this,
|
||||
.public = {
|
||||
.xof_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.get_block_size = _get_block_size,
|
||||
|
||||
Reference in New Issue
Block a user