libtomcrypt/prime.c
2010-06-16 12:38:02 +02:00

79 lines
1.6 KiB
C

#include "mycrypt.h"
#ifdef MPI
#define UPPER_LIMIT PRIME_SIZE
/* figures out if a number is prime (MR test) */
int is_prime(mp_int *N, int *result)
{
int err;
if ((err = mp_prime_is_prime(N, 8, result)) != MP_OKAY) {
return CRYPT_MEM;
}
return CRYPT_OK;
}
int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
{
unsigned char buf[260];
int err, step, ormask;
_ARGCHK(N != NULL);
/* pass a negative size if you want a prime congruent to 3 mod 4 */
if (len < 0) {
step = 1;
ormask = 3;
len = -len;
} else {
step = 0;
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? */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
/* read the prng */
if (prng_descriptor[wprng].read(buf+2, (unsigned long)len, prng) != (unsigned long)len) {
return CRYPT_ERROR_READPRNG;
}
/* set sign byte to zero */
buf[0] = (unsigned char)0;
/* Set the top byte to 0x01 which makes the number a len*8 bit number */
buf[1] = (unsigned char)0x01;
/* set the LSB to the desired settings
* (1 for any prime, 3 for primes congruent to 3 mod 4)
*/
buf[len+1] |= (unsigned char)ormask;
/* read the number in */
if (mp_read_raw(N, buf, 2+len) != MP_OKAY) {
return CRYPT_MEM;
}
/* Find the next prime after N */
if (mp_prime_next_prime(N, 8, step) != MP_OKAY) {
return CRYPT_MEM;
}
#ifdef CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
#endif