bliss: Implemented FFT with fast Montgomery arithmetic

This commit is contained in:
Andreas Steffen
2016-07-29 12:36:14 +02:00
parent 5ff88c9622
commit a7d626118f
8 changed files with 290 additions and 98 deletions
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 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
@@ -21,6 +21,7 @@
#include "bliss_signature.h"
#include "bliss_bitpacker.h"
#include "bliss_fft.h"
#include "bliss_reduce.h"
#include <crypto/mgf1/mgf1_bitspender.h>
#include <asn1/asn1.h>
@@ -63,6 +64,11 @@ struct private_bliss_private_key_t {
*/
uint32_t *A;
/**
* NTT of BLISS public key in Montgomery representation Ar = rA mod
*/
uint32_t *Ar;
/**
* reference count
*/
@@ -337,7 +343,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
for (i = 0; i < n; i++)
{
ay[i] = (this->A[i] * ay[i]) % q;
ay[i] = bliss_mreduce(this->Ar[i] * ay[i], this->set->fft_params);
}
fft->transform(fft, ay, ay, TRUE);
@@ -668,6 +674,7 @@ METHOD(private_key_t, destroy, void,
free(this->s2);
}
free(this->A);
free(this->Ar);
free(this);
}
}
@@ -795,13 +802,13 @@ static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa)
/**
* Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
*/
static uint32_t invert(uint32_t x, uint16_t q)
static uint32_t invert(private_bliss_private_key_t *this, uint32_t x)
{
uint32_t x1, x2;
uint16_t q2;
int i, i_max;
q2 = q - 2;
q2 = this->set->q - 2;
x1 = (q2 & 1) ? x : 1;
x2 = x;
i_max = 15;
@@ -812,11 +819,11 @@ static uint32_t invert(uint32_t x, uint16_t q)
}
for (i = 1; i <= i_max; i++)
{
x2 = (x2 * x2) % q;
x2 = bliss_mreduce(x2 * x2, this->set->fft_params);
if (q2 & (1 << i))
{
x1 = (x1 * x2) % q;
x1 = bliss_mreduce(x1 * x2, this->set->fft_params);
}
}
@@ -1068,7 +1075,8 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
S1 = malloc(n * sizeof(uint32_t));
S2 = malloc(n * sizeof(uint32_t));
a = malloc(n * sizeof(uint32_t));
this->A = malloc(n * sizeof(uint32_t));
this->A = malloc(n * sizeof(uint32_t));
this->Ar = malloc(n * sizeof(uint32_t));
/* Instantiate a true random generator */
rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
@@ -1091,6 +1099,7 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
fft->transform(fft, S2, S2, FALSE);
success = TRUE;
for (i = 0; i < n; i++)
{
if (S1[i] == 0)
@@ -1103,8 +1112,9 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
success = FALSE;
break;
}
this->A[i] = invert(S1[i], q);
this->A[i] = (S2[i] * this->A[i]) % q;
this->Ar[i] = invert(this, S1[i]);
this->Ar[i] = bliss_mreduce(S2[i] * this->Ar[i], set->fft_params);
this->A[i] = bliss_mreduce(this->Ar[i], set->fft_params);
}
}
while (!success && trials < SECRET_KEY_TRIALS_MAX);
@@ -1114,13 +1124,15 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
if (success)
{
fft->transform(fft, this->A, a, TRUE);
fft->transform(fft, this->Ar, a, TRUE);
DBG4(DBG_LIB, " i f g a F G A");
for (i = 0; i < n; i++)
{
DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u",
i, this->s1[i], this->s2[i], a[i], S1[i], S2[i], this->A[i]);
i, this->s1[i], this->s2[i],
bliss_mreduce(a[i], set->fft_params),
S1[i], S2[i], this->A[i]);
}
}
else
@@ -1167,7 +1179,7 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
asn1_parser_t *parser;
size_t s_bits = 0;
int8_t s, s_min = 0, s_max = 0;
uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value;
uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value, r2;
bool success = FALSE;
int objectID, oid, i;
@@ -1248,6 +1260,14 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
{
goto end;
}
this->Ar = malloc(this->set->n * sizeof(uint32_t));
r2 = this->set->fft_params->r2;
for (i = 0; i < this->set->n; i++)
{
this->Ar[i] = bliss_mreduce(this->A[i] * r2,
this->set->fft_params);
}
break;
case PRIV_KEY_SECRET1:
if (object.len != 1 + (s_bits * this->set->n + 7)/8)