Severity: Performance; low priority but well-scoped.
Source: Performance posture report (internal draft,
2026-06-08), Recommendation #2.
Problem
secp256k1_mpt_get_generator_vector accounts for ~4% of CPU
during the dominant ConfidentialMPTSend::preclaim path on
the 5-TPS ConfidentialSendOnly workload, per the recent eBPF
profile. The generator vectors G_vec and H_vec are
deterministically derived via HKDF from a label and the
issuance parameters; they are constant for the lifetime of
an issuance (or, since the labels are "BP_G" / "BP_H",
constant for the lifetime of the protocol — they don't even
depend on issuance state).
Currently rippled recomputes them per verify_agg call,
which is once per ConfidentialMPTSend validated.
Recommended fix
Cache the vector on the rippled side. Two reasonable scopes:
-
Per-process cache (cleanest). Compute once at startup
(or first use); reuse for the lifetime of the rippled
process. Since G_vec/H_vec are protocol-constant (HKDF
label "BP_G" / "BP_H", fixed N=64×max_m), a single
process-wide cache suffices.
-
Per-issuance cache (more general). If the
instantiation ever becomes issuance-specific, switch to
a map keyed by issuance ID.
Option 1 is enough for the current protocol; option 2 is the
fallback if the API evolves.
Scope
This is a rippled-side change (caller-side caching). The
mpt-crypto API itself doesn't need to change; the function
can stay pure and the caller manages the cache.
Alternative (mpt-crypto side): add a *_cached variant
of the wrapper that memoizes internally with a thread-safe
cache. Probably overkill — the rippled caller is in a much
better position to manage cache lifetime.
Expected impact
~4% of CPU saved per verifySendProofs call. Modest on its
own, additive on top of the MSM-track speedup from #104 /
#105.
References
Severity: Performance; low priority but well-scoped.
Source: Performance posture report (internal draft,
2026-06-08), Recommendation #2.
Problem
secp256k1_mpt_get_generator_vectoraccounts for ~4% of CPUduring the dominant
ConfidentialMPTSend::preclaimpath onthe 5-TPS ConfidentialSendOnly workload, per the recent eBPF
profile. The generator vectors
G_vecandH_vecaredeterministically derived via HKDF from a label and the
issuance parameters; they are constant for the lifetime of
an issuance (or, since the labels are
"BP_G"/"BP_H",constant for the lifetime of the protocol — they don't even
depend on issuance state).
Currently
rippledrecomputes them perverify_aggcall,which is once per
ConfidentialMPTSendvalidated.Recommended fix
Cache the vector on the rippled side. Two reasonable scopes:
Per-process cache (cleanest). Compute once at startup
(or first use); reuse for the lifetime of the rippled
process. Since
G_vec/H_vecare protocol-constant (HKDFlabel
"BP_G"/"BP_H", fixed N=64×max_m), a singleprocess-wide cache suffices.
Per-issuance cache (more general). If the
instantiation ever becomes issuance-specific, switch to
a map keyed by issuance ID.
Option 1 is enough for the current protocol; option 2 is the
fallback if the API evolves.
Scope
This is a rippled-side change (caller-side caching). The
mpt-crypto API itself doesn't need to change; the function
can stay pure and the caller manages the cache.
Alternative (mpt-crypto side): add a
*_cachedvariantof the wrapper that memoizes internally with a thread-safe
cache. Probably overkill — the rippled caller is in a much
better position to manage cache lifetime.
Expected impact
~4% of CPU saved per
verifySendProofscall. Modest on itsown, additive on top of the MSM-track speedup from #104 /
#105.
References
Recommendation Enhance scalar security, update docs, and add IPA unit test #2.
mpt_verify_aggregated_bulletproof≈ 76% ofCPU at 5 TPS, with
secp256k1_mpt_get_generator_vector≈ 4% of that.