/* field.c: generator and prime are defined here
   This has nothing to do with cryptography.
   Copyright (C) 1998 Paul Sheer

   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 "mostincludes.h"
#include "huge-number.h"
#include "field.h"
#include "diffie/compat.h"

#define GENERATOR 2

typedef struct {
    int size;
    char *hex;
} Primes;

/* 512 and 1536 primes are from cryptolib
 * (http://www.cs.aukuni.ac.nz/~pgut001/cryptlib/)
 * from SKIP (http://www.sun.com/security/skip/). Now something
 * bizarre: their 768 bit and 2048 bit primes only works with
 * p-new for half of the messages.
 * In other words, p-new will fail randomly half of the time for no
 * apparent reason, if these primes are used. So now I am using the
 * 768 and 1024 bit primes from a document that begins:
 *
 * IPSEC Working Group                                D. Harkins, D. Carrel
 * INTERNET-DRAFT                                             cisco Systems
 * draft-ietf-ipsec-isakmp-oakley-08.txt                          June 1998
 *
 *
 *                    The Internet Key Exchange (IKE)
 *                <draft-ietf-ipsec-isakmp-oakley-08.txt>
 *
 *
 *                          Status of this Memo
 *
 *    This document is an Internet Draft. Internet Drafts are working
 * ...
 *
 *  -paul */

static Primes primes[] =
{
    {0, 0},
    {512, "F52AFF3CE1B1294018118D7C84A70A72D686C40319C80729"
     "7ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7C"
     "BD894B221926BAABA25EC355E92A055F"
    },
    {768, "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
     "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
    },
    {1024, "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
     "FFFFFFFFFFFFFFFF"
    },
    {1536, "F8F5595FDC76524F3D3D8DDBCE99E1579259CDFDB8AE744F"
     "C5FC76BC83C5473061CE7CC966FF15F9BBFD915EC701AAD3"
     "5B9E8DA0A5723AD41AF0BF4600582BE5F488FD584E49DBCD"
     "20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6"
     "F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743"
     "A31D186CDE33212CB52AFF3CE1B1294018118D7C84A70A72"
     "D686C40319C807297ACA950CD9969FABD00A509B0246D308"
     "3D66A45D419F9C7CBD894B221926BAABA25EC355E9587C47"
    },
    {2048, ""},
    {3072, ""},
    {4096, ""},
    {6144, ""},
    {8192, ""},
    {12288, ""},
    {16384, ""},
    {24576, ""},
    {32768, ""},
    {49152, ""},
    {65536, ""},
    {98304, ""},
    {131072, ""},
    {196608, ""},
    {262144, ""},
    {393216, ""},
    {524288, ""},
    {786432, ""},
    {1048576, ""}
};

static int n_primes = sizeof (primes) / sizeof (Primes);

Huge *field_prime (int type)
{
    if (type >= n_primes || type < 1)
	return 0;
    if (!primes[type].hex)
	return 0;
    if (!*primes[type].hex)
	return 0;
    return huge_from_string (primes[type].hex, 0, 16);
}

int field_size (int type)
{
    if (type >= n_primes || type < 1)
	return 1024;
    if (!primes[type].hex)
	return 1024;
    if (!*primes[type].hex)
	return 1024;
    return primes[type].size;
}

/* returns 0 on error */
int field_type (int size)
{
    int type;
    for (type = 1; type < n_primes; type++)
	if (primes[type].size == size)
	    if (primes[type].hex)
		if (*primes[type].hex)
		    return type;
    return 0;
}
