Skip to content

Commit 563ede1

Browse files
authored
fix: add hook for ed decompress (#1829)
1 parent a2402fb commit 563ede1

File tree

13 files changed

+154
-97
lines changed

13 files changed

+154
-97
lines changed

Cargo.lock

+24-57
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace.package]
2-
version = "3.3.0"
2+
version = "3.4.0"
33
edition = "2021"
44
license = "MIT OR Apache-2.0"
55
repository = "https://github.com/succinctlabs/sp1"
@@ -47,26 +47,26 @@ debug-assertions = true
4747

4848
[workspace.dependencies]
4949
# sp1
50-
sp1-build = { path = "crates/build", version = "3.3.0" }
51-
sp1-cli = { path = "crates/cli", version = "3.3.0", default-features = false }
52-
sp1-core-machine = { path = "crates/core/machine", version = "3.3.0" }
53-
sp1-core-executor = { path = "crates/core/executor", version = "3.3.0" }
54-
sp1-curves = { path = "crates/curves", version = "3.3.0" }
55-
sp1-derive = { path = "crates/derive", version = "3.3.0" }
56-
sp1-eval = { path = "crates/eval", version = "3.3.0" }
57-
sp1-helper = { path = "crates/helper", version = "3.3.0", default-features = false }
58-
sp1-primitives = { path = "crates/primitives", version = "3.3.0" }
59-
sp1-prover = { path = "crates/prover", version = "3.3.0" }
60-
sp1-recursion-compiler = { path = "crates/recursion/compiler", version = "3.3.0" }
61-
sp1-recursion-core = { path = "crates/recursion/core", version = "3.3.0", default-features = false }
62-
sp1-recursion-derive = { path = "crates/recursion/derive", version = "3.3.0", default-features = false }
63-
sp1-recursion-gnark-ffi = { path = "crates/recursion/gnark-ffi", version = "3.3.0", default-features = false }
64-
sp1-recursion-circuit = { path = "crates/recursion/circuit", version = "3.3.0", default-features = false }
65-
sp1-sdk = { path = "crates/sdk", version = "3.3.0" }
66-
sp1-cuda = { path = "crates/cuda", version = "3.3.0" }
67-
sp1-stark = { path = "crates/stark", version = "3.3.0" }
68-
sp1-lib = { path = "crates/zkvm/lib", version = "3.3.0", default-features = false }
69-
sp1-zkvm = { path = "crates/zkvm/entrypoint", version = "3.3.0", default-features = false }
50+
sp1-build = { path = "crates/build", version = "3.4.0" }
51+
sp1-cli = { path = "crates/cli", version = "3.4.0", default-features = false }
52+
sp1-core-machine = { path = "crates/core/machine", version = "3.4.0" }
53+
sp1-core-executor = { path = "crates/core/executor", version = "3.4.0" }
54+
sp1-curves = { path = "crates/curves", version = "3.4.0" }
55+
sp1-derive = { path = "crates/derive", version = "3.4.0" }
56+
sp1-eval = { path = "crates/eval", version = "3.4.0" }
57+
sp1-helper = { path = "crates/helper", version = "3.4.0", default-features = false }
58+
sp1-primitives = { path = "crates/primitives", version = "3.4.0" }
59+
sp1-prover = { path = "crates/prover", version = "3.4.0" }
60+
sp1-recursion-compiler = { path = "crates/recursion/compiler", version = "3.4.0" }
61+
sp1-recursion-core = { path = "crates/recursion/core", version = "3.4.0", default-features = false }
62+
sp1-recursion-derive = { path = "crates/recursion/derive", version = "3.4.0", default-features = false }
63+
sp1-recursion-gnark-ffi = { path = "crates/recursion/gnark-ffi", version = "3.4.0", default-features = false }
64+
sp1-recursion-circuit = { path = "crates/recursion/circuit", version = "3.4.0", default-features = false }
65+
sp1-sdk = { path = "crates/sdk", version = "3.4.0" }
66+
sp1-cuda = { path = "crates/cuda", version = "3.4.0" }
67+
sp1-stark = { path = "crates/stark", version = "3.4.0" }
68+
sp1-lib = { path = "crates/zkvm/lib", version = "3.4.0", default-features = false }
69+
sp1-zkvm = { path = "crates/zkvm/entrypoint", version = "3.4.0", default-features = false }
7070

7171
# p3
7272
p3-air = "0.1.4-succinct"

book/writing-programs/patched-crates.md

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ sha3-v0-10-6 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", packa
3636
sha3-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha3", tag = "sha3-v0.10.8-patch-v1" }
3737
crypto-bigint = { git = "https://github.com/sp1-patches/RustCrypto-bigint", tag = "crypto_bigint-v0.5.5-patch-v1" }
3838
tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "tiny_keccak-v2.0.2-patch-v1" }
39+
# For sp1 versions >= 3.4.0
40+
curve25519-dalek = { git = "https://github.com/sp1-patches/curve25519-dalek", tag = "patch-v4.1.3-v3.4.0" }
41+
# For sp1 versions < 3.4.0
3942
curve25519-dalek = { git = "https://github.com/sp1-patches/curve25519-dalek", tag = "curve25519_dalek-v4.1.3-patch-v1" }
4043
curve25519-dalek-ng = { git = "https://github.com/sp1-patches/curve25519-dalek-ng", tag = "curve25519_dalek_ng-v4.1.1-patch-v1" }
4144
ed25519-consensus = { git = "https://github.com/sp1-patches/ed25519-consensus", tag = "ed25519_consensus-v2.1.0-patch-v1" }

crates/core/executor/src/hook.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ pub const FD_ECRECOVER_HOOK: u32 = 5;
1818
/// The file descriptor through which to access `hook_ecrecover_2`.
1919
pub const FD_ECRECOVER_HOOK_2: u32 = 7;
2020

21+
/// The file descriptor through which to access `hook_ed_decompress`.
22+
pub const FD_EDDECOMPRESS: u32 = 8;
23+
2124
/// A runtime hook. May be called during execution by writing to a specified file descriptor,
2225
/// accepting and returning arbitrary data.
2326
pub trait Hook {
@@ -82,6 +85,7 @@ impl<'a> Default for HookRegistry<'a> {
8285
// add an assertion to the test `hook_fds_match` below.
8386
(FD_ECRECOVER_HOOK, hookify(hook_ecrecover)),
8487
(FD_ECRECOVER_HOOK_2, hookify(hook_ecrecover_v2)),
88+
(FD_EDDECOMPRESS, hookify(hook_ed_decompress)),
8589
]);
8690

8791
Self { table }
@@ -179,8 +183,9 @@ pub fn hook_ecrecover_v2(_: HookEnv, buf: &[u8]) -> Vec<Vec<u8>> {
179183
sig = sig_normalized;
180184
recovery_id ^= 1;
181185
};
182-
let recid = RecoveryId::from_byte(recovery_id).expect("Computed recovery ID is invalid, this is a bug.");
183-
186+
let recid = RecoveryId::from_byte(recovery_id)
187+
.expect("Computed recovery ID is invalid, this is a bug.");
188+
184189
// Attempting to recvover the public key has failed, write a 0 to indicate to the caller.
185190
let Ok(recovered_key) = VerifyingKey::recover_from_prehash(&msg_hash[..], &sig, recid) else {
186191
return vec![vec![0]];
@@ -194,6 +199,31 @@ pub fn hook_ecrecover_v2(_: HookEnv, buf: &[u8]) -> Vec<Vec<u8>> {
194199
vec![vec![1], bytes.to_vec(), s_inverse.to_bytes().to_vec()]
195200
}
196201

202+
/// Checks if a compressed Edwards point can be decompressed.
203+
///
204+
/// # Arguments
205+
/// * `env` - The environment in which the hook is invoked.
206+
/// * `buf` - The buffer containing the compressed Edwards point.
207+
/// - The compressed Edwards point is 32 bytes.
208+
/// - The high bit of the last byte is the sign bit.
209+
///
210+
/// The result is either `0` if the point cannot be decompressed, or `1` if it can.
211+
///
212+
/// WARNING: This function merely hints at the validity of the compressed point. These values must
213+
/// be constrained by the zkVM for correctness.
214+
#[must_use]
215+
pub fn hook_ed_decompress(_: HookEnv, buf: &[u8]) -> Vec<Vec<u8>> {
216+
let Ok(point) = sp1_curves::curve25519_dalek::CompressedEdwardsY::from_slice(buf) else {
217+
return vec![vec![0]];
218+
};
219+
220+
if sp1_curves::edwards::ed25519::decompress(&point).is_some() {
221+
vec![vec![1]]
222+
} else {
223+
vec![vec![0]]
224+
}
225+
}
226+
197227
#[cfg(test)]
198228
pub mod tests {
199229
use super::*;

0 commit comments

Comments
 (0)