From 4de7bc578e477cb6b85057fa27f1ccb54b4eead6 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 25 May 2026 19:39:59 -0700 Subject: [PATCH] [random] introduce template-based `NonCrypto` random APIs (#13142) This commit introduces a new set of template-based APIs for non-cryptographic random number generation in the `Random::NonCrypto` namespace. These new methods provide a cleaner, type-safe, and more robust interface compared to the previous methods. Key additions: - `Generate()`: Returns a random value of the given unsigned integer type (`uint8_t`, `uint16_t`, or `uint32_t`). - `GenerateUpToExcluding(aMax)`: Returns a random value in the range `[0, aMax)`. - `GenerateFromMinUpToExcluding(aMin, aMax)`: Returns a random value in the range `[aMin, aMax)`. - `GenerateInClosedRange(aMin, aMax)`: Returns a random value in the closed range `[aMin, aMax]`. The introduction of `GenerateInClosedRange` is an improvement as it safely handles ranges up to the maximum value of the integer type (e.g., `0xffff`) without the risk of overflow. All call sites across the OpenThread core stack and tests have been updated to adopt these new APIs. The public `otRandomNonCrypto` functions are also updated to leverage the new internal methods. Doxygen documentation is added for all new template methods, detailing their behavior, including edge cases where the upper bound is smaller than or equal to the lower bound. --- src/core/api/random_noncrypto_api.cpp | 12 +- src/core/backbone_router/bbr_leader.cpp | 8 +- src/core/backbone_router/bbr_local.cpp | 5 +- src/core/border_router/dhcp6_pd_client.cpp | 6 +- src/core/border_router/routing_manager.cpp | 2 +- src/core/border_router/rx_ra_tracker.cpp | 2 +- src/core/coap/coap.cpp | 6 +- src/core/common/random.cpp | 58 +++++- src/core/common/random.hpp | 81 ++++---- src/core/common/time_ticker.cpp | 2 +- src/core/common/trickle_timer.cpp | 15 +- src/core/instance/instance.cpp | 2 +- src/core/mac/channel_mask.cpp | 2 +- src/core/mac/mac.cpp | 4 +- src/core/mac/mac_types.cpp | 2 +- src/core/mac/sub_mac.cpp | 2 +- src/core/meshcop/meshcop_leader.cpp | 2 +- src/core/meshcop/timestamp.cpp | 2 +- src/core/net/dns_client.cpp | 2 +- src/core/net/dns_dso.cpp | 2 +- src/core/net/ip6.cpp | 2 +- src/core/net/ip6_mpl.cpp | 2 +- src/core/net/mdns.cpp | 10 +- src/core/net/nat64_translator.cpp | 2 +- src/core/net/srp_client.cpp | 4 +- src/core/net/srp_server.cpp | 2 +- src/core/thread/announce_sender.cpp | 2 +- src/core/thread/dua_manager.cpp | 3 +- src/core/thread/message_framer.cpp | 2 +- src/core/thread/mle.cpp | 9 +- src/core/thread/mle_ftd.cpp | 11 +- src/core/thread/mlr_manager.cpp | 4 +- src/core/thread/network_data_leader.cpp | 4 +- src/core/thread/network_data_notifier.cpp | 2 +- src/core/thread/network_data_publisher.cpp | 4 +- src/core/thread/network_diagnostic.cpp | 2 +- src/core/thread/radio_selector.cpp | 2 +- src/core/thread/router_table.cpp | 4 +- src/core/utils/channel_manager.cpp | 2 +- src/core/utils/jam_detector.cpp | 2 +- tests/nexus/test_dtls.cpp | 4 +- tests/nexus/test_srp_lease.cpp | 6 +- tests/unit/CMakeLists.txt | 1 + tests/unit/test_checksum.cpp | 4 +- tests/unit/test_random.cpp | 225 +++++++++++++++++++++ tests/unit/test_spinel_buffer.cpp | 2 +- 46 files changed, 393 insertions(+), 141 deletions(-) create mode 100644 tests/unit/test_random.cpp diff --git a/src/core/api/random_noncrypto_api.cpp b/src/core/api/random_noncrypto_api.cpp index 6a2d18ba3..1813ad312 100644 --- a/src/core/api/random_noncrypto_api.cpp +++ b/src/core/api/random_noncrypto_api.cpp @@ -37,25 +37,25 @@ using namespace ot; -uint32_t otRandomNonCryptoGetUint32(void) { return Random::NonCrypto::GetUint32(); } +uint32_t otRandomNonCryptoGetUint32(void) { return Random::NonCrypto::Generate(); } -uint8_t otRandomNonCryptoGetUint8(void) { return Random::NonCrypto::GetUint8(); } +uint8_t otRandomNonCryptoGetUint8(void) { return Random::NonCrypto::Generate(); } -uint16_t otRandomNonCryptoGetUint16(void) { return Random::NonCrypto::GetUint16(); } +uint16_t otRandomNonCryptoGetUint16(void) { return Random::NonCrypto::Generate(); } uint8_t otRandomNonCryptoGetUint8InRange(uint8_t aMin, uint8_t aMax) { - return Random::NonCrypto::GetUint8InRange(aMin, aMax); + return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax); } uint16_t otRandomNonCryptoGetUint16InRange(uint16_t aMin, uint16_t aMax) { - return Random::NonCrypto::GetUint16InRange(aMin, aMax); + return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax); } uint32_t otRandomNonCryptoGetUint32InRange(uint32_t aMin, uint32_t aMax) { - return Random::NonCrypto::GetUint32InRange(aMin, aMax); + return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax); } void otRandomNonCryptoFillBuffer(uint8_t *aBuffer, uint16_t aSize) { Random::NonCrypto::FillBuffer(aBuffer, aSize); } diff --git a/src/core/backbone_router/bbr_leader.cpp b/src/core/backbone_router/bbr_leader.cpp index 3200444dc..fb79b2e2d 100644 --- a/src/core/backbone_router/bbr_leader.cpp +++ b/src/core/backbone_router/bbr_leader.cpp @@ -63,13 +63,7 @@ exit: uint16_t Config::SelectRandomReregistrationDelay(void) const { - uint16_t delay = 1; - - VerifyOrExit(mReregistrationDelay > 1); - delay = 1 + Random::NonCrypto::GetUint16InRange(0, mReregistrationDelay); - -exit: - return delay; + return Random::NonCrypto::GenerateInClosedRange(1, mReregistrationDelay); } #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index e341a4fd5..481c0d9db 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -47,7 +47,7 @@ Local::Local(Instance &aInstance) : InstanceLocator(aInstance) , mIsServiceAdded(false) , mState(kStateDisabled) - , mSequenceNumber(Random::NonCrypto::GetUint8() % 127) + , mSequenceNumber(Random::NonCrypto::GenerateUpToExcluding(127)) , mRegistrationJitter(kDefaultRegistrationJitter) , mReregistrationDelay(kDefaultRegistrationDelay) , mRegistrationTimeout(0) @@ -266,8 +266,7 @@ void Local::UpdateState(void) } else { - mRegistrationTimeout = - 1 + Random::NonCrypto::GetUint16InRange(0, static_cast(mRegistrationJitter)); + mRegistrationTimeout = Random::NonCrypto::GenerateInClosedRange(1, mRegistrationJitter); Get().RegisterReceiver(TimeTicker::kBbrLocal); } } diff --git a/src/core/border_router/dhcp6_pd_client.cpp b/src/core/border_router/dhcp6_pd_client.cpp index 6b9e7a43a..67fc46d9c 100644 --- a/src/core/border_router/dhcp6_pd_client.cpp +++ b/src/core/border_router/dhcp6_pd_client.cpp @@ -120,7 +120,7 @@ void Dhcp6PdClient::EnterState(State aState) case kStateToSolicit: ClearServerDuid(); ClearPdPrefix(); - mTimer.Start(Random::NonCrypto::GetUint32InRange(0, kMaxDelayFirstSolicit)); + mTimer.Start(Random::NonCrypto::GenerateUpToExcluding(kMaxDelayFirstSolicit)); break; case kStateSoliciting: @@ -1183,11 +1183,11 @@ uint32_t Dhcp6PdClient::RetxTracker::AddJitter(uint32_t aValue, JitterMode aJitt switch (aJitterMode) { case kPositiveJitter: - randomizedValue += Random::NonCrypto::GetUint32InRange(0, jitter); + randomizedValue += Random::NonCrypto::GenerateUpToExcluding(jitter); break; case kFullJitter: - randomizedValue += Random::NonCrypto::GetUint32InRange(0, 2 * jitter) - jitter; + randomizedValue += Random::NonCrypto::GenerateUpToExcluding(2 * jitter) - jitter; break; } diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 40549ee7f..8130ce567 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -986,7 +986,7 @@ void RoutingManager::OmrPrefixManager::Evaluate(void) { case kNotAdded: { - uint32_t delay = Random::NonCrypto::GetUint32InRange(kMinDelayToAdd, kMaxDelayToAdd); + uint32_t delay = Random::NonCrypto::GenerateInClosedRange(kMinDelayToAdd, kMaxDelayToAdd); mLocalInNetDataState = kToAdd; mTimer.Start(delay); diff --git a/src/core/border_router/rx_ra_tracker.cpp b/src/core/border_router/rx_ra_tracker.cpp index e01d5402b..6a63d7aa5 100644 --- a/src/core/border_router/rx_ra_tracker.cpp +++ b/src/core/border_router/rx_ra_tracker.cpp @@ -1806,7 +1806,7 @@ void RxRaTracker::RsSender::Start(void) VerifyOrExit(!IsInProgress()); - delay = Random::NonCrypto::GetUint32InRange(0, kMaxStartDelay); + delay = Random::NonCrypto::GenerateUpToExcluding(kMaxStartDelay); LogInfo("RsSender: Starting - will send first RS in %lu msec", ToUlong(delay)); diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index bafc8fc9d..e2395d858 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -124,7 +124,7 @@ CoapBase::CoapBase(Instance &aInstance, Transmitter aTransmitter) , mResponseCache(aInstance) , mResourceHandler(nullptr) , mTransmitter(aTransmitter) - , mMessageId(Random::NonCrypto::GetUint16()) + , mMessageId(Random::NonCrypto::Generate()) #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE , mLastResponse(nullptr) #endif @@ -2045,8 +2045,8 @@ exit: uint32_t TxParameters::CalculateInitialRetransmissionTimeout(void) const { - return Random::NonCrypto::GetUint32InRange( - mAckTimeout, mAckTimeout * mAckRandomFactorNumerator / mAckRandomFactorDenominator + 1); + return Random::NonCrypto::GenerateInClosedRange(mAckTimeout, mAckTimeout * mAckRandomFactorNumerator / + mAckRandomFactorDenominator); } uint32_t TxParameters::CalculateExchangeLifetime(void) const diff --git a/src/core/common/random.cpp b/src/core/common/random.cpp index d39a06b8c..da7745079 100644 --- a/src/core/common/random.cpp +++ b/src/core/common/random.cpp @@ -37,6 +37,8 @@ #include "common/code_utils.hpp" #include "common/debug.hpp" +#include "common/num_utils.hpp" +#include "common/numeric_limits.hpp" namespace ot { namespace Random { @@ -129,30 +131,64 @@ uint32_t Manager::NonCryptoPrng::GetNext(void) namespace NonCrypto { -uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax) +static uint32_t GenerateInRange(uint32_t aMin, uint32_t aMax) { - OT_ASSERT(aMax > aMin); + uint32_t value; + uint32_t range; - return (aMin + (GetUint8() % (aMax - aMin))); + VerifyOrExit(aMin < aMax, value = aMin); + + value = Generate(); + + range = aMax - aMin; + + VerifyOrExit(range < NumericLimits::kMax); + + value = aMin + (value % (range + 1)); + +exit: + return value; } -uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax) +template UintType GenerateUpToExcluding(UintType aMax) { - OT_ASSERT(aMax > aMin); - return (aMin + (GetUint16() % (aMax - aMin))); + return GenerateFromMinUpToExcluding(0, aMax); } -uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax) +template UintType GenerateFromMinUpToExcluding(UintType aMin, UintType aMax) { - OT_ASSERT(aMax > aMin); - return (aMin + (GetUint32() % (aMax - aMin))); + if (aMax > 0) + { + aMax--; + } + + return GenerateInClosedRange(aMin, aMax); } +template UintType GenerateInClosedRange(UintType aMin, UintType aMax) +{ + return static_cast(GenerateInRange(aMin, aMax)); +} + +// Explicit instantiations + +template uint8_t GenerateUpToExcluding(uint8_t aMax); +template uint16_t GenerateUpToExcluding(uint16_t aMax); +template uint32_t GenerateUpToExcluding(uint32_t aMax); + +template uint8_t GenerateFromMinUpToExcluding(uint8_t aMin, uint8_t aMax); +template uint16_t GenerateFromMinUpToExcluding(uint16_t aMin, uint16_t aMax); +template uint32_t GenerateFromMinUpToExcluding(uint32_t aMin, uint32_t aMax); + +template uint8_t GenerateInClosedRange(uint8_t aMin, uint8_t aMax); +template uint16_t GenerateInClosedRange(uint16_t aMin, uint16_t aMax); +template uint32_t GenerateInClosedRange(uint32_t aMin, uint32_t aMax); + void FillBuffer(uint8_t *aBuffer, uint16_t aSize) { while (aSize-- != 0) { - *aBuffer++ = GetUint8(); + *aBuffer++ = Generate(); } } @@ -163,7 +199,7 @@ uint32_t AddJitter(uint32_t aValue, uint16_t aJitter) VerifyOrExit(aValue != 0); aJitter = (aJitter <= aValue) ? aJitter : static_cast(aValue); - delay = aValue + GetUint32InRange(0, 2 * aJitter + 1) - aJitter; + delay = aValue + GenerateUpToExcluding(2 * aJitter + 1) - aJitter; exit: return delay; diff --git a/src/core/common/random.hpp b/src/core/common/random.hpp index e42f8920d..7e27a9adb 100644 --- a/src/core/common/random.hpp +++ b/src/core/common/random.hpp @@ -101,60 +101,53 @@ private: namespace NonCrypto { /** - * Generates and returns a random `uint32_t` value. + * Generates and returns a random value of a given unsigned integer type. * - * @returns A random `uint32_t` value. + * @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`). + * + * @returns A random `UintType` value. */ -inline uint32_t GetUint32(void) { return Manager::NonCryptoGetUint32(); } +template inline UintType Generate(void) +{ + static_assert(TypeTraits::IsUint::kValue, "UintType must be an unsigned int"); + static_assert(!TypeTraits::IsSame::kValue, "UintType cannot be `uint64_t`"); + + return static_cast(Manager::NonCryptoGetUint32()); +} /** - * Generates and returns a random byte. + * Generates and returns a random value of a given unsigned integer type within range `[0, aMax)`. * - * @returns A random `uint8_t` value. + * @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`). + * + * @param[in] aMax The upper bound (exclusive). If zero, zero is returned. + * + * @returns A random `UintType` value in the range `[0, aMax)`. */ -inline uint8_t GetUint8(void) { return static_cast(GetUint32() & 0xff); } +template UintType GenerateUpToExcluding(UintType aMax); +/** + * Generates and returns a random value of a given unsigned integer type within range `[aMin, aMax)`. + * + * @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`). + * + * @param[in] aMin The lower bound (inclusive). + * @param[in] aMax The upper bound (exclusive). If @p aMax <= @p aMin, @p aMin is returned. + * + * @returns A random `UintType` value in the range `[aMin, aMax)`. + */ +template UintType GenerateFromMinUpToExcluding(UintType aMin, UintType aMax); /** - * Generates and returns a random `uint16_t` value. + * Generates and returns a random value of a given unsigned integer type within a closed range `[aMin, aMax]`. * - * @returns A random `uint16_t` value. + * @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`). + * + * @param[in] aMin The lower bound (inclusive). + * @param[in] aMax The upper bound (inclusive). If @p aMax < @p aMin, @p aMin is returned. + * + * @returns A random `UintType` value in the range `[aMin, aMax]`. */ -inline uint16_t GetUint16(void) { return static_cast(GetUint32() & 0xffff); } - -/** - * Generates and returns a random `uint8_t` value within a given range `[aMin, aMax)`. - * - * @param[in] aMin A minimum value (this value can be included in returned random result). - * @param[in] aMax A maximum value (this value is excluded from returned random result). - * - * @returns A random `uint8_t` value in the given range (i.e., aMin <= random value < aMax). - */ -uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax); - -/** - * Generates and returns a random `uint16_t` value within a given range `[aMin, aMax)`. - * - * @note The returned random value can include the @p aMin value but excludes the @p aMax. - * - * @param[in] aMin A minimum value (this value can be included in returned random result). - * @param[in] aMax A maximum value (this value is excluded from returned random result). - * - * @returns A random `uint16_t` value in the given range (i.e., aMin <= random value < aMax). - */ -uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax); - -/** - * Generates and returns a random `uint32_t` value within a given range `[aMin, aMax)`. - * - * @note The returned random value can include the @p aMin value but excludes the @p aMax. - * - * @param[in] aMin A minimum value (this value can be included in returned random result). - * @param[in] aMax A maximum value (this value is excluded from returned random result). - * - * @returns A random `uint32_t` value in the given range (i.e., aMin <= random value < aMax). - */ -uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax); - +template UintType GenerateInClosedRange(UintType aMin, UintType aMax); /** * Fills a given buffer with random bytes. * diff --git a/src/core/common/time_ticker.cpp b/src/core/common/time_ticker.cpp index 9e0b348dd..dabe21afe 100644 --- a/src/core/common/time_ticker.cpp +++ b/src/core/common/time_ticker.cpp @@ -50,7 +50,7 @@ void TimeTicker::RegisterReceiver(Receiver aReceiver) if (!mTimer.IsRunning()) { - mTimer.Start(Random::NonCrypto::GetUint32InRange(0, kTickInterval + 1)); + mTimer.Start(Random::NonCrypto::GenerateInClosedRange(0, kTickInterval)); } } diff --git a/src/core/common/trickle_timer.cpp b/src/core/common/trickle_timer.cpp index 2f86f808c..edd0f0665 100644 --- a/src/core/common/trickle_timer.cpp +++ b/src/core/common/trickle_timer.cpp @@ -216,7 +216,7 @@ void TrickleTimer::Start(Mode aMode, uint32_t aIntervalMin, uint32_t aIntervalMa mMode = aMode; // Select interval randomly from range [Imin, Imax]. - mInterval = Random::NonCrypto::GetUint32InRange(mIntervalMin, mIntervalMax + 1); + mInterval = Random::NonCrypto::GenerateInClosedRange(mIntervalMin, mIntervalMax); StartNewInterval(); } @@ -257,11 +257,12 @@ void TrickleTimer::StartNewInterval(void) case kModeTrickle: // Select a random point in the interval taken from the range [I/2, I). - halfInterval = mInterval / 2; - mTimeInInterval = - (halfInterval < mInterval) ? Random::NonCrypto::GetUint32InRange(halfInterval, mInterval) : halfInterval; - mCounter = 0; - mPhase = kBeforeRandomTime; + halfInterval = mInterval / 2; + mTimeInInterval = (halfInterval < mInterval) + ? Random::NonCrypto::GenerateFromMinUpToExcluding(halfInterval, mInterval) + : halfInterval; + mCounter = 0; + mPhase = kBeforeRandomTime; break; } @@ -275,7 +276,7 @@ void TrickleTimer::HandleTimer(void) switch (mMode) { case kModePlainTimer: - mInterval = Random::NonCrypto::GetUint32InRange(mIntervalMin, mIntervalMax + 1); + mInterval = Random::NonCrypto::GenerateInClosedRange(mIntervalMin, mIntervalMax); StartNewInterval(); break; diff --git a/src/core/instance/instance.cpp b/src/core/instance/instance.cpp index 43527cd0b..cf706867e 100644 --- a/src/core/instance/instance.cpp +++ b/src/core/instance/instance.cpp @@ -331,7 +331,7 @@ Instance::Instance(void) #endif #endif , mIsInitialized(false) - , mId(Random::NonCrypto::GetUint32()) + , mId(Random::NonCrypto::Generate()) { #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE #if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE diff --git a/src/core/mac/channel_mask.cpp b/src/core/mac/channel_mask.cpp index 810d53d48..87e00db28 100644 --- a/src/core/mac/channel_mask.cpp +++ b/src/core/mac/channel_mask.cpp @@ -80,7 +80,7 @@ uint8_t ChannelMask::ChooseRandomChannel(void) const VerifyOrExit(!IsEmpty()); - randomIndex = Random::NonCrypto::GetUint8InRange(0, GetNumberOfChannels()); + randomIndex = Random::NonCrypto::GenerateUpToExcluding(GetNumberOfChannels()); SuccessOrExit(GetNextChannel(channel)); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index ca1a9c648..a865b2f21 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -66,8 +66,8 @@ Mac::Mac(Instance &aInstance) #endif , mOperation(kOperationIdle) , mPendingOperations(0) - , mBeaconSequence(Random::NonCrypto::GetUint8()) - , mDataSequence(Random::NonCrypto::GetUint8()) + , mBeaconSequence(Random::NonCrypto::Generate()) + , mDataSequence(Random::NonCrypto::Generate()) , mBroadcastTransmitCount(0) , mPanId(kPanIdBroadcast) , mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) diff --git a/src/core/mac/mac_types.cpp b/src/core/mac/mac_types.cpp index 897e05232..4ec56c1fc 100644 --- a/src/core/mac/mac_types.cpp +++ b/src/core/mac/mac_types.cpp @@ -52,7 +52,7 @@ PanId GenerateRandomPanId(void) do { - panId = Random::NonCrypto::GetUint16(); + panId = Random::NonCrypto::Generate(); } while (panId == kPanIdBroadcast); return panId; diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 27cefde5a..03e083468 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -469,7 +469,7 @@ void SubMac::StartTimerForBackoff(uint8_t aBackoffExponent) { uint32_t backoff; - backoff = Random::NonCrypto::GetUint32InRange(0, static_cast(1UL << aBackoffExponent)); + backoff = Random::NonCrypto::GenerateUpToExcluding(static_cast(1UL << aBackoffExponent)); backoff *= (kUnitBackoffPeriod * Radio::kSymbolTime); if (mRxOnWhenIdle) diff --git a/src/core/meshcop/meshcop_leader.cpp b/src/core/meshcop/meshcop_leader.cpp index afa52623b..1b700fd76 100644 --- a/src/core/meshcop/meshcop_leader.cpp +++ b/src/core/meshcop/meshcop_leader.cpp @@ -45,7 +45,7 @@ RegisterLogModule("MeshCoPLeader"); Leader::Leader(Instance &aInstance) : InstanceLocator(aInstance) , mTimer(aInstance) - , mSessionId(Random::NonCrypto::GetUint16()) + , mSessionId(Random::NonCrypto::Generate()) { } diff --git a/src/core/meshcop/timestamp.cpp b/src/core/meshcop/timestamp.cpp index 28f6ab349..f86aa35b9 100644 --- a/src/core/meshcop/timestamp.cpp +++ b/src/core/meshcop/timestamp.cpp @@ -124,7 +124,7 @@ void Timestamp::AdvanceRandomTicks(void) { uint16_t ticks = GetTicks(); - ticks += Random::NonCrypto::GetUint32InRange(1, kMaxTicks + 1); + ticks += Random::NonCrypto::GenerateInClosedRange(1, kMaxTicks); if (ticks > kMaxTicks) { diff --git a/src/core/net/dns_client.cpp b/src/core/net/dns_client.cpp index 4f7634ea7..9fe35c746 100644 --- a/src/core/net/dns_client.cpp +++ b/src/core/net/dns_client.cpp @@ -1789,7 +1789,7 @@ void Client::RecordServerAsLimitedToSingleQuestion(const Ip6::Address &aServerAd if (mLimitedQueryServers.IsFull()) { - uint8_t randomIndex = Random::NonCrypto::GetUint8InRange(0, mLimitedQueryServers.GetMaxSize()); + uint8_t randomIndex = Random::NonCrypto::GenerateUpToExcluding(mLimitedQueryServers.GetMaxSize()); mLimitedQueryServers.Remove(mLimitedQueryServers[randomIndex]); } diff --git a/src/core/net/dns_dso.cpp b/src/core/net/dns_dso.cpp index 1102bb1c7..245044cdc 100644 --- a/src/core/net/dns_dso.cpp +++ b/src/core/net/dns_dso.cpp @@ -631,7 +631,7 @@ Error Dso::Connection::AppendPadding(Message &aMessage) // that its padded length is a multiple of the chosen block // length. - blockLength = kBlockLengths[Random::NonCrypto::GetUint8InRange(0, GetArrayLength(kBlockLengths))]; + blockLength = kBlockLengths[Random::NonCrypto::GenerateUpToExcluding(GetArrayLength(kBlockLengths))]; paddingTlv.Init((blockLength - ((aMessage.GetLength() + sizeof(Tlv)) % blockLength)) % blockLength); diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 301d6d86a..f6feb48a2 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -558,7 +558,7 @@ Error Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto) header.SetNextHeader(kProtoFragment); fragmentHeader.Init(); - fragmentHeader.SetIdentification(Random::NonCrypto::GetUint32()); + fragmentHeader.SetIdentification(Random::NonCrypto::Generate()); fragmentHeader.SetNextHeader(aIpProto); fragmentHeader.SetMoreFlag(); diff --git a/src/core/net/ip6_mpl.cpp b/src/core/net/ip6_mpl.cpp index 0790210ab..cbfe7e23f 100644 --- a/src/core/net/ip6_mpl.cpp +++ b/src/core/net/ip6_mpl.cpp @@ -448,7 +448,7 @@ void Mpl::HandleRetransmissionTimer(void) void Mpl::Metadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval) { // Emulate Trickle timer behavior and set up the next retransmission within [0,I) range. - uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval); + uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GenerateUpToExcluding(aInterval); // Set transmission time at the beginning of the next interval. mTransmissionTime = aCurrentTime + static_cast(mIntervalOffset + t); diff --git a/src/core/net/mdns.cpp b/src/core/net/mdns.cpp index 56589cad2..d2aad10df 100644 --- a/src/core/net/mdns.cpp +++ b/src/core/net/mdns.cpp @@ -4337,7 +4337,7 @@ Core::RxMessage::ProcessOutcome Core::RxMessage::ProcessQuery(bool aShouldProces if (shouldDelay) { - delay = Random::NonCrypto::GetUint16InRange(kMinResponseDelay, kMaxResponseDelay); + delay = Random::NonCrypto::GenerateInClosedRange(kMinResponseDelay, kMaxResponseDelay); } for (const Question &question : mQuestions) @@ -5035,7 +5035,7 @@ void Core::MultiPacketRxMessages::RxMsgEntry::Add(OwnedPtr &aRxMessag if (aRxMessagePtr->IsTruncated()) { - mProcessTime += Random::NonCrypto::GetUint32InRange(kMinProcessDelay, kMaxProcessDelay); + mProcessTime += Random::NonCrypto::GenerateInClosedRange(kMinProcessDelay, kMaxProcessDelay); } // We push the new `RxMessage` at tail of the list to keep the @@ -5416,7 +5416,7 @@ TimeMilli Core::RandomizeFirstProbeTxTime(void) if ((mNextProbeTxTime - now) >= kMaxProbeDelay) { - mNextProbeTxTime = now + Random::NonCrypto::GetUint32InRange(kMinProbeDelay, kMaxProbeDelay); + mNextProbeTxTime = now + Random::NonCrypto::GenerateInClosedRange(kMinProbeDelay, kMaxProbeDelay); } return mNextProbeTxTime; @@ -5428,7 +5428,7 @@ TimeMilli Core::RandomizeInitialQueryTxTime(void) if ((mNextQueryTxTime - now) >= kMaxInitialQueryDelay) { - mNextQueryTxTime = now + Random::NonCrypto::GetUint32InRange(kMinInitialQueryDelay, kMaxInitialQueryDelay); + mNextQueryTxTime = now + Random::NonCrypto::GenerateInClosedRange(kMinInitialQueryDelay, kMaxInitialQueryDelay); } return mNextQueryTxTime; @@ -5550,7 +5550,7 @@ void Core::CacheRecordInfo::UpdateQueryAndFireTimeOn(CacheEntry &aCacheEntry) if (queryTime > now) { - queryTime += Random::NonCrypto::GetUint32InRange(0, GetClampedTtl() * kQueryTtlVariation); + queryTime += Random::NonCrypto::GenerateUpToExcluding(GetClampedTtl() * kQueryTtlVariation); aCacheEntry.ScheduleQuery(queryTime); break; } diff --git a/src/core/net/nat64_translator.cpp b/src/core/net/nat64_translator.cpp index c5fe4d8e3..332417d6f 100644 --- a/src/core/net/nat64_translator.cpp +++ b/src/core/net/nat64_translator.cpp @@ -365,7 +365,7 @@ uint16_t Translator::AllocateSourcePort(uint16_t aSrcPort) do { - port = Random::NonCrypto::GetUint16InRange(kMinTranslationPort, kMaxTranslationPort); + port = Random::NonCrypto::GenerateInClosedRange(kMinTranslationPort, kMaxTranslationPort); // The NAT64 SHOULD preserve the port parity (odd/even), as // per Section 4.2.2 of [RFC4787]). Determine if original and diff --git a/src/core/net/srp_client.cpp b/src/core/net/srp_client.cpp index 769bd5c78..f2b299191 100644 --- a/src/core/net/srp_client.cpp +++ b/src/core/net/srp_client.cpp @@ -232,7 +232,7 @@ uint32_t Client::TxJitter::DetermineDelay(void) mRequestedMax = 0; } - delay = Random::NonCrypto::GetUint32InRange(kMinTxJitter, maxJitter); + delay = Random::NonCrypto::GenerateInClosedRange(kMinTxJitter, maxJitter); LogInfo("Use random tx jitter %lu from [%lu, %lu]", ToUlong(delay), ToUlong(kMinTxJitter), ToUlong(maxJitter)); return delay; @@ -1942,7 +1942,7 @@ void Client::SelectNewMessageId(void) do { - mCurMessageId = Random::NonCrypto::GetUint16(); + mCurMessageId = Random::NonCrypto::Generate(); } while (oldId == mCurMessageId); } diff --git a/src/core/net/srp_server.cpp b/src/core/net/srp_server.cpp index 6b72cd507..431c90b4b 100644 --- a/src/core/net/srp_server.cpp +++ b/src/core/net/srp_server.cpp @@ -80,7 +80,7 @@ Server::Server(Instance &aInstance) , mLeaseTimer(aInstance) , mOutstandingUpdatesTimer(aInstance) , mCompletedUpdateTask(aInstance) - , mServiceUpdateId(Random::NonCrypto::GetUint32()) + , mServiceUpdateId(Random::NonCrypto::Generate()) , mPort(kUninitializedPort) , mState(kStateDisabled) , mAddressMode(kDefaultAddressMode) diff --git a/src/core/thread/announce_sender.cpp b/src/core/thread/announce_sender.cpp index 2acfe87d8..f49e71c72 100644 --- a/src/core/thread/announce_sender.cpp +++ b/src/core/thread/announce_sender.cpp @@ -68,7 +68,7 @@ void AnnounceSenderBase::SendAnnounce(uint8_t aCount) mCount = aCount; mChannel = mStartingChannel; - mTimer.Start(Random::NonCrypto::GetUint32InRange(0, mJitter + 1)); + mTimer.Start(Random::NonCrypto::GenerateUpToExcluding(mJitter + 1)); exit: return; diff --git a/src/core/thread/dua_manager.cpp b/src/core/thread/dua_manager.cpp index 9e73429f6..0c6b4e061 100644 --- a/src/core/thread/dua_manager.cpp +++ b/src/core/thread/dua_manager.cpp @@ -732,7 +732,8 @@ void DuaManager::HandleChildDuaAddressEvent(const Child &aChild, ChildDuaAddress { if (mChildDuaMask == mChildDuaRegisteredMask) { - UpdateCheckDelay(Random::NonCrypto::GetUint8InRange(1, BackboneRouter::kParentAggregateDelay)); + UpdateCheckDelay( + Random::NonCrypto::GenerateInClosedRange(1, BackboneRouter::kParentAggregateDelay)); } mChildDuaMask.Add(childIndex); diff --git a/src/core/thread/message_framer.cpp b/src/core/thread/message_framer.cpp index 9cb9424bf..c91674e5b 100644 --- a/src/core/thread/message_framer.cpp +++ b/src/core/thread/message_framer.cpp @@ -40,7 +40,7 @@ namespace ot { MessageFramer::MessageFramer(Instance &aInstance) : InstanceLocator(aInstance) { - mFragTag = Random::NonCrypto::GetUint16(); + mFragTag = Random::NonCrypto::Generate(); } void MessageFramer::DetermineMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Addresses &aMacAddrs) const diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 198517dec..affa8d337 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -652,7 +652,7 @@ uint32_t Mle::GenerateRandomDelay(uint32_t aMaxDelay) const { // Generates a random delay within `[1, aMaxDelay]` (inclusive). - return 1 + Random::NonCrypto::GetUint32InRange(0, aMaxDelay); + return Random::NonCrypto::GenerateInClosedRange(1, aMaxDelay); } void Mle::SetTimeout(uint32_t aTimeout, TimeoutAction aAction) @@ -2819,7 +2819,7 @@ void Mle::ParentSearch::StartTimer(void) ExitNow(); } - interval = Random::NonCrypto::GetUint32InRange(0, kJitterInterval); + interval = Random::NonCrypto::GenerateUpToExcluding(kJitterInterval); if (mIsInBackoff) { @@ -4485,7 +4485,8 @@ void Mle::PrevRoleRestorer::SendMulticastLinkRequest(void) retxDelayMax = kLeaderRetxDelayMax; } - delay = (mAttempts == 0) ? kLinkRequestTimeout : Random::NonCrypto::GetUint32InRange(retxDelayMin, retxDelayMax); + delay = + (mAttempts == 0) ? kLinkRequestTimeout : Random::NonCrypto::GenerateInClosedRange(retxDelayMin, retxDelayMax); mTimer.Start(delay); @@ -4666,7 +4667,7 @@ uint32_t Mle::Attacher::GetStartDelay(void) const } #endif // OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE - jitter = Random::NonCrypto::GetUint32InRange(0, kAttachStartJitter); + jitter = Random::NonCrypto::GenerateUpToExcluding(kAttachStartJitter); if (jitter + delay > delay) // check for overflow { diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index 5a2f5075b..fc0e47445 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -303,7 +303,7 @@ uint8_t Mle::SelectLeaderId(void) const #endif return IsValueInRange(mPreviousRouterId, minId, maxId) ? mPreviousRouterId - : Random::NonCrypto::GetUint8InRange(minId, maxId + 1); + : Random::NonCrypto::GenerateInClosedRange(minId, maxId); } uint32_t Mle::SelectPartitionId(void) const @@ -318,7 +318,7 @@ uint32_t Mle::SelectPartitionId(void) const else #endif { - partitionId = Random::NonCrypto::GetUint32(); + partitionId = Random::NonCrypto::Generate(); } return partitionId; @@ -1432,7 +1432,8 @@ void Mle::EstablishRouterLinkOnFtdChild(Router &aRouter, RxInfo &aRxInfo, uint8_ VerifyOrExit(neighborCount < mChildRouterLinks + GradualChildRouterLink::kExtraChildRouterLinks); VerifyOrExit(LinkQualityForLinkMargin(aLinkMargin) >= kLinkQuality2); VerifyOrExit(GetCurrentAttachDuration() > GradualChildRouterLink::kWaitDurationAfterAttach); - VerifyOrExit(Random::NonCrypto::GetUint8InRange(0, 100) < GradualChildRouterLink::kProbabilityPercentage); + VerifyOrExit(Random::NonCrypto::GenerateUpToExcluding(100) < + GradualChildRouterLink::kProbabilityPercentage); minDelay = GradualChildRouterLink::kMinLinkRequestDelay; maxDelay = GradualChildRouterLink::kMaxLinkRequestDelay; @@ -1441,7 +1442,7 @@ void Mle::EstablishRouterLinkOnFtdChild(Router &aRouter, RxInfo &aRxInfo, uint8_ InitNeighbor(aRouter, aRxInfo); aRouter.SetState(Neighbor::kStateLinkRequest); aRouter.ClearLinkAcceptTimeout(); - mDelayedSender.ScheduleLinkRequest(aRouter, Random::NonCrypto::GetUint32InRange(minDelay, maxDelay)); + mDelayedSender.ScheduleLinkRequest(aRouter, Random::NonCrypto::GenerateInClosedRange(minDelay, maxDelay)); exit: return; @@ -3981,7 +3982,7 @@ Mle::RoleTransitioner::RoleTransitioner(Instance &aInstance) { } -void Mle::RoleTransitioner::StartTimeout(void) { mTimeout = 1 + Random::NonCrypto::GetUint8InRange(0, mJitter); } +void Mle::RoleTransitioner::StartTimeout(void) { mTimeout = 1 + Random::NonCrypto::GenerateUpToExcluding(mJitter); } bool Mle::RoleTransitioner::IsRouterCountBelowUpgradeThreshold(void) const { diff --git a/src/core/thread/mlr_manager.cpp b/src/core/thread/mlr_manager.cpp index 1dd9bba02..fe3a773ca 100644 --- a/src/core/thread/mlr_manager.cpp +++ b/src/core/thread/mlr_manager.cpp @@ -169,7 +169,7 @@ void Manager::UpdateProxiedSubscriptions(Child &aChild, const ChildAddressArray if (hasUnregistered) { - ScheduleSend(Random::NonCrypto::GetUint16InRange(1, BackboneRouter::kParentAggregateDelay)); + ScheduleSend(Random::NonCrypto::GenerateInClosedRange(1, BackboneRouter::kParentAggregateDelay)); } exit: @@ -579,7 +579,7 @@ uint32_t Manager::DetermineRenewDelay(void) timeout = Clamp(timeout, BackboneRouter::kMinMlrTimeout, kLongRenewTimeout); - return Random::NonCrypto::GetUint32InRange((timeout / 2) + 1, timeout - kRenewGuardTime); + return Random::NonCrypto::GenerateInClosedRange((timeout / 2) + 1, timeout - kRenewGuardTime); } void Manager::ScheduleNextRegistration(RegistrationRequest aRequest) diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 7d564ae79..3c9fa4791 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -57,8 +57,8 @@ Leader::Leader(Instance &aInstance) void Leader::Reset(void) { - mVersion = Random::NonCrypto::GetUint8(); - mStableVersion = Random::NonCrypto::GetUint8(); + mVersion = Random::NonCrypto::Generate(); + mStableVersion = Random::NonCrypto::Generate(); SetLength(0); SignalNetDataChanged(); diff --git a/src/core/thread/network_data_notifier.cpp b/src/core/thread/network_data_notifier.cpp index b7e3e9ad0..63b218965 100644 --- a/src/core/thread/network_data_notifier.cpp +++ b/src/core/thread/network_data_notifier.cpp @@ -321,7 +321,7 @@ void Notifier::ScheduleRouterRoleUpgradeIfEligible(void) VerifyOrExit(Get().IsChild()); VerifyOrExit(IsEligibleForRouterRoleUpgradeAsBorderRouter() && (mRouterRoleUpgradeTimeout == 0)); - mRouterRoleUpgradeTimeout = Random::NonCrypto::GetUint8InRange(1, kRouterRoleUpgradeMaxTimeout + 1); + mRouterRoleUpgradeTimeout = Random::NonCrypto::GenerateInClosedRange(1, kRouterRoleUpgradeMaxTimeout); Get().RegisterReceiver(TimeTicker::kNetworkDataNotifier); exit: diff --git a/src/core/thread/network_data_publisher.cpp b/src/core/thread/network_data_publisher.cpp index f880c879e..35b755442 100644 --- a/src/core/thread/network_data_publisher.cpp +++ b/src/core/thread/network_data_publisher.cpp @@ -305,7 +305,7 @@ void Publisher::Entry::UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEnt if (aNumEntries < aDesiredNumEntries) { - mUpdateTime = now + Random::NonCrypto::GetUint32InRange(1, kMaxDelayToAdd); + mUpdateTime = now + Random::NonCrypto::GenerateInClosedRange(1, kMaxDelayToAdd); SetState(kAdding); Get().GetTimer().FireAtIfEarlier(mUpdateTime); LogUpdateTime(now); @@ -345,7 +345,7 @@ void Publisher::Entry::UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEnt if (aDesiredNumEntries > 0) { - mUpdateTime += Random::NonCrypto::GetUint32InRange(1, kMaxDelayToRemove); + mUpdateTime += Random::NonCrypto::GenerateInClosedRange(1, kMaxDelayToRemove); if (aNumPreferredEntries < aDesiredNumEntries) { diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index 0daef2cf4..6ee9c0a7d 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -886,7 +886,7 @@ exit: Client::Client(Instance &aInstance) : InstanceLocator(aInstance) - , mQueryId(Random::NonCrypto::GetUint16()) + , mQueryId(Random::NonCrypto::Generate()) { } diff --git a/src/core/thread/radio_selector.cpp b/src/core/thread/radio_selector.cpp index 4c16ea011..0a9dde05e 100644 --- a/src/core/thread/radio_selector.cpp +++ b/src/core/thread/radio_selector.cpp @@ -309,7 +309,7 @@ Mac::TxFrame &RadioSelector::SelectRadio(Message &aMessage, const Mac::Address & #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE if (!selections.Contains(Mac::kRadioTypeTrel) && neighbor->GetSupportedRadioTypes().Contains(Mac::kRadioTypeTrel) && - (Random::NonCrypto::GetUint8InRange(0, 100) < kTrelProbeProbability)) + (Random::NonCrypto::GenerateUpToExcluding(100) < kTrelProbeProbability)) { aTxFrames.SetRequiredRadioTypes(selections); selections.Add(Mac::kRadioTypeTrel); diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp index fac5dea9e..a4f3154c4 100644 --- a/src/core/thread/router_table.cpp +++ b/src/core/thread/router_table.cpp @@ -41,7 +41,7 @@ RouterTable::RouterTable(Instance &aInstance) , mRouters(aInstance) , mChangedTask(aInstance) , mRouterIdSequenceLastUpdated(0) - , mRouterIdSequence(Random::NonCrypto::GetUint8()) + , mRouterIdSequence(Random::NonCrypto::Generate()) , mEvents(0) #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE , mMinRouterId(0) @@ -168,7 +168,7 @@ Router *RouterTable::Allocate(void) // selected ID with current entry in the list with // probably `1/numAvailable`. - if (Random::NonCrypto::GetUint8InRange(0, numAvailable) == 0) + if (Random::NonCrypto::GenerateUpToExcluding(numAvailable) == 0) { selectedRouterId = routerId; } diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp index 8a7957507..d46ab3f8a 100644 --- a/src/core/utils/channel_manager.cpp +++ b/src/core/utils/channel_manager.cpp @@ -100,7 +100,7 @@ void ChannelManager::RequestNetworkChannelChange(uint8_t aChannel) mState = kStateChangeRequested; mChannel = aChannel; - mTimer.Start(1 + Random::NonCrypto::GetUint32InRange(0, kRequestStartJitterInterval)); + mTimer.Start(1 + Random::NonCrypto::GenerateUpToExcluding(kRequestStartJitterInterval)); Get().Signal(kEventChannelManagerNewChannelChanged); diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp index c77dd091a..cb3fe5622 100644 --- a/src/core/utils/jam_detector.cpp +++ b/src/core/utils/jam_detector.cpp @@ -188,7 +188,7 @@ void JamDetector::HandleTimer(void) } } - mTimer.Start(mSampleInterval + Random::NonCrypto::GetUint32InRange(0, kMaxRandomDelay)); + mTimer.Start(mSampleInterval + Random::NonCrypto::GenerateUpToExcluding(kMaxRandomDelay)); exit: return; diff --git a/tests/nexus/test_dtls.cpp b/tests/nexus/test_dtls.cpp index 531fcb4ef..d889917eb 100644 --- a/tests/nexus/test_dtls.cpp +++ b/tests/nexus/test_dtls.cpp @@ -125,11 +125,11 @@ OwnedPtr PrepareMessage(Node &aNode) VerifyOrQuit(message != nullptr); - length = Random::NonCrypto::GetUint16InRange(1, kMessageSize); + length = Random::NonCrypto::GenerateFromMinUpToExcluding(1, kMessageSize); for (uint16_t i = 0; i < length; i++) { - SuccessOrQuit(message->Append(Random::NonCrypto::GetUint8())); + SuccessOrQuit(message->Append(Random::NonCrypto::Generate())); } return OwnedPtr(message); diff --git a/tests/nexus/test_srp_lease.cpp b/tests/nexus/test_srp_lease.cpp index a49c766b6..81a6adca4 100644 --- a/tests/nexus/test_srp_lease.cpp +++ b/tests/nexus/test_srp_lease.cpp @@ -144,8 +144,8 @@ static void UpdateSrpRegistration(Node &aNode) service->mSubTypeLabels = nullptr; service->mTxtEntries = nullptr; service->mNumTxtEntries = 0; - service->mPort = Random::NonCrypto::GetUint16InRange(0x100, 0xff00); - service->mSubTypeLabels = &info->mSubTypeLabels[Random::NonCrypto::GetUint8InRange(0, 4)]; + service->mPort = Random::NonCrypto::GenerateFromMinUpToExcluding(0x100, 0xff00); + service->mSubTypeLabels = &info->mSubTypeLabels[Random::NonCrypto::GenerateUpToExcluding(4)]; SuccessOrQuit(aNode.Get().AddService(*service)); } @@ -154,7 +154,7 @@ static bool ShouldPerform(uint16_t aProbability) { // Uses the given probability to randomly decide whether a certain action should be performed. - return Random::NonCrypto::GetUint16InRange(0, 1000) < aProbability; + return Random::NonCrypto::GenerateUpToExcluding(1000) < aProbability; } static const Srp::Server::Host *FindHost(Node &aServer, const char *aName) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 1c02f08c5..dbb48f487 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -250,6 +250,7 @@ ot_unit_test(pool) ot_unit_test(power_calibration) ot_unit_test(priority_queue) ot_unit_test(pskc) +ot_unit_test(random) ot_unit_test(routing_manager) ot_unit_test(seeker) ot_unit_test(serial_number) diff --git a/tests/unit/test_checksum.cpp b/tests/unit/test_checksum.cpp index 2d09071ad..a57e96bf2 100644 --- a/tests/unit/test_checksum.cpp +++ b/tests/unit/test_checksum.cpp @@ -159,11 +159,11 @@ void CorruptMessage(Message &aMessage) uint8_t bitOffset; uint8_t byte; - byteOffset = Random::NonCrypto::GetUint16InRange(0, aMessage.GetLength()); + byteOffset = Random::NonCrypto::GenerateUpToExcluding(aMessage.GetLength()); SuccessOrQuit(aMessage.Read(byteOffset, byte)); - bitOffset = Random::NonCrypto::GetUint8InRange(0, kBitsPerByte); + bitOffset = Random::NonCrypto::GenerateUpToExcluding(kBitsPerByte); byte ^= (1 << bitOffset); diff --git a/tests/unit/test_random.cpp b/tests/unit/test_random.cpp new file mode 100644 index 000000000..37e0089e3 --- /dev/null +++ b/tests/unit/test_random.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2026, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * +c * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_platform.h" + +#include + +#include "test_util.h" +#include "common/code_utils.hpp" +#include "common/num_utils.hpp" +#include "common/numeric_limits.hpp" +#include "common/random.hpp" + +namespace ot { + +template void TestRandomNonCryto(const char *aName) +{ + static constexpr uint8_t kMaxIters = 6; + + Instance *instance = static_cast(testInitInstance()); + UintType value; + UintType max = NumericLimits::kMax; + + VerifyOrQuit(instance != nullptr); + + printf("--------------------------------------------------------------------\n\r"); + printf("TestRandomNonCryto<%s>()\r\n", aName); + + //-------------------------------------------------------------------------- + // GenerateUpToExcluding + + value = Random::NonCrypto::GenerateUpToExcluding(0); + VerifyOrQuit(value == 0); + + printf("\r\nGenerateUpToExcluding(100): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateUpToExcluding(100); + printf("%lu, ", ToUlong(value)); + + VerifyOrQuit(value < 100); + } + + printf("\r\nGenerateUpToExcluding(kMax): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateUpToExcluding(max); + printf("0x%lx, ", ToUlong(value)); + + VerifyOrQuit(value < max); + } + + //-------------------------------------------------------------------------- + // GenerateUpToExcluding + + value = Random::NonCrypto::GenerateFromMinUpToExcluding(12, 12); + VerifyOrQuit(value == 12); + + value = Random::NonCrypto::GenerateFromMinUpToExcluding(12, 11); + VerifyOrQuit(value == 12); + + value = Random::NonCrypto::GenerateFromMinUpToExcluding(12, 0); + VerifyOrQuit(value == 12); + + value = Random::NonCrypto::GenerateFromMinUpToExcluding(max, 0); + VerifyOrQuit(value == max); + + value = Random::NonCrypto::GenerateFromMinUpToExcluding(max, max); + VerifyOrQuit(value == max); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateFromMinUpToExcluding(iter, iter + 1); + VerifyOrQuit(value == iter); + } + + printf("\r\nGenerateFromMinUpToExcluding(100, 105): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateFromMinUpToExcluding(100, 105); + printf("%lu, ", ToUlong(value)); + + VerifyOrQuit(value >= 100); + VerifyOrQuit(value < 105); + } + + printf("\r\nGenerateFromMinUpToExcluding(max - 2, max): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateFromMinUpToExcluding(max - 2, max); + printf("0x%lx, ", ToUlong(value)); + + VerifyOrQuit(value >= max - 2); + VerifyOrQuit(value < max); + } + + printf("\r\nGenerateFromMinUpToExcluding(0, max): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateFromMinUpToExcluding(0, max); + printf("0x%lx, ", ToUlong(value)); + + VerifyOrQuit(value < max); + } + + //-------------------------------------------------------------------------- + // GenerateInClosedRange + + value = Random::NonCrypto::GenerateInClosedRange(101, 101); + VerifyOrQuit(value == 101); + + value = Random::NonCrypto::GenerateInClosedRange(101, 100); + VerifyOrQuit(value == 101); + + value = Random::NonCrypto::GenerateInClosedRange(101, 0); + VerifyOrQuit(value == 101); + + value = Random::NonCrypto::GenerateInClosedRange(max, max); + VerifyOrQuit(value == max); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateInClosedRange(iter, iter); + VerifyOrQuit(value == iter); + } + + printf("\r\nGenerateInClosedRange(200, 201): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateInClosedRange(200, 201); + printf("%lu, ", ToUlong(value)); + + VerifyOrQuit(value >= 200); + VerifyOrQuit(value <= 201); + } + + while (true) + { + // Make sure upper bound can be returned + + value = Random::NonCrypto::GenerateInClosedRange(100, 101); + VerifyOrQuit(value >= 100); + VerifyOrQuit(value <= 101); + + if (value == 101) + { + break; + } + } + + printf("\r\nGenerateInClosedRange(0, max): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateInClosedRange(0, max); + printf("0x%lx, ", ToUlong(value)); + } + + printf("\r\nGenerateInClosedRange(max-1, max): "); + + for (uint8_t iter = 0; iter < kMaxIters; iter++) + { + value = Random::NonCrypto::GenerateInClosedRange(max - 1, max); + printf("0x%lx, ", ToUlong(value)); + + VerifyOrQuit(value >= max - 1); + } + + while (true) + { + // Make sure upper bound can be returned + + value = Random::NonCrypto::GenerateInClosedRange(max - 1, max); + VerifyOrQuit(value >= max - 1); + + if (value == max) + { + break; + } + } + + printf("\r\nTest passed\r\n"); +} + +} // namespace ot + +int main(void) +{ + ot::TestRandomNonCryto("uint8_t"); + ot::TestRandomNonCryto("uint16_t"); + ot::TestRandomNonCryto("uint32_t"); + + printf("\nAll tests passed.\n"); + return 0; +} diff --git a/tests/unit/test_spinel_buffer.cpp b/tests/unit/test_spinel_buffer.cpp index 0d01102d4..bc567a717 100644 --- a/tests/unit/test_spinel_buffer.cpp +++ b/tests/unit/test_spinel_buffer.cpp @@ -887,7 +887,7 @@ uint32_t GetRandom(uint32_t max) } else { - value = Random::NonCrypto::GetUint32(); + value = Random::NonCrypto::Generate(); } return value % max;