2
2
/* SPDX-License-Identifier: Unlicense */
3
3
#include <tfm_private.h>
4
4
5
+ #define fp_on_bitnum (a , bitnum ) \
6
+ a->dp[(bitnum) >> DIGIT_SHIFT] |= (fp_digit)1 << ((bitnum) & (DIGIT_BIT-1))
7
+
8
+ #define fp_off_bitnum (a , bitnum ) \
9
+ a->dp[(bitnum) >> DIGIT_SHIFT] &= ~((fp_digit)1 << ((bitnum) & (DIGIT_BIT-1)))
10
+
5
11
/* This is possibly the mother of all prime generation functions, muahahahahaha! */
6
12
int fp_prime_random_ex (fp_int * a , int t , int size , int flags , tfm_prime_callback cb , void * dat )
7
13
{
8
- unsigned char * tmp , maskAND , maskOR_msb , maskOR_lsb ;
9
- int res , err , bsize , maskOR_msb_offset ;
14
+ fp_digit maskAND_msb , maskOR_lsb ;
15
+ int res , bsize , dsize ;
16
+ unsigned char buf [FP_SIZE * sizeof (fp_digit )];
10
17
11
18
/* sanity check the input */
12
19
if (size <= 1 || cb == NULL || t <= 0 || t > FP_PRIME_SIZE ) {
@@ -18,26 +25,13 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
18
25
flags |= TFM_PRIME_BBS ;
19
26
}
20
27
21
- /* calc the byte size */
22
- bsize = (size >>3 )+ (size & 7 ?1 :0 );
28
+ /* calc the size in fp_digit */
29
+ dsize = (size + DIGIT_BIT - 1 ) >> DIGIT_SHIFT ;
30
+ /* calc the size in bytes */
31
+ bsize = (size + 7 ) >> 3 ;
23
32
24
- /* we need a buffer of bsize bytes */
25
- tmp = malloc (bsize );
26
- if (tmp == NULL ) {
27
- return FP_MEM ;
28
- }
29
-
30
- /* calc the maskAND value for the MSbyte*/
31
- maskAND = 0xFF >> ((8 - (size & 7 )) & 7 );
32
-
33
- /* calc the maskOR_msb */
34
- maskOR_msb = 0 ;
35
- maskOR_msb_offset = (size - 2 ) >> 3 ;
36
- if (flags & TFM_PRIME_2MSB_ON ) {
37
- maskOR_msb |= 1 << ((size - 2 ) & 7 );
38
- } else if (flags & TFM_PRIME_2MSB_OFF ) {
39
- maskAND &= ~(1 << ((size - 2 ) & 7 ));
40
- }
33
+ /* calc the maskAND value for the MSbyte */
34
+ maskAND_msb = FP_MASK >> ((DIGIT_BIT - size ) & (DIGIT_BIT - 1 ));
41
35
42
36
/* get the maskOR_lsb */
43
37
maskOR_lsb = 1 ;
@@ -47,21 +41,30 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
47
41
48
42
do {
49
43
/* read the bytes */
50
- if (cb (tmp , bsize , dat ) != bsize ) {
51
- err = FP_VAL ;
52
- goto error ;
44
+ if (cb (buf , bsize , dat ) != bsize ) {
45
+ return FP_VAL ;
53
46
}
47
+ fp_read_unsigned_bin (a , buf , bsize );
48
+
49
+ /* make sure the MSbyte has the required number of bits */
50
+ a -> dp [dsize - 1 ] &= maskAND_msb ;
54
51
55
- /* work over the MSbyte */
56
- tmp [ 0 ] &= maskAND ;
57
- tmp [ 0 ] |= 1 << (( size - 1 ) & 7 ) ;
52
+ /* Force a->used as well, it could be smaller if the highest bits were
53
+ generated as 0 by the callback. */
54
+ a -> used = dsize ;
58
55
59
- /* mix in the maskORs */
60
- tmp [maskOR_msb_offset ] |= maskOR_msb ;
61
- tmp [bsize - 1 ] |= maskOR_lsb ;
56
+ /* modify the LSbyte as requested */
57
+ a -> dp [0 ] |= maskOR_lsb ;
62
58
63
- /* read it in */
64
- fp_read_unsigned_bin (a , tmp , bsize );
59
+ /* turn on the MSbit to force the requested magnitude */
60
+ fp_on_bitnum (a , size - 1 );
61
+
62
+ /* modify the 2nd MSBit */
63
+ if (flags & TFM_PRIME_2MSB_ON ) {
64
+ fp_on_bitnum (a , size - 2 );
65
+ } else if (flags & TFM_PRIME_2MSB_OFF ) {
66
+ fp_off_bitnum (a , size - 2 );
67
+ }
65
68
66
69
/* is it prime? */
67
70
res = fp_isprime_ex (a , t );
@@ -83,8 +86,5 @@ int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback
83
86
fp_add_d (a , 1 , a );
84
87
}
85
88
86
- err = FP_OKAY ;
87
- error :
88
- free (tmp );
89
- return err ;
89
+ return FP_OKAY ;
90
90
}
0 commit comments