/* prime.c - part of the Libgcrypt test suite.
   Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.

   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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.  */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "../src/gcrypt-int.h"

static int verbose;

static void
die (const char *format, ...)
{
  va_list arg_ptr;

  va_start (arg_ptr, format);
  vfprintf (stderr, format, arg_ptr);
  va_end (arg_ptr);
  exit (1);
}

static void
check_primes (void)
{
  gcry_error_t err = GPG_ERR_NO_ERROR;
  gcry_mpi_t *factors = NULL;
  gcry_mpi_t prime = NULL;
  gcry_mpi_t g;
  unsigned int i = 0;
  struct prime_spec
  {
    unsigned int prime_bits;
    unsigned int factor_bits;
    unsigned int flags;
  } prime_specs[] =
    {
      { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR },
      { 128, 0, 0 },
      { 0 },
    };

  for (i = 0; prime_specs[i].prime_bits; i++)
    {
      err = gcry_prime_generate (&prime,
				 prime_specs[i].prime_bits,
				 prime_specs[i].factor_bits,
				 &factors,
				 NULL, NULL,
				 GCRY_WEAK_RANDOM,
				 prime_specs[i].flags);
      assert (! err);
      if (verbose)
        {
          fprintf (stderr, "test %d: p = ", i);
          gcry_mpi_dump (prime);
          putc ('\n', stderr);
        }

      err = gcry_prime_check (prime, 0);
      assert (! err);

      err = gcry_prime_group_generator (&g, prime, factors, NULL);
      assert (!err);
      gcry_prime_release_factors (factors); factors = NULL;

      if (verbose)
        {
          fprintf (stderr, "     %d: g = ", i);
          gcry_mpi_dump (g);
          putc ('\n', stderr);
        }
      gcry_mpi_release (g);


      gcry_mpi_add_ui (prime, prime, 1);
      err = gcry_prime_check (prime, 0);
      assert (err);
      gcry_mpi_release (prime); prime = NULL;
    }
}


/* Print an MPI S-expression.  */
static void
print_mpi (const char *name, gcry_mpi_t a)
{
  gcry_error_t err;
  unsigned char *buf;
  int writerr = 0;

  err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
  if (err)
    die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err));

  printf ("  (%s #%s#)\n", name, buf);
  if (ferror (stdout))
    writerr++;
  if (!writerr && fflush (stdout) == EOF)
    writerr++;
  if (writerr)
    die ("writing output failed\n");
  gcry_free (buf);
}


/* Create the key for our public standard dummy CA.  */
static void
create_42prime (void)
{
  gcry_error_t err;
  char string[128*2+1];
  int i;
  gcry_mpi_t start = NULL;
  gcry_mpi_t p, q, n, t1, t2, phi, f, g, e, d, u;


  /* Our start value is a string of 0x42 values, with the exception
     that the two high order bits are set.  This is to resemble the
     way Lingcrypt generates RSA primes.  */
  for (i=0; i < 128;)
    {
      string[i++] = '4';
      string[i++] = '2';
    }
  string[i] = 0;
  string[0] = 'C';

  err = gcry_mpi_scan (&start, GCRYMPI_FMT_HEX, string, 0, NULL);
  if (err)
    die ("gcry_mpi_scan failed: %s\n", gcry_strerror (err));
  fputs ("start:", stderr); gcry_mpi_dump (start); putc ('\n', stderr);

  /* Generate two primes with p < q.  We take the first primes below
     and above a start value. */
  p = gcry_mpi_copy (start);
  gcry_mpi_sub_ui (p, p, 1);
  while (gcry_prime_check (p, 0))
    gcry_mpi_sub_ui (p, p, 2);
  fputs ("    p:", stderr); gcry_mpi_dump (p); putc ('\n', stderr);
  q = gcry_mpi_copy (start);
  gcry_mpi_add_ui (q, q, 1);
  while (gcry_prime_check (q, 0))
    gcry_mpi_add_ui (q, q, 2);
  fputs ("    q:", stderr); gcry_mpi_dump (q); putc ('\n', stderr);

  /* Compute the modulus.  */
  n = gcry_mpi_new (1024);
  gcry_mpi_mul (n, p, q);
  fputs ("    n:", stderr); gcry_mpi_dump (n); putc ('\n', stderr);
  if (gcry_mpi_get_nbits (n) != 1024)
    die ("Oops: the size of N is not 1024 but %u\n", gcry_mpi_get_nbits (n));

  /* Calculate Euler totient: phi = (p-1)(q-1) */
  t1 = gcry_mpi_new (0);
  t2 = gcry_mpi_new (0);
  phi = gcry_mpi_new (0);
  g   = gcry_mpi_new (0);
  f   = gcry_mpi_new (0);
  gcry_mpi_sub_ui (t1, p, 1);
  gcry_mpi_sub_ui (t2, q, 1);
  gcry_mpi_mul (phi, t1, t2);
  gcry_mpi_gcd (g, t1, t2);
  gcry_mpi_div (f, NULL, phi, g, -1);

  /* Check the public exponent.  */
  e = gcry_mpi_set_ui (NULL, 65537);
  if (!gcry_mpi_gcd (t1, e, phi))
    die ("Oops: E is not a generator\n");
  fputs ("    e:", stderr); gcry_mpi_dump (e); putc ('\n', stderr);

  /* Compute the secret key:  d = e^-1 mod phi */
  d = gcry_mpi_new (0);
  gcry_mpi_invm (d, e, f );
  fputs ("    d:", stderr); gcry_mpi_dump (d); putc ('\n', stderr);

  /* Compute the inverse of p and q. */
  u = gcry_mpi_new (0);
  gcry_mpi_invm (u, p, q);
  fputs ("    u:", stderr); gcry_mpi_dump (u); putc ('\n', stderr);

  /* Print the S-expression.  */
  fputs ("(private-key\n (rsa\n", stdout);
  print_mpi ("n", n);
  print_mpi ("e", e);
  print_mpi ("d", d);
  print_mpi ("p", p);
  print_mpi ("q", q);
  print_mpi ("u", u);
  fputs ("))\n", stdout);

  gcry_mpi_release (p);
  gcry_mpi_release (q);
  gcry_mpi_release (n);
  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);
  gcry_mpi_release (f);
  gcry_mpi_release (g);
  gcry_mpi_release (e);
  gcry_mpi_release (d);
  gcry_mpi_release (u);
}




int
main (int argc, char **argv)
{
  int debug = 0;
  int mode42 = 0;

  if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
    verbose = 1;
  else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
    verbose = debug = 1;
  else if ((argc > 1) && (! strcmp (argv[1], "--42")))
    verbose = debug = mode42 = 1;

  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
  if (! gcry_check_version (GCRYPT_VERSION))
    die ("version mismatch\n");

  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  if (debug)
    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);

  if (mode42)
    create_42prime ();
  else
    check_primes ();

  return 0;
}
