Skip to content

Commit d5ab698

Browse files
committed
improve signature caching (for tests/benchmarks)
1 parent d7ab759 commit d5ab698

2 files changed

Lines changed: 23 additions & 37 deletions

File tree

.github/workflows/rust.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ jobs:
4545
toolchain: nightly
4646
- name: Cache cargo build
4747
uses: Swatinem/rust-cache@v2
48+
- name: Cache benchmark signers
49+
uses: actions/cache@v4
50+
with:
51+
path: target/signers-cache
52+
key: benchmark-signers-${{ hashFiles('crates/xmss/**', 'crates/utils/**', 'crates/backend/**') }}
4853
- name: Build
4954
run: cargo build --release --all --verbose
5055
env:

crates/xmss/src/signers_cache.rs

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fs;
2+
use std::hash::{DefaultHasher, Hash, Hasher};
23
use std::path::PathBuf;
34
use std::sync::OnceLock;
45
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -26,14 +27,22 @@ pub fn message_for_benchmark() -> [F; MESSAGE_LEN_FE] {
2627

2728
#[derive(Serialize, Deserialize)]
2829
struct SignersCacheFile {
29-
slot: u32,
30-
message: Vec<F>,
3130
signatures: Vec<(XmssPublicKey, XmssSignature)>,
3231
}
3332

34-
fn cache_path() -> PathBuf {
35-
let file = "benchmark_signers_cache.bin";
36-
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(format!("../../target/{file}"))
33+
fn cache_footprint(first_pubkey: &XmssPublicKey) -> u64 {
34+
let mut hasher = DefaultHasher::new();
35+
NUM_BENCHMARK_SIGNERS.hash(&mut hasher);
36+
BENCHMARK_SLOT.hash(&mut hasher);
37+
message_for_benchmark().hash(&mut hasher);
38+
first_pubkey.merkle_root.hash(&mut hasher);
39+
hasher.finish()
40+
}
41+
42+
fn cache_path(first_pubkey: &XmssPublicKey) -> PathBuf {
43+
let footprint = cache_footprint(first_pubkey);
44+
let file = format!("benchmark_signers_cache_{footprint:016x}.bin");
45+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(format!("../../target/signers-cache/{file}"))
3746
}
3847

3948
fn compute_signer(index: usize) -> (XmssPublicKey, XmssSignature) {
@@ -45,45 +54,19 @@ fn compute_signer(index: usize) -> (XmssPublicKey, XmssSignature) {
4554
(pk, sig)
4655
}
4756

48-
fn try_load_cache(path: &PathBuf, first_pubkey: &XmssPublicKey) -> Option<Vec<(XmssPublicKey, XmssSignature)>> {
57+
fn try_load_cache(path: &PathBuf) -> Option<Vec<(XmssPublicKey, XmssSignature)>> {
4958
let data = fs::read(path).ok()?;
5059
let decompressed = lz4_flex::decompress_size_prepended(&data).ok()?;
5160
let cached: SignersCacheFile = postcard::from_bytes(&decompressed).ok()?;
52-
53-
if cached.slot != BENCHMARK_SLOT {
54-
println!(
55-
"Cache slot {} does not match benchmark slot {}, recomputing...",
56-
cached.slot, BENCHMARK_SLOT
57-
);
58-
return None;
59-
}
60-
if cached.message != message_for_benchmark() {
61-
println!("Cache message does not match benchmark message, recomputing...");
62-
return None;
63-
}
64-
if cached.signatures.len() != NUM_BENCHMARK_SIGNERS {
65-
println!(
66-
"Cache contains {} signatures, expected {}, recomputing...",
67-
cached.signatures.len(),
68-
NUM_BENCHMARK_SIGNERS
69-
);
70-
return None;
71-
}
72-
if cached.signatures[0].0 != *first_pubkey {
73-
println!("Cache first public key does not match computed first public key, recomputing...");
74-
return None;
75-
}
76-
7761
Some(cached.signatures)
7862
}
7963

8064
fn gen_benchmark_signers_cache() -> Vec<(XmssPublicKey, XmssSignature)> {
81-
let path = cache_path();
82-
83-
// Compute first signer; its pubkey is used to validate the cache
65+
// Compute first signer; its pubkey feeds into the cache footprint
8466
let first_signer = compute_signer(0);
67+
let path = cache_path(&first_signer.0);
8568

86-
if let Some(signers) = try_load_cache(&path, &first_signer.0) {
69+
if let Some(signers) = try_load_cache(&path) {
8770
return signers;
8871
}
8972

@@ -112,8 +95,6 @@ fn gen_benchmark_signers_cache() -> Vec<(XmssPublicKey, XmssSignature)> {
11295
signers.extend(rest);
11396

11497
let cache_file = SignersCacheFile {
115-
slot: BENCHMARK_SLOT,
116-
message: message_for_benchmark().to_vec(),
11798
signatures: signers.clone(),
11899
};
119100
let encoded = postcard::to_allocvec(&cache_file).expect("serialization failed");

0 commit comments

Comments
 (0)