bliss: Implemented FFT with fast Montgomery arithmetic
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user