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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions