diff --git a/common/pseudorand.c b/common/pseudorand.c index 7f3efafe5..52da1e61e 100644 --- a/common/pseudorand.c +++ b/common/pseudorand.c @@ -26,25 +26,42 @@ static void init_if_needed(void) } } -uint64_t pseudorand(uint64_t max) +uint64_t pseudorand_(uint64_t max, uint64_t *offset) { init_if_needed(); assert(max); + + /* We try to avoid being order-dependent here. */ + if (randbytes_overridden()) { + uint64_t rand; + randbytes_(&rand, sizeof(rand), offset); + return rand % max; + } return isaac64_next_uint(&isaac64, max); } -uint64_t pseudorand_u64(void) +uint64_t pseudorand_u64_(uint64_t *offset) { init_if_needed(); + if (randbytes_overridden()) { + uint64_t rand; + randbytes_(&rand, sizeof(rand), offset); + return rand; + } return isaac64_next_uint64(&isaac64); } -double pseudorand_double(void) +double pseudorand_double_(uint64_t *offset) { init_if_needed(); + if (randbytes_overridden()) { + uint64_t rand; + randbytes_(&rand, sizeof(rand), offset); + return rand / (double)UINT64_MAX; + } return isaac64_next_double(&isaac64); } diff --git a/common/pseudorand.h b/common/pseudorand.h index ebe9e0b59..0e5ce6c56 100644 --- a/common/pseudorand.h +++ b/common/pseudorand.h @@ -8,18 +8,21 @@ /** * pseudorand - pseudo (guessable!) random number between 0 and max-1. */ -uint64_t pseudorand(uint64_t max); +#define pseudorand(max) ({static uint64_t offset; pseudorand_((max), &offset);}) +uint64_t pseudorand_(uint64_t max, uint64_t *offset); /** - * pseudorand - pseudo (guessable!) random number between 0 and UINT64_MAX. + * pseudorand_u64 - pseudo (guessable!) random number between 0 and UINT64_MAX. */ -uint64_t pseudorand_u64(void); +#define pseudorand_u64() ({static uint64_t offset; pseudorand_u64_(&offset);}) +uint64_t pseudorand_u64_(uint64_t *offset); /** * pseudorand - pseudo (guessable!) random number between 0 (inclusive) and 1 * (exclusive). */ -double pseudorand_double(void); +#define pseudorand_double() ({static uint64_t offset; pseudorand_double_(&offset);}) +double pseudorand_double_(uint64_t *offset); /** * Get the siphash seed for hash tables. diff --git a/common/test/run-psbt_diff.c b/common/test/run-psbt_diff.c index 235163fe0..1c107851a 100644 --- a/common/test/run-psbt_diff.c +++ b/common/test/run-psbt_diff.c @@ -38,9 +38,9 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) /* Generated stub for fromwire_u8_array */ void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED) { fprintf(stderr, "fromwire_u8_array called!\n"); abort(); } -/* Generated stub for pseudorand_u64 */ -uint64_t pseudorand_u64(void) -{ fprintf(stderr, "pseudorand_u64 called!\n"); abort(); } +/* Generated stub for pseudorand_u64_ */ +uint64_t pseudorand_u64_(uint64_t *offset UNNEEDED) +{ fprintf(stderr, "pseudorand_u64_ called!\n"); abort(); } /* Generated stub for towire */ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "towire called!\n"); abort(); } diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index 4e64c268b..e57aca2a4 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -175,6 +175,9 @@ void peer_billboard(bool perm UNNEEDED, const char *fmt UNNEEDED, ...) /* Generated stub for randbytes_ */ void randbytes_(void *bytes UNNEEDED, size_t num_bytes UNNEEDED, u64 *offset UNNEEDED) { fprintf(stderr, "randbytes_ called!\n"); abort(); } +/* Generated stub for randbytes_overridden */ +bool randbytes_overridden(void) +{ fprintf(stderr, "randbytes_overridden called!\n"); abort(); } /* Generated stub for shachain_get_secret */ bool shachain_get_secret(const struct shachain *shachain UNNEEDED, u64 commit_num UNNEEDED, diff --git a/tests/fuzz/libfuzz.c b/tests/fuzz/libfuzz.c index aada6f8ce..00e4b84d0 100644 --- a/tests/fuzz/libfuzz.c +++ b/tests/fuzz/libfuzz.c @@ -21,7 +21,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv); /* Provide a non-random pseudo-random function to speed fuzzing. */ static isaac64_ctx isaac64; -uint64_t pseudorand(uint64_t max) +uint64_t pseudorand_(uint64_t max, uint64_t *offset) { assert(max); return isaac64_next_uint(&isaac64, max); diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index a220af8fc..cc6886456 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -25,6 +25,9 @@ extern secp256k1_context *secp256k1_ctx; /* Generated stub for randbytes_ */ void randbytes_(void *bytes UNNEEDED, size_t num_bytes UNNEEDED, u64 *offset UNNEEDED) { fprintf(stderr, "randbytes_ called!\n"); abort(); } +/* Generated stub for randbytes_overridden */ +bool randbytes_overridden(void) +{ fprintf(stderr, "randbytes_overridden called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ /* memsetting pubkeys doesn't work */ diff --git a/wire/test/run-tlvstream.c b/wire/test/run-tlvstream.c index 3782191da..5aa609336 100644 --- a/wire/test/run-tlvstream.c +++ b/wire/test/run-tlvstream.c @@ -33,6 +33,9 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, /* Generated stub for randbytes_ */ void randbytes_(void *bytes UNNEEDED, size_t num_bytes UNNEEDED, u64 *offset UNNEEDED) { fprintf(stderr, "randbytes_ called!\n"); abort(); } +/* Generated stub for randbytes_overridden */ +bool randbytes_overridden(void) +{ fprintf(stderr, "randbytes_overridden called!\n"); abort(); } /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); }