Commit f4dec308 authored by Niels Möller's avatar Niels Möller

*** empty log message ***

Rev: src/dsa_keygen.c:1.1
Rev: src/dsa_keygen.h:1.1
Rev: src/lsh_keygen.c:1.1
Rev: src/prime_table.c:1.1
parent 1960c720
/* dss_keygen.c
*
* Generate dss key pairs..
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dss_keygen.h"
#include "randomness.h"
#include "sha.h"
#include <assert.h>
/* The (slow) NIST method of generating DSA primes. Algorithm 4.56 of
* Handbook of Applied Cryptography. */
#define SEED_LENGTH SHA_DIGESTSIZE
#define SEED_BITS (SEED_LENGTH * 8)
static void hash(mpz_t x, UINT8 *digest)
{
mpz_t t;
UINT8 data[SEED_LENGTH];
struct sha_ctx ctx;
mpz_init_set(t, x);
mpz_fdiv_r_2exp(t, t, SEED_BITS);
bignum_write(t, SEED_LENGTH, data);
mpz_clear(t);
sha_init(&ctx);
sha_update(&ctx, data, SEED_LENGTH);
sha_final(&ctx);
sha_digest(&ctx, digest);
}
void dss_nist_gen(mpz_t p, mpz_t q, struct randomness *r, unsigned l)
{
unsigned L;
unsigned n, b;
mpz_t s, t, c;
assert( (0 <= l) && (l <= 8) );
L = 512 + 64*l;
n = (L-1) / 160; b = (L-1) % 160;
mpz_init(s);
mpz_init(t);
mpz_init(c);
while (1)
{
{ /* Generate q */
UINT8 h1[SHA_DIGESTSIZE];
UINT8 h2[SHA_DIGESTSIZE];
mpz_init(s);
bignum_random_size(s, r, SEED_BITS);
hash(s, h1);
mpz_set(t, s);
mpz_add_ui(t, t, 1);
hash(t, h2);
memxor(h1, h2, SHA_DIGESTSIZE);
h1[0] |= 0x80;
h1[SHA_DIGESTSIZE - 1] |= 1;
bignum_parse_u(q, SHA_DIGESTSIZE, h1);
if (bignum_small_factor(q, 1000)
|| !mpz_probab_prime_p(q, 18))
/* Try new seed. */
continue;
}
/* q is a prime, with overwelming probability. */
{
unsigned size = (n+1) * SHA_DIGESTSIZE;
UINT8 *buffer = alloca(size);
unsigned i, j;
for (i = 0, j = 2; i<4096; i++, j+= n+1)
{
unsigned k;
for (k = 0; k<=n ; k++)
{
mpz_set(t, s);
mpz_add_ui(t, t, j + k);
hash(t, buffer + ( (n+1-k) *SHA_DIGESTSIZE));
}
bignum_parse_u(p, size, buffer);
mpz_fdiv_r_2exp(p, p, L);
mpz_setbit(p, L-1);
mpz_set(t, q);
mpz_mul_2exp(t, t, 1);
mpz_fdiv_r(c, p, t);
mpz_sub_ui(c, c, 1);
mpz_sub(p, p, c);
if (!bignum_small_factor(p, 1000)
&& mpz_probab_prime_p(p, 5))
{
/* Done! */
mpz_clear(s);
mpz_clear(t);
mpz_clear(c);
return;
}
}
}
}
}
void dss_find_generator(mpz_t g, struct randomness *r, mpz_t p, mpz_t q)
{
mpz_t e;
mpz_t n;
/* e = (p-1)/q */
mpz_init_set(e, p);
mpz_sub_ui(e, e, 1);
mpz_divexact(e, e, q);
/* n = p-2 = |2, 3, ... p-1| */
mpz_init_set(n, p);
mpz_sub_ui(n, n, 2);
while(1)
{
bignum_random(g, r, n);
mpz_add_ui(g, g, 2);
mpz_powm(g, g, e, p);
if (mpz_cmp_ui(g, 1))
{
/* g != 1. Finished. */
mpz_clear(e);
mpz_clear(n);
return;
}
}
}
/* dss_keygen.h
*
* Generate dss key pairs..
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_DSS_KEYGEN_H_INCLUDED
#define LSH_DSS_KEYGEN_H_INCLUDED
#include "bignum.h"
void dss_nist_gen(mpz_t p, mpz_t q, struct randomness *r, unsigned l);
void dss_find_generator(mpz_t g, struct randomness *r, mpz_t p, mpz_t q);
#endif /* LSH_DSS_KEYGEN_H_INCLUDED */
/* lsh_keygen.c
*
* Generate dss key pairs..
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dss_keygen.h"
#include "crypto.h"
#include "format.h"
#include "publickey_crypto.h"
#include "randomness.h"
#include "getopt.h"
#include <stdio.h>
static void usage(void) NORETURN;
static void usage(void)
{
fprintf(stderr, "Usage: lsh_keygen nist-level\n");
exit(1);
}
int main(int argc, char **argv)
{
int l;
struct dss_public public;
mpz_t x;
mpz_t t;
struct randomness *r;
if (argc != 2)
usage();
l = atoi(argv[1]);
if ( (l<0) || (l > 8))
usage();
mpz_init(public.p);
mpz_init(public.q);
mpz_init(public.g);
mpz_init(public.y);
mpz_init(x);
mpz_init(t);
r = make_poor_random(&sha_algorithm, NULL);
dss_nist_gen(public.p, public.q, r, l);
mpz_out_str(stderr, 16, public.p);
printf("\n");
mpz_out_str(stderr, 16, public.q);
printf("\n");
/* Sanity check. */
if (!mpz_probab_prime_p(q, 10))
{
fprintf(stderr, "p not a prime!\n");
return 1;
}
if (!mpz_probab_prime_p(q, 10))
{
fprintf(stderr, "p not a prime!\n");
return 1;
}
mpz_fdiv_r(t, p, q);
if (mpz_cmp_ui(t, 1))
{
fprintf(stderr, "q doesn't divide p-1 !\n");
return 1;
}
dss_find_generator(public.g, r, public.p, public.q);
r = make_reasonably_random();
mpz_set(t, q);
mpz_sub_ui(t, t, 2);
bignum_random(x, r, t);
mpz_add_ui(x, x, 1);
/* Now, output a private key spki structure. */
struct sexp *key =
sexp_l(2, sexp_z("private-key"),
sexp_l(6, sexp_z("dss")
sexp_l(2, sexp_z("p"), sexp_n(public.p), -1),
sexp_l(2, sexp_z("q"), sexp_n(public.q), -1),
sexp_l(2, sexp_z("g"), sexp_n(public.g), -1),
sexp_l(2, sexp_z("y"), sexp_n(public.y), -1),
sexp_l(2, sexp_z("p"), sexp_n(x), -1), -1), -2);
return 0;
}
/* $Id$
*
* Generates a table of small odd primes.
*/
#include <stdio.h>
#include <stdlib.h>
void fill_table(unsigned long *primes, unsigned long *squares, int length);
void write_table(char *program,
unsigned long *primes, unsigned long *squares, int length);
int
main(int argc, char **argv)
{
int length;
unsigned long *table;
if ( (argc != 2) || ((length = atoi(argv[1])) < 1))
{
fprintf(stderr, "Usage: %s tablesize\n", argv[0]);
exit(1);
}
table = (unsigned long *) malloc(2 * length * sizeof(*table));
fill_table(table, table + length, length);
write_table(argv[0], table, table + length, length);
return 0;
}
void
fill_table(unsigned long *primes, unsigned long *squares, int length)
{
int i;
int j;
unsigned long n;
primes[0] = 2; squares[0] = 4;
i = 1;
n = 3;
while (i < length)
{
for (j=0; (j < i) && (squares[j] <= n); j++)
{
if (n % primes[j] == 0)
/* n is no prime */
goto outer;
}
primes[i] = n; squares[i] = n*n;
i++;
outer:
n += 2;
}
}
void
write_table(char *program, unsigned long *primes, unsigned long *squares, int length)
{
int i;
printf("/* Automatically generated by\n"
" * %s %d\n"
" * Do not edit.\n"
" */\n\n", program, length);
printf("#define NUMBER_OF_PRIMES %d\n\n", length);
printf("const unsigned long primes[NUMBER_OF_PRIMES] = {");
for (i=0; i<length - 1; i++)
{
if (i % 10 == 0)
printf("\n ");
printf("%ld, ", (long)primes[i]);
}
printf("%ld };\n\n", (long)primes[i]);
#if 0
printf("const unsigned long prime_squares[NUMBER_OF_PRIMES] = {");
for (i=0; i<length - 1; i++)
{
if (i % 10 == 0)
printf("\n ");
printf("%d, ", squares[i]);
}
printf("%d };\n", squares[i]);
#endif
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment