Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfixes to fp_prime_random_ex #4

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions src/headers/tfm.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* TomsFastMath, a fast ISO C bignum library.
*
*
* This project is meant to fill in where LibTomMath
* falls short. That is speed ;-)
*
* This project is public domain and free for all purposes.
*
*
* Tom St Denis, [email protected]
*/
#ifndef TFM_H_
Expand All @@ -27,13 +27,13 @@
/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */
#ifndef TFM_ALREADY_SET

/* do we want the large set of small multiplications ?
/* do we want the large set of small multiplications ?
Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC
Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-)
*/
#define TFM_SMALL_SET

/* do we want huge code
/* do we want huge code
Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA)
Less important on 64-bit machines as 32 digits == 2048 bits
*/
Expand Down Expand Up @@ -81,7 +81,7 @@
/* #define TFM_PRESCOTT */

/* Do we want timing resistant fp_exptmod() ?
* This makes it slower but also timing invariant with respect to the exponent
* This makes it slower but also timing invariant with respect to the exponent
*/
/* #define TFM_TIMING_RESISTANT */

Expand All @@ -106,7 +106,7 @@

/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */
#if defined(__x86_64__)
#if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)
#if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)
#error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)
Expand All @@ -121,7 +121,7 @@

/* try to detect x86-32 */
#if defined(__i386__) && !defined(TFM_SSE2)
#if defined(TFM_X86_64) || defined(TFM_ARM)
#if defined(TFM_X86_64) || defined(TFM_ARM)
#error x86-32 detected, x86-64/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86) && !defined(TFM_NO_ASM)
Expand Down Expand Up @@ -185,7 +185,7 @@
#undef TFM_PPC32
#undef TFM_PPC64
#undef TFM_AVR32
#undef TFM_ASM
#undef TFM_ASM
#endif

/* ECC helpers */
Expand Down Expand Up @@ -249,10 +249,11 @@
#endif
typedef ulong64 fp_digit;
typedef unsigned long fp_word __attribute__ ((mode(TI)));
#define DIGIT_SHIFT 6
#else
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
#if defined(_MSC_VER) || defined(__BORLANDC__)
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
#else
Expand All @@ -262,6 +263,7 @@
#endif
typedef unsigned long fp_digit;
typedef ulong64 fp_word;
#define DIGIT_SHIFT 5
#endif

/* # of digits this is */
Expand Down Expand Up @@ -290,7 +292,7 @@
/* a FP type */
typedef struct {
fp_digit dp[FP_SIZE];
int used,
int used,
sign;
} fp_int;

Expand Down Expand Up @@ -434,9 +436,9 @@ int fp_isprime(fp_int *a);
/* callback for fp_prime_random, should fill dst with random bytes and return how many read [upto len] */
typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);

#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)
#define fp_prime_random(a, size, bbs, cb, dat) fp_prime_random_ex(a, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)

int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);
int fp_prime_random_ex(fp_int *a, int size, int flags, tfm_prime_callback cb, void *dat);

/* radix conersions */
int fp_count_bits(fp_int *a);
Expand Down
83 changes: 41 additions & 42 deletions src/numtheory/fp_prime_random_ex.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
/* TomsFastMath, a fast ISO C bignum library.
*
*
* This project is meant to fill in where LibTomMath
* falls short. That is speed ;-)
*
* This project is public domain and free for all purposes.
*
*
* Tom St Denis, [email protected]
*/
#include <tfm.h>

#define fp_on_bitnum(a, bitnum) \
a->dp[(bitnum) >> DIGIT_SHIFT] |= (fp_digit)1 << ((bitnum) & (DIGIT_BIT-1))

#define fp_off_bitnum(a, bitnum) \
a->dp[(bitnum) >> DIGIT_SHIFT] &= ~((fp_digit)1 << ((bitnum) & (DIGIT_BIT-1)))

/* This is possibly the mother of all prime generation functions, muahahahahaha! */
int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat)
int fp_prime_random_ex(fp_int *a, int size, int flags, tfm_prime_callback cb, void *dat)
{
unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
int res, err, bsize, maskOR_msb_offset;
fp_digit maskAND_msb, maskOR_lsb;
int res, bsize, dsize;
unsigned char buf[FP_SIZE * sizeof(fp_digit)];

/* sanity check the input */
if (size <= 1 || t <= 0) {
if (size <= 1) {
return FP_VAL;
}

Expand All @@ -25,26 +32,12 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
flags |= TFM_PRIME_BBS;
}

/* calc the byte size */
bsize = (size>>3)+(size&7?1:0);
/* calc the digit size */
dsize = (size + DIGIT_BIT - 1) >> DIGIT_SHIFT;
bsize = (size + 7) >> 3;

/* we need a buffer of bsize bytes */
tmp = malloc(bsize);
if (tmp == NULL) {
return FP_MEM;
}

/* calc the maskAND value for the MSbyte*/
maskAND = 0xFF >> (8 - (size & 7));

/* calc the maskOR_msb */
maskOR_msb = 0;
maskOR_msb_offset = (size - 2) >> 3;
if (flags & TFM_PRIME_2MSB_ON) {
maskOR_msb |= 1 << ((size - 2) & 7);
} else if (flags & TFM_PRIME_2MSB_OFF) {
maskAND &= ~(1 << ((size - 2) & 7));
}
/* calc the maskAND value for the MSbyte */
maskAND_msb = FP_MASK >> ((DIGIT_BIT - size) & (DIGIT_BIT-1));

/* get the maskOR_lsb */
maskOR_lsb = 1;
Expand All @@ -54,21 +47,30 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback

do {
/* read the bytes */
if (cb(tmp, bsize, dat) != bsize) {
err = FP_VAL;
goto error;
if (cb(buf, bsize, dat) != bsize) {
return FP_VAL;
}

/* work over the MSbyte */
tmp[0] &= maskAND;
tmp[0] |= 1 << ((size - 1) & 7);
fp_read_unsigned_bin(a, buf, bsize);

/* make sure the MSbyte has the required number of bits */
a->dp[dsize-1] &= maskAND_msb;

/* Force a->used as well, it could be smaller if the highest bits were
generated as 0 by the callback. */
a->used = dsize;

/* mix in the maskORs */
tmp[maskOR_msb_offset] |= maskOR_msb;
tmp[bsize-1] |= maskOR_lsb;
/* modify the LSbyte as requested */
a->dp[0] |= maskOR_lsb;

/* read it in */
fp_read_unsigned_bin(a, tmp, bsize);
/* turn on the MSbit to force the requested magnitude */
fp_on_bitnum(a, size-1);

/* modify the 2nd MSBit */
if (flags & TFM_PRIME_2MSB_ON) {
fp_on_bitnum(a, size-2);
} else if (flags & TFM_PRIME_2MSB_OFF) {
fp_off_bitnum(a, size-2);
}

/* is it prime? */
res = fp_isprime(a);
Expand All @@ -78,7 +80,7 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
/* see if (a-1)/2 is prime */
fp_sub_d(a, 1, a);
fp_div_2(a, a);

/* is it prime? */
res = fp_isprime(a);
}
Expand All @@ -90,10 +92,7 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
fp_add_d(a, 1, a);
}

err = FP_OKAY;
error:
free(tmp);
return err;
return FP_OKAY;
}

/* $Source$ */
Expand Down