Summary
The security-critical primitives are tested almost exclusively on happy paths:
pluto_crypto (blst_impl.rs, types.rs)
- The threshold property itself is never negatively tested: every recovery test uses ≥ threshold shares, so recovery from fewer shares yielding a wrong secret is unasserted. All recovery subsets also come from
HashMap iteration (nondeterministic) — pin a non-contiguous {2,4,5}-style subset and a descending-order case for compute_lagrange_coefficients; IndicesNotUnique is unasserted too.
- Empty-input guards unasserted:
SharesAreEmpty (recover_secret), EmptySignatureArray (threshold_aggregate), EmptyPublicKeyArray (verify_aggregate).
- Malformed-byte branches of
verify/threshold_aggregate/verify_aggregate untested (only semantic-mismatch cases exist); types.rs has no test module at all, so the From<BLST_ERROR> mapping and the newer variants (ThresholdOverflow, PolynomialIsEmpty, IndicesSharesMismatch, DivisionByZero) are unasserted.
generate_insecure_secret's only test asserts len == 32: no same-seed reproducibility, no seeded expected-output vector (several call sites seed it: test_cluster.rs, dkg tests), and no retry-exhaustion test (an adversarial RngCore emitting all-0xff drives the 100-iteration loop to InvalidSecretKey).
pluto_frost (curve.rs, kryptology.rs)
- No value-based tests for
Scalar Add/Sub or any G1Projective Add/Sub/Mul; from_bytes_wide modular reduction with an out-of-range 64-byte input untested; no not-in-G1 subgroup rejection for a well-encoded off-subgroup point; from_commitments never gets a mixed valid/invalid vector.
pluto-k1util
- No
Ok(false) assertion for verify_65/verify_64 — an always-true bug would pass the suite.
recover/verify_64/sign length-error branches untested; the 27/28 normalization is asserted only as is_ok() without pinning that 27→0/28→1 recover the same key; public_key_from_libp2p's non-secp256k1 error path unasserted.
Ordering
#602 free-function refactor churns every crypto call site — land this backfill either before it (pinning behavior through the refactor) or immediately after; #635 benches can share the fixtures.
Summary
The security-critical primitives are tested almost exclusively on happy paths:
pluto_crypto(blst_impl.rs,types.rs)HashMapiteration (nondeterministic) — pin a non-contiguous{2,4,5}-style subset and a descending-order case forcompute_lagrange_coefficients;IndicesNotUniqueis unasserted too.SharesAreEmpty(recover_secret),EmptySignatureArray(threshold_aggregate),EmptyPublicKeyArray(verify_aggregate).verify/threshold_aggregate/verify_aggregateuntested (only semantic-mismatch cases exist);types.rshas no test module at all, so theFrom<BLST_ERROR>mapping and the newer variants (ThresholdOverflow,PolynomialIsEmpty,IndicesSharesMismatch,DivisionByZero) are unasserted.generate_insecure_secret's only test assertslen == 32: no same-seed reproducibility, no seeded expected-output vector (several call sites seed it:test_cluster.rs, dkg tests), and no retry-exhaustion test (an adversarialRngCoreemitting all-0xffdrives the 100-iteration loop toInvalidSecretKey).pluto_frost(curve.rs,kryptology.rs)ScalarAdd/Subor anyG1ProjectiveAdd/Sub/Mul;from_bytes_widemodular reduction with an out-of-range 64-byte input untested; no not-in-G1 subgroup rejection for a well-encoded off-subgroup point;from_commitmentsnever gets a mixed valid/invalid vector.pluto-k1utilOk(false)assertion forverify_65/verify_64— an always-true bug would pass the suite.recover/verify_64/signlength-error branches untested; the 27/28 normalization is asserted only asis_ok()without pinning that 27→0/28→1 recover the same key;public_key_from_libp2p's non-secp256k1 error path unasserted.Ordering
#602 free-function refactor churns every crypto call site — land this backfill either before it (pinning behavior through the refactor) or immediately after; #635 benches can share the fixtures.