Skip to content

Commit 3b40bd8

Browse files
feat(toolchain): support getrandom v0.2 and v0.3 simultaneously (#1795)
With the v1.3.0-rc release, we moved to supporting `getrandom v0.3`. However some libraries like `ecdsa` still use `getrandom v0.2` and it would give the unsupported backend error. Turns out it is possible to support both simultaneously. Closes INT-4187
1 parent 93cd469 commit 3b40bd8

File tree

7 files changed

+70
-6
lines changed

7 files changed

+70
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/toolchain/openvm/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ bytemuck = { workspace = true, features = ["extern_crate_alloc"] }
1717

1818
[target.'cfg(target_os = "zkvm")'.dependencies]
1919
getrandom = { version = "0.3", optional = true }
20+
getrandom-v02 = { version = "0.2", package = "getrandom", features = [
21+
"custom",
22+
], optional = true }
2023

2124
[target.'cfg(not(target_os = "zkvm"))'.dependencies]
2225
num-bigint.workspace = true
@@ -27,7 +30,7 @@ chrono = { version = "0.4", default-features = false, features = ["serde"] }
2730
[features]
2831
default = ["getrandom-unsupported"]
2932
# Defines a custom getrandom backend that always errors. This feature should be enabled if you are sure getrandom is never used but it is pulled in as a compilation dependency.
30-
getrandom-unsupported = ["dep:getrandom"]
33+
getrandom-unsupported = ["dep:getrandom", "dep:getrandom-v02"]
3134
# The zkVM uses a bump-pointer heap allocator by default which does not free
3235
# memory. This will use a slower linked-list heap allocator to reclaim memory.
3336
heap-embedded-alloc = ["openvm-platform/heap-embedded-alloc"]

crates/toolchain/openvm/src/getrandom.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ unsafe extern "Rust" fn __getrandom_v03_custom(
1212
) -> Result<(), getrandom::Error> {
1313
Err(getrandom::Error::UNSUPPORTED)
1414
}
15+
16+
#[cfg(feature = "getrandom-unsupported")]
17+
pub fn __getrandom_v02_custom(_dest: &mut [u8]) -> Result<(), getrandom_v02::Error> {
18+
Err(getrandom_v02::Error::UNSUPPORTED)
19+
}
20+
// https://docs.rs/getrandom/0.2.16/src/getrandom/custom.rs.html#74
21+
#[cfg(feature = "getrandom-unsupported")]
22+
getrandom_v02::register_custom_getrandom!(__getrandom_v02_custom);

extensions/rv32im/tests/programs/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ serde = { version = "1.0", default-features = false, features = [
1414
"derive",
1515
] }
1616
getrandom = { version = "0.3", optional = true }
17+
getrandom-v02 = { version = "0.2", package = "getrandom", optional = true }
1718

1819
[features]
1920
default = []
2021
std = ["serde/std", "openvm/std"]
2122
heap-embedded-alloc = ["openvm/heap-embedded-alloc"]
2223
getrandom-unsupported = ["openvm/getrandom-unsupported"]
23-
getrandom = ["dep:getrandom"]
2424

2525
[profile.release]
2626
panic = "abort"
@@ -30,3 +30,7 @@ lto = "thin" # turn on lto = fat to decrease binary size, but this optimizes
3030
[[example]]
3131
name = "getrandom"
3232
required-features = ["getrandom"]
33+
34+
[[example]]
35+
name = "getrandom_v02"
36+
required-features = ["getrandom-v02"]

extensions/rv32im/tests/programs/examples/getrandom.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#![cfg_attr(not(feature = "std"), no_main)]
22
#![cfg_attr(not(feature = "std"), no_std)]
3+
#[cfg(feature = "getrandom-v02")]
4+
compile_error!("this program is not compatible with getrandom v0.2");
5+
36
use getrandom::Error;
47

58
fn get_random_u128() -> Result<u128, Error> {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#![cfg_attr(not(feature = "std"), no_main)]
2+
#![cfg_attr(not(feature = "std"), no_std)]
3+
#[cfg(feature = "getrandom")]
4+
compile_error!("this program is not compatible with getrandom v0.2");
5+
use getrandom_v02::Error;
6+
// For this to work, need to enable the "custom" feature in getrandom-v02
7+
#[cfg(all(feature = "getrandom-v02", not(feature = "getrandom-unsupported")))]
8+
getrandom_v02::register_custom_getrandom!(__getrandom_v02_custom);
9+
10+
fn get_random_u128() -> Result<u128, Error> {
11+
let mut buf = [0u8; 16];
12+
getrandom_v02::getrandom(&mut buf)?;
13+
Ok(u128::from_ne_bytes(buf))
14+
}
15+
16+
openvm::entry!(main);
17+
18+
pub fn main() {
19+
// do unrelated stuff
20+
let mut c = core::hint::black_box(0);
21+
for _ in 0..10 {
22+
c += 1;
23+
}
24+
25+
#[cfg(not(feature = "getrandom-unsupported"))]
26+
{
27+
// not a good random function!
28+
assert_eq!(get_random_u128(), Ok(0));
29+
}
30+
#[cfg(feature = "getrandom-unsupported")]
31+
{
32+
assert!(get_random_u128().is_err());
33+
}
34+
}
35+
36+
// custom user-specified getrandom
37+
#[cfg(all(feature = "getrandom-v02", not(feature = "getrandom-unsupported")))]
38+
pub fn __getrandom_v02_custom(dest: &mut [u8]) -> Result<(), Error> {
39+
for byte in dest {
40+
*byte = 0u8;
41+
}
42+
Ok(())
43+
}

extensions/rv32im/tests/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,15 @@ mod tests {
276276
executor.execute(exe, vec![]).unwrap();
277277
}
278278

279-
#[test_case(vec!["getrandom", "getrandom-unsupported"])]
280-
#[test_case(vec!["getrandom"])]
281-
fn test_getrandom_unsupported(features: Vec<&str>) {
279+
#[test_case("getrandom", vec!["getrandom", "getrandom-unsupported"])]
280+
#[test_case("getrandom", vec!["getrandom"])]
281+
#[test_case("getrandom_v02", vec!["getrandom-v02", "getrandom-unsupported"])]
282+
#[test_case("getrandom_v02", vec!["getrandom-v02/custom"])]
283+
fn test_getrandom_unsupported(program: &str, features: Vec<&str>) {
282284
let config = Rv32ImConfig::default();
283285
let elf = build_example_program_at_path_with_features(
284286
get_programs_dir!(),
285-
"getrandom",
287+
program,
286288
&features,
287289
&config,
288290
)

0 commit comments

Comments
 (0)