mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
improve how random seed state is determined
Added "STATIC bool blum_initialized = false" to zrandom.c to improve how the code detects if the Blum-Blum-Shub pseudo-random number generator is seeded or not, and how to free the state correctly. NOTE: There is a very minor memory leak in zrandom.c that will be fixed in a later release.
This commit is contained in:
8
CHANGES
8
CHANGES
@@ -1,4 +1,5 @@
|
|||||||
The following are the changes from calc version 2.15.0.2 to date:
|
The following are the changes from calc version 2.15.0.2 to date:
|
||||||
|
|
||||||
Updated BUGS about MSYS2 on Windows compiling of calc.
|
Updated BUGS about MSYS2 on Windows compiling of calc.
|
||||||
|
|
||||||
Added more git related checks and sanity checks to chk_tree.
|
Added more git related checks and sanity checks to chk_tree.
|
||||||
@@ -21,6 +22,13 @@ The following are the changes from calc version 2.15.0.2 to date:
|
|||||||
Fixed the check for <sys/mount.h> when forming have_sys_mount.h.
|
Fixed the check for <sys/mount.h> when forming have_sys_mount.h.
|
||||||
Thanks goes to GitHub user @gromit1811 for their pull request.
|
Thanks goes to GitHub user @gromit1811 for their pull request.
|
||||||
|
|
||||||
|
Added "STATIC bool blum_initialized = false" to zrandom.c to improve
|
||||||
|
how the code detects if the Blum-Blum-Shub pseudo-random number
|
||||||
|
generator is seeded or not, and how to free the state correctly.
|
||||||
|
|
||||||
|
NOTE: There is a very minor memory leak in zrandom.c that will be
|
||||||
|
fixed in a later release.
|
||||||
|
|
||||||
|
|
||||||
The following are the changes from calc version 2.14.3.5 to 2.15.0.1:
|
The following are the changes from calc version 2.14.3.5 to 2.15.0.1:
|
||||||
|
|
||||||
|
77
zrandom.c
77
zrandom.c
@@ -1107,6 +1107,7 @@
|
|||||||
* current Blum generator state
|
* current Blum generator state
|
||||||
*/
|
*/
|
||||||
STATIC RANDOM blum;
|
STATIC RANDOM blum;
|
||||||
|
STATIC bool blum_initialized = false; /* true ==> blum has a seeded and initialized state */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2272,11 +2273,14 @@ zsrandom1(CONST ZVALUE seed, bool need_ret)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2342,6 +2346,9 @@ zsrandom1(CONST ZVALUE seed, bool need_ret)
|
|||||||
* reserved seed
|
* reserved seed
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
|
if (ret != NULL) {
|
||||||
|
randomfree(ret);
|
||||||
|
}
|
||||||
math_error("srandom seed must be 0 or >= 2^32");
|
math_error("srandom seed must be 0 or >= 2^32");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
@@ -2384,11 +2391,14 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2409,11 +2419,13 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
|
|||||||
* preset moduli only if small newn
|
* preset moduli only if small newn
|
||||||
*/
|
*/
|
||||||
if (ziszero(newn)) {
|
if (ziszero(newn)) {
|
||||||
|
randomfree(ret);
|
||||||
math_error("srandom newn == 0 reserved for future use");
|
math_error("srandom newn == 0 reserved for future use");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
set = (HALF)z1tol(newn);
|
set = (HALF)z1tol(newn);
|
||||||
if (!zistiny(newn) || set > BLUM_PREGEN) {
|
if (!zistiny(newn) || set > BLUM_PREGEN) {
|
||||||
|
randomfree(ret);
|
||||||
math_error("srandom small newn must be [1,20]");
|
math_error("srandom small newn must be [1,20]");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
@@ -2433,7 +2445,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
|
|||||||
* Otherwise non-zero seeds are processed as 1 arg calls
|
* Otherwise non-zero seeds are processed as 1 arg calls
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
zsrandom1(seed, false);
|
(void) zsrandom1(seed, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2452,6 +2464,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
|
|||||||
* Blum modulus must be 1 mod 4
|
* Blum modulus must be 1 mod 4
|
||||||
*/
|
*/
|
||||||
if (newn.v[0] % 4 != 1) {
|
if (newn.v[0] % 4 != 1) {
|
||||||
|
randomfree(ret);
|
||||||
math_error("srandom large newn must be 1 mod 4");
|
math_error("srandom large newn must be 1 mod 4");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
@@ -2498,6 +2511,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
|
|||||||
* reserved newn
|
* reserved newn
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
|
randomfree(ret);
|
||||||
math_error("srandom newn must be [1,20] or >= 2^32");
|
math_error("srandom newn must be [1,20] or >= 2^32");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
@@ -2543,11 +2557,14 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2559,10 +2576,12 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials)
|
|||||||
* search the 'p' and 'q' Blum prime (3 mod 4) candidates
|
* search the 'p' and 'q' Blum prime (3 mod 4) candidates
|
||||||
*/
|
*/
|
||||||
if (!znextcand(ip, trials, _zero_, _three_, _four_, &p)) {
|
if (!znextcand(ip, trials, _zero_, _three_, _four_, &p)) {
|
||||||
|
randomfree(ret);
|
||||||
math_error("failed to find 1st Blum prime");
|
math_error("failed to find 1st Blum prime");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
if (!znextcand(iq, trials, _zero_, _three_, _four_, &q)) {
|
if (!znextcand(iq, trials, _zero_, _three_, _four_, &q)) {
|
||||||
|
randomfree(ret);
|
||||||
math_error("failed to find 2nd Blum prime");
|
math_error("failed to find 2nd Blum prime");
|
||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
@@ -2640,11 +2659,14 @@ zsetrandom(CONST RANDOM *state)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2684,11 +2706,14 @@ zrandomskip(long cnt)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
loglogn = (long)blum.loglogn;
|
loglogn = (long)blum.loglogn;
|
||||||
new_r.len = 0; /* paranoia */
|
new_r.len = 0; /* paranoia */
|
||||||
@@ -2798,11 +2823,14 @@ zrandom(long cnt, ZVALUE *res)
|
|||||||
/*
|
/*
|
||||||
* initialize state if first call
|
* initialize state if first call
|
||||||
*/
|
*/
|
||||||
if (!blum.seeded) {
|
if (blum_initialized == false || !blum.seeded) {
|
||||||
p_blum = randomcopy(&init_blum);
|
p_blum = randomcopy(&init_blum);
|
||||||
randomfree(&blum);
|
if (blum_initialized == true) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
blum = *p_blum;
|
blum = *p_blum;
|
||||||
free(p_blum);
|
free(p_blum);
|
||||||
|
blum_initialized = true;
|
||||||
}
|
}
|
||||||
loglogn = blum.loglogn;
|
loglogn = blum.loglogn;
|
||||||
mask = blum.mask;
|
mask = blum.mask;
|
||||||
@@ -3120,16 +3148,18 @@ randomfree(RANDOM *state)
|
|||||||
not_reached();
|
not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the values */
|
/* clear the seed */
|
||||||
|
state->seeded = 0;
|
||||||
|
state->bits = 0; /* paranoia */
|
||||||
|
state->loglogn = 0; /* paranoia */
|
||||||
|
state->buffer = 0; /* paranoia */
|
||||||
|
state->mask = 0; /* paranoia */
|
||||||
|
|
||||||
|
/* free the values - unless they are one of the default states */
|
||||||
zfree_random(state->n);
|
zfree_random(state->n);
|
||||||
zfree_random(state->r);
|
zfree_random(state->r);
|
||||||
|
|
||||||
/* free it if it is not pre-defined */
|
/* free the RANDOM structure if it is NOT our static blum value */
|
||||||
state->seeded = 0;
|
|
||||||
state->bits = 0; /* paranoia */
|
|
||||||
state->buffer = 0;
|
|
||||||
|
|
||||||
/* free it if it is not pre-defined */
|
|
||||||
if (state != &blum) {
|
if (state != &blum) {
|
||||||
free(state);
|
free(state);
|
||||||
}
|
}
|
||||||
@@ -3223,8 +3253,10 @@ randomprint(CONST RANDOM *UNUSED(state), int UNUSED(flags))
|
|||||||
void
|
void
|
||||||
random_libcalc_cleanup(void)
|
random_libcalc_cleanup(void)
|
||||||
{
|
{
|
||||||
/* free our state - let zfree_random protect the default state */
|
/* free our state if seed was initialized - zfree_random protect default states */
|
||||||
randomfree(&blum);
|
if (blum_initialized == true && blum.seeded) {
|
||||||
|
randomfree(&blum);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3238,6 +3270,7 @@ random_libcalc_cleanup(void)
|
|||||||
S_FUNC void
|
S_FUNC void
|
||||||
zfree_random(ZVALUE z)
|
zfree_random(ZVALUE z)
|
||||||
{
|
{
|
||||||
|
/* do not free if NULL or one of the default states */
|
||||||
if (z.v != NULL &&
|
if (z.v != NULL &&
|
||||||
z.v != h_ndefvec && z.v != h_rdefvec && z.v != h_rdefvec_2 &&
|
z.v != h_ndefvec && z.v != h_rdefvec && z.v != h_rdefvec_2 &&
|
||||||
z.v != h_nvec01 && z.v != h_rvec01 &&
|
z.v != h_nvec01 && z.v != h_rvec01 &&
|
||||||
|
Reference in New Issue
Block a user