Skip to main content

max / makenotwork

Bump rand to 0.10 across MNW crates rand 0.9/0.8 -> 0.10.2 in server, multithreaded, and synckit-client. 0.10 dropped the rand::RngCore re-export (fill_bytes now resolves via the rand::Rng trait) and moved random/random_range/sample onto a new RngExt extension trait; imports updated per call site. multithreaded's 0.8 thread_rng() calls become rand::rng(). The CSPRNG source (rand::rng()) is unchanged, so nonce/key/token generation keeps its security properties. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-21 00:19 UTC
Commit: 4d1b1ff8f162b9ec6131bbe7eda33578bba4ebf2
Parent: 47ac267
24 files changed, +90 insertions, -82 deletions
@@ -756,6 +756,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
756 756 checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
757 757
758 758 [[package]]
759 + name = "chacha20"
760 + version = "0.10.1"
761 + source = "registry+https://github.com/rust-lang/crates.io-index"
762 + checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
763 + dependencies = [
764 + "cfg-if",
765 + "cpufeatures 0.3.0",
766 + "rand_core 0.10.1",
767 + ]
768 +
769 + [[package]]
759 770 name = "chrono"
760 771 version = "0.4.44"
761 772 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1460,6 +1471,7 @@ dependencies = [
1460 1471 "cfg-if",
1461 1472 "libc",
1462 1473 "r-efi 6.0.0",
1474 + "rand_core 0.10.1",
1463 1475 "wasip2",
1464 1476 "wasip3",
1465 1477 ]
@@ -2301,7 +2313,7 @@ dependencies = [
2301 2313 "mt-db",
2302 2314 "pom-contract",
2303 2315 "pulldown-cmark",
2304 - "rand 0.8.5",
2316 + "rand 0.10.2",
2305 2317 "regex-lite",
2306 2318 "reqwest",
2307 2319 "s3-storage",
@@ -2817,6 +2829,17 @@ dependencies = [
2817 2829 ]
2818 2830
2819 2831 [[package]]
2832 + name = "rand"
2833 + version = "0.10.2"
2834 + source = "registry+https://github.com/rust-lang/crates.io-index"
2835 + checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
2836 + dependencies = [
2837 + "chacha20",
2838 + "getrandom 0.4.2",
2839 + "rand_core 0.10.1",
2840 + ]
2841 +
2842 + [[package]]
2820 2843 name = "rand_chacha"
2821 2844 version = "0.3.1"
2822 2845 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2855,6 +2878,12 @@ dependencies = [
2855 2878 ]
2856 2879
2857 2880 [[package]]
2881 + name = "rand_core"
2882 + version = "0.10.1"
2883 + source = "registry+https://github.com/rust-lang/crates.io-index"
2884 + checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
2885 +
2886 + [[package]]
2858 2887 name = "raw-cpuid"
2859 2888 version = "11.6.0"
2860 2889 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -36,7 +36,7 @@ url = "2"
36 36 sha2 = "0.10"
37 37 hmac = "0.12"
38 38 base64 = "0.22"
39 - rand = "0.8"
39 + rand = "0.10"
40 40
41 41 # S3 storage
42 42 s3-storage = { path = "../shared/s3-storage" }
@@ -12,7 +12,7 @@ use axum::{
12 12 Json,
13 13 };
14 14 use base64::Engine;
15 - use rand::RngCore;
15 + use rand::Rng;
16 16 use serde::{Deserialize, Serialize};
17 17 use sha2::{Digest, Sha256};
18 18 use tokio::time::sleep;
@@ -24,7 +24,7 @@ use crate::AppState;
24 24
25 25 fn generate_verifier() -> String {
26 26 let mut bytes = [0u8; 32];
27 - rand::thread_rng().fill_bytes(&mut bytes);
27 + rand::rng().fill_bytes(&mut bytes);
28 28 base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes)
29 29 }
30 30
@@ -37,7 +37,7 @@ fn pkce_challenge(verifier: &str) -> String {
37 37
38 38 fn generate_state_nonce() -> String {
39 39 let mut bytes = [0u8; 16];
40 - rand::thread_rng().fill_bytes(&mut bytes);
40 + rand::rng().fill_bytes(&mut bytes);
41 41 hex::encode(bytes)
42 42 }
43 43
@@ -9,7 +9,7 @@ use axum::{
9 9 middleware::Next,
10 10 response::{IntoResponse, Response},
11 11 };
12 - use rand::RngCore;
12 + use rand::Rng;
13 13 use tower_sessions::Session;
14 14
15 15 const CSRF_SESSION_KEY: &str = "csrf_token";
@@ -18,7 +18,7 @@ const CSRF_TOKEN_LENGTH: usize = 32;
18 18 /// Generate a new random CSRF token (64-char hex string).
19 19 pub fn generate_token() -> String {
20 20 let mut token = [0u8; CSRF_TOKEN_LENGTH];
21 - rand::thread_rng().fill_bytes(&mut token);
21 + rand::rng().fill_bytes(&mut token);
22 22 hex::encode(token)
23 23 }
24 24
@@ -1606,13 +1606,24 @@ dependencies = [
1606 1606 ]
1607 1607
1608 1608 [[package]]
1609 + name = "chacha20"
1610 + version = "0.10.1"
1611 + source = "registry+https://github.com/rust-lang/crates.io-index"
1612 + checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
1613 + dependencies = [
1614 + "cfg-if",
1615 + "cpufeatures 0.3.0",
1616 + "rand_core 0.10.1",
1617 + ]
1618 +
1619 + [[package]]
1609 1620 name = "chacha20poly1305"
1610 1621 version = "0.10.1"
1611 1622 source = "registry+https://github.com/rust-lang/crates.io-index"
1612 1623 checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
1613 1624 dependencies = [
1614 1625 "aead",
1615 - "chacha20",
1626 + "chacha20 0.9.1",
1616 1627 "cipher 0.4.4",
1617 1628 "poly1305",
1618 1629 "zeroize",
@@ -3145,6 +3156,7 @@ dependencies = [
3145 3156 "js-sys",
3146 3157 "libc",
3147 3158 "r-efi 6.0.0",
3159 + "rand_core 0.10.1",
3148 3160 "wasm-bindgen",
3149 3161 ]
3150 3162
@@ -4409,7 +4421,7 @@ dependencies = [
4409 4421 "openssl",
4410 4422 "pom-contract",
4411 4423 "proptest",
4412 - "rand 0.9.4",
4424 + "rand 0.10.2",
4413 4425 "regex",
4414 4426 "reqwest 0.13.4",
4415 4427 "s3-storage",
@@ -5767,6 +5779,17 @@ dependencies = [
5767 5779 ]
5768 5780
5769 5781 [[package]]
5782 + name = "rand"
5783 + version = "0.10.2"
5784 + source = "registry+https://github.com/rust-lang/crates.io-index"
5785 + checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
5786 + dependencies = [
5787 + "chacha20 0.10.1",
5788 + "getrandom 0.4.3",
5789 + "rand_core 0.10.1",
5790 + ]
5791 +
5792 + [[package]]
5770 5793 name = "rand_chacha"
5771 5794 version = "0.3.1"
5772 5795 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5805,6 +5828,12 @@ dependencies = [
5805 5828 ]
5806 5829
5807 5830 [[package]]
5831 + name = "rand_core"
5832 + version = "0.10.1"
5833 + source = "registry+https://github.com/rust-lang/crates.io-index"
5834 + checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
5835 +
5836 + [[package]]
5808 5837 name = "rand_xorshift"
5809 5838 version = "0.4.0"
5810 5839 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -70,7 +70,7 @@ webauthn-rs-proto = "0.5"
70 70 openssl = { version = "0.10", features = ["vendored"] }
71 71
72 72 # Security
73 - rand = "0.9"
73 + rand = "0.10"
74 74 hmac = "0.12.1"
75 75 sha1 = "0.10.6"
76 76 sha2 = "0.10.9"
@@ -235,7 +235,7 @@ impl Config {
235 235 }
236 236 tracing::warn!("SIGNING_SECRET not set — using random value (dev mode only)");
237 237 let mut bytes = [0u8; 32];
238 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut bytes);
238 + rand::Rng::fill_bytes(&mut rand::rng(), &mut bytes);
239 239 hex::encode(bytes)
240 240 }
241 241 };
@@ -38,7 +38,7 @@ pub fn encrypt_totp_secret(plaintext: &str, signing_secret: &str) -> String {
38 38 let cipher = ChaCha20Poly1305::new((&key).into());
39 39
40 40 let mut nonce_bytes = [0u8; 12];
41 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut nonce_bytes);
41 + rand::Rng::fill_bytes(&mut rand::rng(), &mut nonce_bytes);
42 42 let nonce = Nonce::from(nonce_bytes);
43 43
44 44 let ciphertext = cipher
@@ -125,7 +125,7 @@ pub fn constant_time_compare(a: &str, b: &str) -> bool {
125 125 /// any realistic license catalog. Returns a `KeyCode` via `from_trusted` —
126 126 /// the wordlist guarantees validity.
127 127 pub fn generate_key_code() -> crate::db::KeyCode {
128 - use rand::Rng;
128 + use rand::RngExt;
129 129 let mut rng = rand::rng();
130 130 let words: Vec<&str> = (0..6)
131 131 .map(|_| {
@@ -142,7 +142,7 @@ pub fn generate_key_code() -> crate::db::KeyCode {
142 142 /// bytes (~256 bits) rendered as hex so it's safe in a Basic-auth password / URL.
143 143 pub fn generate_git_token() -> (String, String) {
144 144 let mut bytes = [0u8; 32];
145 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut bytes);
145 + rand::Rng::fill_bytes(&mut rand::rng(), &mut bytes);
146 146 let body: String = bytes.iter().map(|b| format!("{b:02x}")).collect();
147 147 let plaintext = format!("mnw_{body}");
148 148 let hash = git_token_hash(&plaintext);
@@ -14,7 +14,7 @@ use axum::{
14 14 routing::{delete, patch, post, put, MethodRouter},
15 15 Router,
16 16 };
17 - use rand::RngCore;
17 + use rand::Rng;
18 18 use std::collections::BTreeMap;
19 19 use std::sync::{LazyLock, Mutex};
20 20 use tower_sessions::Session;
@@ -1,6 +1,6 @@
1 1 //! Invite code generation and redemption queries.
2 2
3 - use rand::Rng;
3 + use rand::RngExt;
4 4 use sqlx::PgPool;
5 5
6 6 use super::models::DbInviteCode;
@@ -107,7 +107,7 @@ fn generate_opaque_token() -> (String, String) {
107 107 use sha2::{Digest, Sha256};
108 108
109 109 let mut token_bytes = [0u8; 32];
110 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut token_bytes);
110 + rand::Rng::fill_bytes(&mut rand::rng(), &mut token_bytes);
111 111 let token = hex::encode(token_bytes);
112 112
113 113 let mut hasher = Sha256::new();
@@ -325,7 +325,7 @@ pub(crate) fn validate_domain(domain: &str) -> Result<()> {
325 325 /// Generate a random verification token.
326 326 fn generate_verification_token() -> String {
327 327 let mut bytes = [0u8; 16];
328 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut bytes);
328 + rand::Rng::fill_bytes(&mut rand::rng(), &mut bytes);
329 329 format!("mnw-verify-{}", hex::encode(bytes))
330 330 }
331 331
@@ -533,7 +533,7 @@ pub(super) async fn remove_domain(
533 533
534 534 fn generate_verification_token() -> String {
535 535 let mut bytes = [0u8; 16];
536 - rand::RngCore::fill_bytes(&mut rand::rng(), &mut bytes);
536 + rand::Rng::fill_bytes(&mut rand::rng(), &mut bytes);
537 537 format!("mnw-verify-{}", hex::encode(bytes))
538 538 }
539 539
@@ -28,7 +28,7 @@ pub(super) async fn setup(
28 28 ) -> Result<Response> {
29 29 user.check_not_sandbox()?;
30 30 // Generate a 20-byte (160-bit) random secret
31 - use rand::Rng;
31 + use rand::RngExt;
32 32 let secret_bytes: Vec<u8> = (0..20).map(|_| rand::rng().random()).collect();
33 33
34 34 let totp = totp_rs::TOTP::new(
@@ -262,7 +262,7 @@ pub(crate) fn build_totp(secret_base32: &str, account_name: &str) -> Result<totp
262 262
263 263 /// Generate random alphanumeric backup codes.
264 264 fn generate_backup_codes() -> Vec<String> {
265 - use rand::Rng;
265 + use rand::RngExt;
266 266 let mut rng = rand::rng();
267 267
268 268 (0..BACKUP_CODE_COUNT)
@@ -12,7 +12,7 @@ use axum::{
12 12 Form, Json,
13 13 };
14 14 use crate::csrf::{post_csrf_manual, post_csrf_skip, CsrfRouter};
15 - use rand::RngCore;
15 + use rand::Rng;
16 16 use serde::{Deserialize, Serialize};
17 17 use sha2::{Digest, Sha256};
18 18 use tower_governor::GovernorLayer;
@@ -6,7 +6,7 @@ use axum::{
6 6 response::{IntoResponse, Redirect, Response},
7 7 routing::get,
8 8 };
9 - use rand::Rng;
9 + use rand::RngExt;
10 10 use sqlx::PgPool;
11 11 use tower_governor::GovernorLayer;
12 12 use tower_sessions::Session;
@@ -19,7 +19,7 @@ use axum::{
19 19 Router,
20 20 };
21 21 use base64::Engine;
22 - use rand::RngCore;
22 + use rand::Rng;
23 23 use serde::Deserialize;
24 24 use sha2::{Digest, Sha256};
25 25 use tower_sessions::Session;
@@ -515,7 +515,7 @@ pub(super) struct AppWithKey {
515 515 // ── Helper ──
516 516
517 517 pub(super) fn generate_api_key() -> String {
518 - use rand::RngCore;
518 + use rand::Rng;
519 519 let mut bytes = [0u8; constants::SYNCKIT_API_KEY_LENGTH];
520 520 rand::rng().fill_bytes(&mut bytes);
521 521 hex::encode(bytes)
@@ -567,18 +567,6 @@ dependencies = [
567 567
568 568 [[package]]
569 569 name = "getrandom"
570 - version = "0.3.4"
571 - source = "registry+https://github.com/rust-lang/crates.io-index"
572 - checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
573 - dependencies = [
574 - "cfg-if",
575 - "libc",
576 - "r-efi",
577 - "wasip2",
578 - ]
579 -
580 - [[package]]
581 - name = "getrandom"
582 570 version = "0.4.1"
583 571 source = "registry+https://github.com/rust-lang/crates.io-index"
584 572 checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
@@ -1307,15 +1295,6 @@ dependencies = [
1307 1295 ]
1308 1296
1309 1297 [[package]]
1310 - name = "ppv-lite86"
1311 - version = "0.2.21"
1312 - source = "registry+https://github.com/rust-lang/crates.io-index"
1313 - checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
1314 - dependencies = [
1315 - "zerocopy",
1316 - ]
1317 -
1318 - [[package]]
1319 1298 name = "prettyplease"
1320 1299 version = "0.2.37"
1321 1300 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1364,7 +1343,7 @@ dependencies = [
1364 1343 "bytes",
1365 1344 "getrandom 0.4.1",
1366 1345 "lru-slab",
1367 - "rand 0.10.2",
1346 + "rand",
1368 1347 "rand_pcg",
1369 1348 "ring",
1370 1349 "rustc-hash",
@@ -1408,16 +1387,6 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
1408 1387
1409 1388 [[package]]
1410 1389 name = "rand"
1411 - version = "0.9.4"
1412 - source = "registry+https://github.com/rust-lang/crates.io-index"
1413 - checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
1414 - dependencies = [
1415 - "rand_chacha",
1416 - "rand_core 0.9.5",
1417 - ]
1418 -
1419 - [[package]]
1420 - name = "rand"
1421 1390 version = "0.10.2"
1422 1391 source = "registry+https://github.com/rust-lang/crates.io-index"
1423 1392 checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
@@ -1428,16 +1397,6 @@ dependencies = [
1428 1397 ]
1429 1398
1430 1399 [[package]]
1431 - name = "rand_chacha"
1432 - version = "0.9.0"
1433 - source = "registry+https://github.com/rust-lang/crates.io-index"
1434 - checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
1435 - dependencies = [
1436 - "ppv-lite86",
1437 - "rand_core 0.9.5",
1438 - ]
1439 -
1440 - [[package]]
1441 1400 name = "rand_core"
1442 1401 version = "0.6.4"
1443 1402 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1448,15 +1407,6 @@ dependencies = [
1448 1407
1449 1408 [[package]]
1450 1409 name = "rand_core"
1451 - version = "0.9.5"
1452 - source = "registry+https://github.com/rust-lang/crates.io-index"
1453 - checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
1454 - dependencies = [
1455 - "getrandom 0.3.4",
1456 - ]
1457 -
1458 - [[package]]
1459 - name = "rand_core"
1460 1410 version = "0.10.1"
1461 1411 source = "registry+https://github.com/rust-lang/crates.io-index"
1462 1412 checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
@@ -1917,7 +1867,7 @@ dependencies = [
1917 1867 "chrono",
1918 1868 "keyring",
1919 1869 "parking_lot",
1920 - "rand 0.9.4",
1870 + "rand",
1921 1871 "reqwest",
1922 1872 "rusqlite",
1923 1873 "serde",
@@ -23,7 +23,7 @@ testing = []
23 23 # Encryption
24 24 chacha20poly1305 = "0.10"
25 25 argon2 = "0.5"
26 - rand = "0.9"
26 + rand = "0.10"
27 27 base64 = "0.22"
28 28 zeroize = "1"
29 29