1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner.
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works.
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h"
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @file rand_prime.c
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Generate a random prime, Tom St Denis
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define USE_BBS 1
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint rand_prime(void *N, long len, prng_state *prng, int wprng)
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int            err, res, type;
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   unsigned char *buf;
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(N != NULL);
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   /* get type */
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (len < 0) {
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      type = USE_BBS;
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      len = -len;
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   } else {
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      type = 0;
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   /* allow sizes between 2 and 512 bytes for a prime size */
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (len < 2 || len > 512) {
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_INVALID_PRIME_SIZE;
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   /* valid PRNG? Better be! */
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return err;
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   /* allocate buffer to work with */
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   buf = XCALLOC(1, len);
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (buf == NULL) {
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_MEM;
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   do {
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* generate value */
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) {
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         XFREE(buf);
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         return CRYPT_ERROR_READPRNG;
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      }
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* munge bits */
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      buf[0]     |= 0x80 | 0x40;
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* load value */
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         XFREE(buf);
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         return err;
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      }
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* test */
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) {
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         XFREE(buf);
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         return err;
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      }
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   } while (res == LTC_MP_NO);
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   zeromem(buf, len);
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   XFREE(buf);
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.6 $ */
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/03/31 14:15:35 $ */
88