fsprg.c revision 29804cc1e0f37ee34301530fd7f1eb8550be464e
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/*
* fsprg v0.1 - (seekable) forward-secure pseudorandom generator
* Copyright (C) 2012 B. Poettering
* Contact: fsprg@point-at-infinity.org
*
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
/*
* See "Practical Secure Logging: Seekable Sequential Key Generators"
* by G. A. Marson, B. Poettering for details:
*
*/
#include <gcrypt.h>
#include <string.h>
#include <assert.h>
#include "fsprg.h"
#define RND_HASH GCRY_MD_SHA256
#define RND_GEN_P 0x01
#define RND_GEN_Q 0x02
#define RND_GEN_X 0x03
/******************************************************************************/
unsigned len;
assert(gcry_mpi_cmp_ui(x, 0) >= 0);
}
gcry_mpi_t h;
unsigned len;
assert(gcry_mpi_cmp_ui(h, 0) >= 0);
return h;
}
}
return
}
static void det_randomize(void *buf, size_t buflen, const void *seed, size_t seedlen, uint32_t idx) {
}
}
gcry_mpi_t p;
while (gcry_prime_check(p, 0))
gcry_mpi_add_ui(p, p, 4);
return p;
}
static gcry_mpi_t gensquare(const gcry_mpi_t n, const void *seed, size_t seedlen, uint32_t idx, unsigned secpar) {
gcry_mpi_t x;
assert(gcry_mpi_cmp(x, n) < 0);
gcry_mpi_mulm(x, x, x, n);
return x;
}
/* compute 2^m (mod phi(p)), for a prime p */
gcry_mpi_t phi, r;
int n;
phi = gcry_mpi_new(0);
/* count number of used bits in m */
for (n = 0; (1ULL << n) <= m; n++)
;
r = gcry_mpi_new(0);
gcry_mpi_set_ui(r, 1);
while (n) { /* square and multiply algorithm for fast exponentiation */
n--;
gcry_mpi_mulm(r, r, r, phi);
if (m & ((uint64_t)1 << n)) {
gcry_mpi_add(r, r, r);
if (gcry_mpi_cmp(r, phi) >= 0)
gcry_mpi_sub(r, r, phi);
}
}
return r;
}
/* Decompose $x \in Z_n$ into $(xp,xq) \in Z_p \times Z_q$ using Chinese Remainder Theorem */
static void CRT_decompose(gcry_mpi_t *xp, gcry_mpi_t *xq, const gcry_mpi_t x, const gcry_mpi_t p, const gcry_mpi_t q) {
*xp = gcry_mpi_new(0);
*xq = gcry_mpi_new(0);
gcry_mpi_mod(*xp, x, p);
gcry_mpi_mod(*xq, x, q);
}
/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */
static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) {
gcry_mpi_t a, u;
a = gcry_mpi_new(0);
u = gcry_mpi_new(0);
*x = gcry_mpi_new(0);
gcry_mpi_invm(u, p, q);
gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p (mod q) */
gcry_mpi_mul(*x, p, a);
gcry_mpi_release(a);
gcry_mpi_release(u);
}
static void initialize_libgcrypt(void) {
const char *p;
return;
p = gcry_check_version("1.4.5");
assert(p);
/* Turn off "secmem". Clients which whish to make use of this
* feature should initialize the library manually */
}
/******************************************************************************/
}
}
}
}
secpar =
}
gcry_mpi_t n, p, q;
if (!seed) {
}
if (msk) {
}
if (mpk) {
n = gcry_mpi_new(0);
gcry_mpi_mul(n, p, q);
gcry_mpi_release(n);
}
gcry_mpi_release(p);
gcry_mpi_release(q);
}
gcry_mpi_t n, x;
gcry_mpi_release(n);
gcry_mpi_release(x);
}
void FSPRG_Evolve(void *state) {
gcry_mpi_t n, x;
gcry_mpi_mulm(x, x, x, n);
epoch++;
gcry_mpi_release(n);
gcry_mpi_release(x);
}
}
n = gcry_mpi_new(0);
gcry_mpi_mul(n, p, q);
gcry_mpi_release(p);
gcry_mpi_release(q);
gcry_mpi_release(n);
gcry_mpi_release(x);
}
}