2003-03-02 19:59:24 -05:00
|
|
|
#include "mycrypt.h"
|
|
|
|
|
|
|
|
#ifdef MPI
|
|
|
|
|
2003-06-01 14:55:11 -04:00
|
|
|
#define UPPER_LIMIT PRIME_SIZE
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
/* figures out if a number is prime (MR test) */
|
|
|
|
int is_prime(mp_int *N, int *result)
|
|
|
|
{
|
2003-06-01 14:55:11 -04:00
|
|
|
int err;
|
|
|
|
if ((err = mp_prime_is_prime(N, 8, result)) != MP_OKAY) {
|
|
|
|
return CRYPT_MEM;
|
|
|
|
}
|
|
|
|
return CRYPT_OK;
|
2003-03-02 20:01:00 -05:00
|
|
|
}
|
|
|
|
|
2003-03-02 19:59:24 -05:00
|
|
|
int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
|
|
|
|
{
|
|
|
|
unsigned char buf[260];
|
2003-03-02 20:02:42 -05:00
|
|
|
int err, step, ormask;
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
_ARGCHK(N != NULL);
|
|
|
|
|
|
|
|
/* pass a negative size if you want a prime congruent to 3 mod 4 */
|
|
|
|
if (len < 0) {
|
2003-07-16 13:43:06 -04:00
|
|
|
step = 1;
|
2003-03-02 19:59:24 -05:00
|
|
|
ormask = 3;
|
|
|
|
len = -len;
|
|
|
|
} else {
|
2003-07-16 13:43:06 -04:00
|
|
|
step = 0;
|
2003-03-02 19:59:24 -05:00
|
|
|
ormask = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allow sizes between 2 and 256 bytes for a prime size */
|
|
|
|
if (len < 2 || len > 256) {
|
|
|
|
return CRYPT_INVALID_PRIME_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* valid PRNG? */
|
2003-03-02 20:02:42 -05:00
|
|
|
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
|
|
|
return err;
|
2003-03-02 19:59:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* read the prng */
|
2003-03-02 20:02:42 -05:00
|
|
|
if (prng_descriptor[wprng].read(buf+2, (unsigned long)len, prng) != (unsigned long)len) {
|
2003-03-02 19:59:24 -05:00
|
|
|
return CRYPT_ERROR_READPRNG;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set sign byte to zero */
|
2003-03-02 20:02:42 -05:00
|
|
|
buf[0] = (unsigned char)0;
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
/* Set the top byte to 0x01 which makes the number a len*8 bit number */
|
2003-03-02 20:02:42 -05:00
|
|
|
buf[1] = (unsigned char)0x01;
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
/* set the LSB to the desired settings
|
|
|
|
* (1 for any prime, 3 for primes congruent to 3 mod 4)
|
|
|
|
*/
|
2003-03-02 20:02:42 -05:00
|
|
|
buf[len+1] |= (unsigned char)ormask;
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
/* read the number in */
|
|
|
|
if (mp_read_raw(N, buf, 2+len) != MP_OKAY) {
|
|
|
|
return CRYPT_MEM;
|
|
|
|
}
|
|
|
|
|
2003-07-16 13:43:06 -04:00
|
|
|
/* Find the next prime after N */
|
|
|
|
if (mp_prime_next_prime(N, 8, step) != MP_OKAY) {
|
|
|
|
return CRYPT_MEM;
|
2003-03-02 20:01:00 -05:00
|
|
|
}
|
2003-03-02 19:59:24 -05:00
|
|
|
|
|
|
|
#ifdef CLEAN_STACK
|
|
|
|
zeromem(buf, sizeof(buf));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return CRYPT_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|