Remove usage of malloc() from fp_prime_random_ex.
This is the only instance of dynamic memory in TFM. It can be avoided by writing directly into the dp[] array, and it does not violate C aliasing rules which specifically allow access on objects through char*. It does not matter the platform-specific representation of digits since we are filling them with random data anyway.
This commit is contained in:
parent
08b3654ac4
commit
279da69658
@ -1,10 +1,10 @@
|
|||||||
/* TomsFastMath, a fast ISO C bignum library.
|
/* TomsFastMath, a fast ISO C bignum library.
|
||||||
*
|
*
|
||||||
* This project is meant to fill in where LibTomMath
|
* This project is meant to fill in where LibTomMath
|
||||||
* falls short. That is speed ;-)
|
* falls short. That is speed ;-)
|
||||||
*
|
*
|
||||||
* This project is public domain and free for all purposes.
|
* This project is public domain and free for all purposes.
|
||||||
*
|
*
|
||||||
* Tom St Denis, tomstdenis@gmail.com
|
* Tom St Denis, tomstdenis@gmail.com
|
||||||
*/
|
*/
|
||||||
#ifndef TFM_H_
|
#ifndef TFM_H_
|
||||||
@ -27,13 +27,13 @@
|
|||||||
/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */
|
/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */
|
||||||
#ifndef TFM_ALREADY_SET
|
#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
|
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 ;-)
|
Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-)
|
||||||
*/
|
*/
|
||||||
#define TFM_SMALL_SET
|
#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)
|
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
|
Less important on 64-bit machines as 32 digits == 2048 bits
|
||||||
*/
|
*/
|
||||||
@ -81,7 +81,7 @@
|
|||||||
/* #define TFM_PRESCOTT */
|
/* #define TFM_PRESCOTT */
|
||||||
|
|
||||||
/* Do we want timing resistant fp_exptmod() ?
|
/* 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 */
|
/* #define TFM_TIMING_RESISTANT */
|
||||||
|
|
||||||
@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */
|
/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */
|
||||||
#if defined(__x86_64__)
|
#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!
|
#error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid!
|
||||||
#endif
|
#endif
|
||||||
#if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)
|
#if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)
|
||||||
@ -121,7 +121,7 @@
|
|||||||
|
|
||||||
/* try to detect x86-32 */
|
/* try to detect x86-32 */
|
||||||
#if defined(__i386__) && !defined(TFM_SSE2)
|
#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!
|
#error x86-32 detected, x86-64/ARM optimizations are not valid!
|
||||||
#endif
|
#endif
|
||||||
#if !defined(TFM_X86) && !defined(TFM_NO_ASM)
|
#if !defined(TFM_X86) && !defined(TFM_NO_ASM)
|
||||||
@ -185,7 +185,7 @@
|
|||||||
#undef TFM_PPC32
|
#undef TFM_PPC32
|
||||||
#undef TFM_PPC64
|
#undef TFM_PPC64
|
||||||
#undef TFM_AVR32
|
#undef TFM_AVR32
|
||||||
#undef TFM_ASM
|
#undef TFM_ASM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ECC helpers */
|
/* ECC helpers */
|
||||||
@ -249,6 +249,7 @@
|
|||||||
#endif
|
#endif
|
||||||
typedef ulong64 fp_digit;
|
typedef ulong64 fp_digit;
|
||||||
typedef unsigned long fp_word __attribute__ ((mode(TI)));
|
typedef unsigned long fp_word __attribute__ ((mode(TI)));
|
||||||
|
#define DIGIT_SHIFT 6
|
||||||
#else
|
#else
|
||||||
/* this is to make porting into LibTomCrypt easier :-) */
|
/* this is to make porting into LibTomCrypt easier :-) */
|
||||||
#ifndef CRYPT
|
#ifndef CRYPT
|
||||||
@ -262,6 +263,7 @@
|
|||||||
#endif
|
#endif
|
||||||
typedef unsigned long fp_digit;
|
typedef unsigned long fp_digit;
|
||||||
typedef ulong64 fp_word;
|
typedef ulong64 fp_word;
|
||||||
|
#define DIGIT_SHIFT 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* # of digits this is */
|
/* # of digits this is */
|
||||||
@ -290,7 +292,7 @@
|
|||||||
/* a FP type */
|
/* a FP type */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fp_digit dp[FP_SIZE];
|
fp_digit dp[FP_SIZE];
|
||||||
int used,
|
int used,
|
||||||
sign;
|
sign;
|
||||||
} fp_int;
|
} fp_int;
|
||||||
|
|
||||||
@ -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] */
|
/* 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);
|
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 */
|
/* radix conersions */
|
||||||
int fp_count_bits(fp_int *a);
|
int fp_count_bits(fp_int *a);
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
/* TomsFastMath, a fast ISO C bignum library.
|
/* TomsFastMath, a fast ISO C bignum library.
|
||||||
*
|
*
|
||||||
* This project is meant to fill in where LibTomMath
|
* This project is meant to fill in where LibTomMath
|
||||||
* falls short. That is speed ;-)
|
* falls short. That is speed ;-)
|
||||||
*
|
*
|
||||||
* This project is public domain and free for all purposes.
|
* This project is public domain and free for all purposes.
|
||||||
*
|
*
|
||||||
* Tom St Denis, tomstdenis@gmail.com
|
* Tom St Denis, tomstdenis@gmail.com
|
||||||
*/
|
*/
|
||||||
#include <tfm.h>
|
#include <tfm.h>
|
||||||
|
|
||||||
|
#define fp_on_bitnum(a, bitnum) \
|
||||||
|
a->dp[(bitnum) >> DIGIT_SHIFT] |= 1 << ((bitnum) & (DIGIT_BIT-1));
|
||||||
|
|
||||||
|
#define fp_off_bitnum(a, bitnum) \
|
||||||
|
a->dp[(bitnum) >> DIGIT_SHIFT] &= ~(1 << ((bitnum) & (DIGIT_BIT-1)));
|
||||||
|
|
||||||
/* This is possibly the mother of all prime generation functions, muahahahahaha! */
|
/* 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;
|
fp_digit maskAND_msb, maskOR_lsb;
|
||||||
int res, err, bsize, maskOR_msb_offset;
|
int res, err, bsize, dsize;
|
||||||
|
|
||||||
/* sanity check the input */
|
/* sanity check the input */
|
||||||
if (size <= 1 || t <= 0) {
|
if (size <= 1) {
|
||||||
return FP_VAL;
|
return FP_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,26 +31,11 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
|
|||||||
flags |= TFM_PRIME_BBS;
|
flags |= TFM_PRIME_BBS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calc the byte size */
|
/* calc the digit size */
|
||||||
bsize = (size>>3)+(size&7?1:0);
|
dsize = (size + DIGIT_BIT - 1) >> DIGIT_SHIFT;
|
||||||
|
|
||||||
/* we need a buffer of bsize bytes */
|
/* calc the maskAND value for the MSbyte */
|
||||||
tmp = malloc(bsize);
|
maskAND_msb = FP_MASK >> ((DIGIT_BIT - (size & (DIGIT_BIT-1))) & (DIGIT_BIT-1));
|
||||||
if (tmp == NULL) {
|
|
||||||
return FP_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calc the maskAND value for the MSbyte*/
|
|
||||||
maskAND = 0xFF >> ((8 - (size & 7)) & 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the maskOR_lsb */
|
/* get the maskOR_lsb */
|
||||||
maskOR_lsb = 1;
|
maskOR_lsb = 1;
|
||||||
@ -54,21 +45,26 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
/* read the bytes */
|
/* read the bytes */
|
||||||
if (cb(tmp, bsize, dat) != bsize) {
|
if (cb((unsigned char*)&a->dp[0], dsize*DIGIT_BIT, dat) != dsize*DIGIT_BIT) {
|
||||||
err = FP_VAL;
|
return FP_VAL;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
a->used = dsize;
|
||||||
/* work over the MSbyte */
|
|
||||||
tmp[0] &= maskAND;
|
|
||||||
tmp[0] |= 1 << ((size - 1) & 7);
|
|
||||||
|
|
||||||
/* mix in the maskORs */
|
/* make sure the MSbyte has the required number of bits */
|
||||||
tmp[maskOR_msb_offset] |= maskOR_msb;
|
a->dp[dsize-1] &= maskAND_msb;
|
||||||
tmp[bsize-1] |= maskOR_lsb;
|
|
||||||
|
|
||||||
/* read it in */
|
/* modify the LSbyte as requested */
|
||||||
fp_read_unsigned_bin(a, tmp, bsize);
|
a->dp[0] |= maskOR_lsb;
|
||||||
|
|
||||||
|
/* 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? */
|
/* is it prime? */
|
||||||
res = fp_isprime(a);
|
res = fp_isprime(a);
|
||||||
@ -78,7 +74,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 */
|
/* see if (a-1)/2 is prime */
|
||||||
fp_sub_d(a, 1, a);
|
fp_sub_d(a, 1, a);
|
||||||
fp_div_2(a, a);
|
fp_div_2(a, a);
|
||||||
|
|
||||||
/* is it prime? */
|
/* is it prime? */
|
||||||
res = fp_isprime(a);
|
res = fp_isprime(a);
|
||||||
}
|
}
|
||||||
@ -90,10 +86,7 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
|
|||||||
fp_add_d(a, 1, a);
|
fp_add_d(a, 1, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = FP_OKAY;
|
return FP_OKAY;
|
||||||
error:
|
|
||||||
free(tmp);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $Source$ */
|
/* $Source$ */
|
||||||
|
Loading…
Reference in New Issue
Block a user