Skip to content

Feature/core enhancements#17

Open
digitsu wants to merge 11 commits into
libitx:masterfrom
digitsu:feature/core-enhancements
Open

Feature/core enhancements#17
digitsu wants to merge 11 commits into
libitx:masterfrom
digitsu:feature/core-enhancements

Conversation

@digitsu
Copy link
Copy Markdown

@digitsu digitsu commented Feb 20, 2026

Deprecation Fixes (2 commits)

  • use Bitwise → import Bitwise, List.zip → Enum.zip
  • Application.get_env → compile_env
  • raise Module, msg → raise(Module, msg)

Security Fixes (4 commits)

  • ECIES: constant-time MAC comparison + correct PKCS7 padding
  • BIP-32: reject invalid derived keys (zero, ≥ curve order, point at infinity)
  • SIGHASH_FORKID: enforce on signature verification
  • Security doc notes on PrivKey memory model + MerkleProof CVE

Robustness (3 commits)

  • VM: OP_SPLIT bounds check, OP_DIV/OP_MOD division-by-zero, OP_CHECKSIG rescue, negative
    zero handling
  • ScriptNum: configurable max_size guard
  • P2PKH: struct type guards with clear errors
  • DecodeError: fallback message/1 clauses

… with Enum.zip/1

`use Bitwise` has been deprecated since Elixir 1.14 in favour of `import Bitwise`.
`List.zip/1` is deprecated in favour of `Enum.zip/2` since Elixir 1.12.
Application.get_env/3 at module attribute time is a compile-time read and
triggers a warning in Elixir 1.14+. compile_env/3 is the correct replacement.
Credo and mix format prefer `raise(Module, msg)` over `raise Module, msg`
in pipeline/guard-adjacent positions for clarity.
Security fixes for BSV.Message ECIES encryption:

- Use :crypto.hash_equals/2 for MAC verification to prevent timing
  side-channel attacks (was using pattern match equality).
- Fix PKCS7 padding to always add a padding block (per spec, even when
  message is block-aligned). Previous implementation skipped padding
  for aligned messages, which is incorrect per PKCS#7.
- Validate all padding bytes during unpadding, not just the last byte.
  Malformed padding now falls through gracefully instead of silently
  truncating data.
Handle arbitrary reason values without crashing the error formatter.
Binary reasons are returned as-is; other terms are inspected.
Pattern match on %BSV.Address{} and %BSV.KeyPair{} structs explicitly
to provide clear error messages when incorrect types are passed.
Per BIP-32 spec:
- Reject derived private keys that are zero or >= curve order
- Reject derived public keys at the point at infinity
These cases are astronomically unlikely but the spec requires handling them.
BSV requires all signatures to include the FORKID flag. Reject
signatures missing this flag early rather than computing the sighash
and failing later.
- OP_SPLIT: validate index is within range before splitting
- OP_DIV/OP_MOD: explicit division-by-zero error instead of crash
- OP_CHECKSIG: rescue malformed pubkey/signature errors gracefully
- true?/1: handle negative zero correctly for arbitrary-length binaries
  (was only handling single-byte 0x80, but Bitcoin script negative zero
  can be any length with all-zero body and 0x80 MSB)
Prevents memory abuse from oversized script numbers. Default limit is
750KB (BSV post-Genesis has no consensus limit, but we need a practical
bound). Callers can pass a custom max_size.
- PrivKey: document BEAM memory model limitation (keys can't be zeroed)
- MerkleProof: document CVE-2017-12842 leaf/internal node ambiguity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant