Skip to content

[API Hardening] Complete NULL checks at every public wrapper, including array elements #111

Description

@tesseract-ripple

Severity: Informational; defensive.
Source: TOB May 2026 revision, Appendix D — "Null pointer
arguments" (pp. 62-63).

Problem

Public C/C++ wrappers in mpt-crypto sometimes pass caller-supplied
pointers to libsecp256k1, OpenSSL, memcpy, or local serializers
without complete NULL checks. The check is sometimes done on the
outer array pointer but not on each element. TOB calls out concrete
examples (line numbers from the report; current line numbers may
differ but the pattern is the issue):

  • mpt_make_ec_pair (mpt_utility.cpp:L247): null buffer not
    rejected before parsing.
  • mpt_generate_keypair (mpt_utility.cpp:L373/L377): null
    out_privkey / out_pubkey not rejected before ElGamal keygen
    and serialization.
  • The four mpt_get_*_context_hash helpers all return through
    sha512_half without first validating the output buffer.
  • mpt_verify_aggregated_bulletproof (mpt_utility.cpp:L865)
    checks the outer compressed_commitments pointer but should
    also validate every compressed_commitments[i] element before
    parsing.
  • secp256k1_bulletproof_create_commitment
    (mpt_utility.cpp:L1090) should reject null ctx,
    commitment_C, blinding_factor, and pk_base before any
    dereference.
  • secp256k1_bulletproof_prove_agg (mpt_utility.cpp:L1212)
    should reject null ctx, proof_out, proof_len, values,
    blindings_flat, and pk_base before computing sizes or
    writing *proof_len.
  • The exported scalar helpers (secp256k1_mpt_scalar_add,
    mul, inverse, negate, reduce32) should either reject
    null inputs or be moved out of the public API.
  • secp256k1_mpt_hash_to_point_nums: either make static or
    validate ctx and out before parsing.

Recommended change

  1. Every public wrapper performs full NULL validation before any
    dereference, including:
    • All scalar pointers
    • All pubkey pointers
    • Every element of any array of pointers (e.g.,
      compressed_commitments[i] not just compressed_commitments).
  2. Each public API gets a negative test that passes NULL for
    each nullable position and asserts the documented failure code.
  3. Internal helpers that escape to the public ABI should either
    move to internal headers (see [API Hardening] Decide and document zero / point-at-infinity handling at every API boundary #112 [exported surface]) or
    validate their own contracts.

Acceptance

  • Every public API in include/utility/mpt_utility.h and in
    include/secp256k1_mpt.h has matching NULL-input negative tests
    for each pointer parameter.
  • Array-element NULL checks land specifically for the
    bulletproof compressed_commitments[i] and any analogous
    array-of-pointers parameters.
  • The scalar helpers either move to mpt_internal.h (preferred)
    or gain explicit NULL guards plus negative tests.

References

  • TOB May 2026 Appendix D, pp. 62-63 (full call-site list).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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