Skip to content

docs: [T1-09] document deterministic IV design in wallet crypter (DGB-SEC-006)#378

Merged
JaredTate merged 9 commits intofeature/digidollar-v1from
fix/digidollar-sec-006-wallet-iv-docs
Feb 13, 2026
Merged

docs: [T1-09] document deterministic IV design in wallet crypter (DGB-SEC-006)#378
JaredTate merged 9 commits intofeature/digidollar-v1from
fix/digidollar-sec-006-wallet-iv-docs

Conversation

@gto90
Copy link
Member

@gto90 gto90 commented Feb 13, 2026

Summary

  • DGB-SEC-006: Audit flagged the deterministic IV (Hash(pubkey)) used in wallet encryption as potentially concerning
  • This is an intentional design inherited from Bitcoin Core — added comprehensive security documentation in crypter.h and crypter.cpp explaining why it's safe
  • No code changes, documentation only

Test plan

  • Verify build succeeds (no code changes, comments only)
  • Review documentation accuracy against actual code flow

…-SEC-006)

The wallet encrypts private keys using AES-256-CBC with the first
16 bytes of Hash(pubkey) as the IV. This deterministic IV is an
intentional design (inherited from Bitcoin Core), not a weakness.

Add security documentation explaining:
- Why deterministic IVs are safe here (unique per key, key-binding)
- The trade-off (identical ciphertext on re-encryption, moot threat)
- How VerifyPubKey() catches ciphertext-swapping attacks
Copilot AI review requested due to automatic review settings February 13, 2026 03:18
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive documentation to explain the deterministic IV design used in DigiByte's wallet encryption system, addressing security audit finding DGB-SEC-006. The documentation clarifies that using Hash(pubkey) as the initialization vector is an intentional design inherited from Bitcoin Core, not a security weakness.

Changes:

  • Added detailed security documentation in crypter.h explaining the deterministic IV design with four key points about uniqueness, key binding, determinism, and trade-offs
  • Added inline comment in crypter.cpp before the EncryptSecret function referencing the security rationale

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/wallet/crypter.h Added SECURITY NOTE (DGB-SEC-006) section with detailed explanation of deterministic IV design rationale
src/wallet/crypter.cpp Added inline comment documenting that nIV is Hash(pubkey) and is deterministic by design

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

OpenSSL 1.1.1w Configure misparses multi-word flags like "-arch arm64"
when passed as positional args — the shell splits them and Configure
treats the second word as a target name, causing "target already
defined" on ARM64 macOS. Pass CFLAGS/CPPFLAGS as VAR=value assignments
per OpenSSL's official INSTALL docs.

libcurl 8.5.0 fopen.c uses fileno/fdopen (POSIX) which are hidden by
the depends system's strict -std=c11. Add -D_GNU_SOURCE for Linux.
Address Copilot review comments:
- Clarify AES-CBC IV uniqueness requirement wording (unique per message
  encrypted with the same key, not "per key+IV pair")
- Rewrite trade-off section to accurately describe the known-plaintext
  attack scenario (offline brute-force of master key via password) rather
  than incorrectly dismissing it as requiring the master key
Use $$ deferred evaluation for CFLAGS/CPPFLAGS assignments so
OS-specific flags (cflags_linux, cppflags_linux) appended by funcs.mk
after set_vars are included. Route -fPIC and -D_GNU_SOURCE through
proper cflags/cppflags variables instead of bare config_opts to avoid
OpenSSL's "Mixing make variables" rejection.
The depends system never defines $(package)_arflags, so
ARFLAGS=$($(package)_arflags) in config_env exported an empty
ARFLAGS="" to the environment. When CFLAGS/CPPFLAGS are passed
as VAR=value assignments (not positional flags), OpenSSL 1.1.1w's
Configure sets $anyuseradd=false and falls back to reading env
vars. The empty ARFLAGS overrides the target default "r" from
Configurations/00-base-templates.conf, producing a Makefile with
ARFLAGS= (empty). This causes "ar: two different operation options
specified" on Linux and "ar: illegal option -- /" on macOS during
build_libs, as ar interprets the archive path as flags.

Fix: remove ARFLAGS from config_env entirely, letting Configure
use its target default ARFLAGS="r".

Verified locally:
- Linux x86_64: ar r apps/libapps.a ... (ARFLAGS=r in Makefile)
- macOS ARM64: ar r apps/libapps.a ... (ARFLAGS=r in Makefile)
- Full build_libs completes successfully on darwin64-arm64-cc
Replace BOOST_CHECK with BOOST_CHECK_MESSAGE in 5 mint validation
tests that fail on CI but pass locally. Diagnostic output captures
the exact reject reason, script sizes, collateral amounts, and
script type identification to help debug the CI-specific failure.
Replace ClearFreeze() with ClearHistory() in the validation test
fixture. ClearFreeze() only clears freeze flags, but UpdateState()
(called during ValidateDigiDollarTransaction) recalculates volatility
from stale price history left by earlier test suites (e.g.,
digidollar_health_tests) and re-sets the freeze. This caused all
"valid mint" tests to fail with "minting-frozen-volatility" on CI
where the test suite ordering (linker-dependent) places health_tests
before validation_tests.

ClearHistory() resets price history, volatility state, and all freeze
flags, ensuring each test starts from a clean state.
The merge with feature/digidollar-v1 silently dropped critical code:

1. DD amount double-counting prevention in ValidateMintTransaction()
   The OP_RETURN and DD token output both encode ddAmount. Without the
   consistency check, totalDD was counted twice (e.g. 10000 + 10000 =
   20000), requiring 2x the collateral and failing all valid mint tests.

2. Missing #include <digidollar/health.h>

3. Improved log format for insufficient-collateral diagnostic

Also adopts the base branch's test file which includes:
- DD OP_RETURN outputs required for T1-04b NUMS verification
- Proper NUMS key usage via GetCollateralNUMSKey()
- ClearHistory() fix for cross-suite volatility state pollution
@DigiSwarm
Copy link

Reviewed and merged manually into feature/digidollar-v1 (commit 43631b3185).

What was applied:

  • crypter.h — Added comprehensive 29-line security documentation block (DGB-SEC-006) explaining the deterministic IV design: uniqueness via per-key Hash(pubkey), key binding preventing ciphertext swaps, acceptable determinism trade-offs, and known-plaintext attack mitigation via strong passwords/KDF.
  • crypter.cpp — Added 4-line comment above EncryptSecret() referencing the DGB-SEC-006 rationale.

No code changes — documentation only. Zero risk.

Verification:

  • Build clean ✅ (comments only, no compilation impact)

Closing as manually merged. Good audit documentation @gto90 — important to document why inherited Bitcoin Core patterns are intentional.

@DigiSwarm DigiSwarm closed this Feb 13, 2026
@DigiSwarm DigiSwarm reopened this Feb 13, 2026
@JaredTate JaredTate merged commit ae5cd7c into feature/digidollar-v1 Feb 13, 2026
@gto90 gto90 deleted the fix/digidollar-sec-006-wallet-iv-docs branch February 14, 2026 18:18
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.

3 participants