Skip to content

Commit 619464c

Browse files
authored
Merge pull request #2814 from ProvableHQ/feat/load-inclusion-external-wasm
[Feature] Enable safe external loading of inclusion prover for `wasm` targets
2 parents 96c802a + bb1384f commit 619464c

6 files changed

Lines changed: 181 additions & 1 deletion

File tree

console/network/src/canary_v0.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ impl Network for CanaryV0 {
234234
.ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
235235
}
236236

237+
#[cfg(not(feature = "wasm"))]
237238
/// Returns the `proving key` for the inclusion_v0 circuit.
238239
fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
239240
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
@@ -246,6 +247,28 @@ impl Network for CanaryV0 {
246247
})
247248
}
248249

250+
#[cfg(feature = "wasm")]
251+
/// Returns the `proving key` for the inclusion_v0 circuit.
252+
fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
253+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
254+
INSTANCE.get_or_init(|| {
255+
inclusion_key_bytes
256+
.map(|bytes| {
257+
snarkvm_parameters::canary::InclusionV0Prover::verify_bytes(&bytes)
258+
.expect("Bytes provided did not match expected inclusion checksum.");
259+
Arc::new(
260+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
261+
)
262+
})
263+
.unwrap_or_else(|| {
264+
Arc::new(
265+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_V0_PROVING_KEY[1..])
266+
.expect("Failed to load inclusion proving key."),
267+
)
268+
})
269+
})
270+
}
271+
249272
/// Returns the `verifying key` for the inclusion_v0 circuit.
250273
fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
251274
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
@@ -258,6 +281,7 @@ impl Network for CanaryV0 {
258281
})
259282
}
260283

284+
#[cfg(not(feature = "wasm"))]
261285
/// Returns the `proving key` for the inclusion circuit.
262286
fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
263287
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
@@ -270,6 +294,28 @@ impl Network for CanaryV0 {
270294
})
271295
}
272296

297+
#[cfg(feature = "wasm")]
298+
/// Returns the `proving key` for the inclusion circuit.
299+
fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
300+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
301+
INSTANCE.get_or_init(|| {
302+
inclusion_key_bytes
303+
.map(|bytes| {
304+
snarkvm_parameters::canary::InclusionProver::verify_bytes(&bytes)
305+
.expect("Bytes provided did not match expected inclusion checksum.");
306+
Arc::new(
307+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
308+
)
309+
})
310+
.unwrap_or_else(|| {
311+
Arc::new(
312+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_PROVING_KEY[1..])
313+
.expect("Failed to load inclusion proving key."),
314+
)
315+
})
316+
})
317+
}
318+
273319
/// Returns the `verifying key` for the inclusion circuit.
274320
fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
275321
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();

console/network/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,24 @@ pub trait Network:
314314
/// Returns the verifying key for the given function name in `credits.aleo`.
315315
fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>>;
316316

317+
#[cfg(not(feature = "wasm"))]
317318
/// Returns the `proving key` for the inclusion_v0 circuit.
318319
fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
319320

321+
#[cfg(feature = "wasm")]
322+
/// Returns the `proving key` for the inclusion_v0 circuit.
323+
fn inclusion_v0_proving_key(bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>>;
324+
320325
/// Returns the `verifying key` for the inclusion_v0 circuit.
321326
fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
322327

328+
#[cfg(not(feature = "wasm"))]
323329
/// Returns the `proving key` for the inclusion circuit.
324330
fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
325331

332+
#[cfg(feature = "wasm")]
333+
fn inclusion_proving_key(bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>>;
334+
326335
/// Returns the `verifying key` for the inclusion circuit.
327336
fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
328337

console/network/src/mainnet_v0.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ impl Network for MainnetV0 {
239239
.ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
240240
}
241241

242+
#[cfg(not(feature = "wasm"))]
242243
/// Returns the `proving key` for the inclusion_v0 circuit.
243244
fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
244245
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
@@ -251,6 +252,28 @@ impl Network for MainnetV0 {
251252
})
252253
}
253254

255+
#[cfg(feature = "wasm")]
256+
/// Returns the `proving key` for the inclusion_v0 circuit.
257+
fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
258+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
259+
INSTANCE.get_or_init(|| {
260+
inclusion_key_bytes
261+
.map(|bytes| {
262+
snarkvm_parameters::mainnet::InclusionV0Prover::verify_bytes(&bytes)
263+
.expect("Bytes provided did not match expected inclusion checksum.");
264+
Arc::new(
265+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
266+
)
267+
})
268+
.unwrap_or_else(|| {
269+
Arc::new(
270+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_PROVING_KEY[1..])
271+
.expect("Failed to load inclusion proving key."),
272+
)
273+
})
274+
})
275+
}
276+
254277
/// Returns the `verifying key` for the inclusion_v0 circuit.
255278
fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
256279
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
@@ -263,6 +286,7 @@ impl Network for MainnetV0 {
263286
})
264287
}
265288

289+
#[cfg(not(feature = "wasm"))]
266290
/// Returns the `proving key` for the inclusion circuit.
267291
fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
268292
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
@@ -275,6 +299,28 @@ impl Network for MainnetV0 {
275299
})
276300
}
277301

302+
#[cfg(feature = "wasm")]
303+
/// Returns the `proving key` for the inclusion circuit.
304+
fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
305+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
306+
INSTANCE.get_or_init(|| {
307+
inclusion_key_bytes
308+
.map(|bytes| {
309+
snarkvm_parameters::mainnet::InclusionProver::verify_bytes(&bytes)
310+
.expect("Bytes provided did not match expected inclusion checksum.");
311+
Arc::new(
312+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
313+
)
314+
})
315+
.unwrap_or_else(|| {
316+
Arc::new(
317+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
318+
.expect("Failed to load inclusion proving key."),
319+
)
320+
})
321+
})
322+
}
323+
278324
/// Returns the `verifying key` for the inclusion circuit.
279325
fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
280326
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();

console/network/src/testnet_v0.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ impl Network for TestnetV0 {
234234
.ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
235235
}
236236

237-
/// Returns the `proving key` for the inclusion circuit.
237+
#[cfg(not(feature = "wasm"))]
238+
/// Returns the `proving key` for the inclusion_v0 circuit.
238239
fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
239240
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
240241
INSTANCE.get_or_init(|| {
@@ -246,6 +247,28 @@ impl Network for TestnetV0 {
246247
})
247248
}
248249

250+
#[cfg(feature = "wasm")]
251+
/// Returns the `proving key` for the inclusion_v0 circuit.
252+
fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
253+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
254+
INSTANCE.get_or_init(|| {
255+
inclusion_key_bytes
256+
.map(|bytes| {
257+
snarkvm_parameters::testnet::InclusionV0Prover::verify_bytes(&bytes)
258+
.expect("Bytes provided did not match expected inclusion checksum.");
259+
Arc::new(
260+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
261+
)
262+
})
263+
.unwrap_or_else(|| {
264+
Arc::new(
265+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_V0_PROVING_KEY[1..])
266+
.expect("Failed to load inclusion proving key."),
267+
)
268+
})
269+
})
270+
}
271+
249272
/// Returns the `verifying key` for the inclusion circuit.
250273
fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
251274
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
@@ -258,6 +281,7 @@ impl Network for TestnetV0 {
258281
})
259282
}
260283

284+
#[cfg(not(feature = "wasm"))]
261285
/// Returns the `proving key` for the inclusion circuit.
262286
fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
263287
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
@@ -270,6 +294,28 @@ impl Network for TestnetV0 {
270294
})
271295
}
272296

297+
#[cfg(feature = "wasm")]
298+
/// Returns the `proving key` for the inclusion circuit.
299+
fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
300+
static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
301+
INSTANCE.get_or_init(|| {
302+
inclusion_key_bytes
303+
.map(|bytes| {
304+
snarkvm_parameters::testnet::InclusionProver::verify_bytes(&bytes)
305+
.expect("Bytes provided did not match expected inclusion checksum.");
306+
Arc::new(
307+
CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
308+
)
309+
})
310+
.unwrap_or_else(|| {
311+
Arc::new(
312+
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_PROVING_KEY[1..])
313+
.expect("Failed to load inclusion proving key."),
314+
)
315+
})
316+
})
317+
}
318+
273319
/// Returns the `verifying key` for the inclusion circuit.
274320
fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
275321
static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();

parameters/src/macros.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,28 @@ macro_rules! impl_remote {
372372

373373
impl_load_bytes_logic_remote!($remote_url, $local_dir, &filename, metadata, expected_checksum, expected_size);
374374
}
375+
376+
#[cfg(feature = "wasm")]
377+
/// Verify external bytes.
378+
pub fn verify_bytes(buffer: &[u8]) -> Result<(), $crate::errors::ParameterError> {
379+
let metadata: serde_json::Value = serde_json::from_str(Self::METADATA).expect("Metadata was not well-formatted");
380+
let expected_checksum: String =
381+
metadata[concat!($ftype, "_checksum")].as_str().expect("Failed to parse checksum").to_string();
382+
let expected_size: usize =
383+
metadata[concat!($ftype, "_size")].to_string().parse().expect("Failed to retrieve the file size");
384+
385+
// Ensure the size matches.
386+
if buffer.len() != expected_size {
387+
return Err($crate::errors::ParameterError::SizeMismatch(expected_size, buffer.len()));
388+
}
389+
390+
// Ensure the checksum matches.
391+
let candidate_checksum = checksum!(buffer);
392+
if expected_checksum != candidate_checksum {
393+
return checksum_error!(expected_checksum, candidate_checksum);
394+
}
395+
Ok(())
396+
}
375397
}
376398

377399
paste::item! {

synthesizer/process/src/trace/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,22 @@ impl<N: Network> Trace<N> {
340340

341341
if !batch_inclusions.is_empty() {
342342
// Fetch the inclusion proving key.
343+
#[cfg(not(feature = "wasm"))]
343344
let proving_key = match inclusion_version {
344345
Some(InclusionAssignmentWrapper::V0(..)) => ProvingKey::<N>::new(N::inclusion_v0_proving_key().clone()),
345346
Some(InclusionAssignmentWrapper::V1(..)) => ProvingKey::<N>::new(N::inclusion_proving_key().clone()),
346347
None => bail!("Invalid or missing inclusion version"),
347348
};
349+
#[cfg(feature = "wasm")]
350+
let proving_key = match inclusion_version {
351+
Some(InclusionAssignmentWrapper::V0(..)) => {
352+
ProvingKey::<N>::new(N::inclusion_v0_proving_key(None).clone())
353+
}
354+
Some(InclusionAssignmentWrapper::V1(..)) => {
355+
ProvingKey::<N>::new(N::inclusion_proving_key(None).clone())
356+
}
357+
None => bail!("Invalid or missing inclusion version"),
358+
};
348359
// Insert the inclusion proving key and assignments.
349360
proving_tasks.push((proving_key, batch_inclusions));
350361
}

0 commit comments

Comments
 (0)