Skip to content

WOTS+ chains recomputed on every sign + missing slot range validation #37

@jiayaoqijia

Description

@jiayaoqijia

Summary

xmss_sign regenerates the WOTS secret key from seed on every call, recomputing all WOTS+ chains (294 extra Poseidon hashes per signature). Additionally, xmss_key_gen does not validate that slot_end < 2^LOG_LIFETIME.

Severity

MEDIUM -- Performance and validation gap.

Location

WOTS+ chain recomputation:

  • crates/xmss/src/wots.rs:32-37 -- WotsSecretKey::new computes iterate_hash(&pre_images[i], CHAIN_LENGTH - 1) for all V chains
  • crates/xmss/src/xmss.rs:142-145 -- xmss_sign regenerates the WOTS secret key from seed on every call

Missing slot validation:

  • crates/xmss/src/xmss.rs:53-60 -- xmss_key_gen checks slot_start > slot_end but not slot_end < 2^LOG_LIFETIME

Impact

Performance: Signing latency includes 294 unnecessary Poseidon hash invocations per operation (V=42 chains of length CHAIN_LENGTH=8, so 42 * 7 = 294). Acceptable for single-slot signing but becomes a bottleneck in batch signing scenarios.

Validation: With LOG_LIFETIME=32 and u32 slots, the range is naturally bounded by the type. However, if LOG_LIFETIME were reduced for testing or alternative configurations, slots could exceed tree capacity silently.

Suggested Fix

WOTS+ caching: Cache WOTS secret keys in the XmssSecretKey struct:

pub struct XmssSecretKey {
    // ... existing fields ...
    wots_cache: HashMap<u32, WotsSecretKey>,
}

Slot validation: Add explicit range check:

if slot_end >= (1u64 << LOG_LIFETIME) as u32 {
    return Err(...);
}

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions