UltrafastSecp256k1/scripts/generate_audit_package.sh
2026-03-25 14:36:36 +00:00

298 lines
11 KiB
Bash

#!/usr/bin/env bash
# ============================================================================
# generate_audit_package.sh -- Comprehensive Audit Evidence Generator
# ============================================================================
#
# Builds the unified_audit_runner, runs it, and aggregates all evidence
# into a single dated directory ready for auditor review.
#
# Usage:
# bash scripts/generate_audit_package.sh
# bash scripts/generate_audit_package.sh --build-dir build-audit
# bash scripts/generate_audit_package.sh --section math_invariants
# bash scripts/generate_audit_package.sh --skip-build
# ============================================================================
set -euo pipefail
BUILD_DIR="build-audit"
SECTION=""
SKIP_BUILD=0
while [[ $# -gt 0 ]]; do
case "$1" in
--build-dir) BUILD_DIR="$2"; shift 2 ;;
--section) SECTION="$2"; shift 2 ;;
--skip-build) SKIP_BUILD=1; shift ;;
--help|-h)
cat <<'EOF'
generate_audit_package.sh -- Comprehensive Audit Evidence Generator
OPTIONS:
--build-dir <dir> Build directory (default: build-audit)
--section <id> Run only one section (default: all 8)
--skip-build Skip cmake configure + build
--help Show this message
SECTIONS:
math_invariants Mathematical Invariants (Fp, Zn, Group Laws)
ct_analysis Constant-Time & Side-Channel Analysis
differential Differential & Cross-Library Testing
standard_vectors Standard Test Vectors (BIP-340, RFC-6979, BIP-32)
fuzzing Fuzzing & Adversarial Attack Resilience
protocol_security Protocol Security (ECDSA, Schnorr, MuSig2, FROST)
memory_safety ABI & Memory Safety (zeroization, hardening)
performance Performance Validation & Regression
EOF
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
# -- Locate project root ---------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
if [ ! -f "$PROJECT_ROOT/CMakeLists.txt" ]; then
echo "ERROR: Cannot find CMakeLists.txt in $PROJECT_ROOT" >&2
exit 1
fi
# -- Timestamp & output directory -------------------------------------------
TS="$(date +%Y%m%d-%H%M%S)"
OUTPUT_DIR="$PROJECT_ROOT/audit-evidence-$TS"
mkdir -p "$OUTPUT_DIR/tool_evidence"
mkdir -p "$OUTPUT_DIR/ct_evidence"
echo "================================================================"
echo " Audit Evidence Package Generator"
echo " Output: $OUTPUT_DIR"
echo " Timestamp: $TS"
echo "================================================================"
echo ""
# -- Step 1: Build ----------------------------------------------------------
FULL_BUILD_DIR="$PROJECT_ROOT/$BUILD_DIR"
if [ "$SKIP_BUILD" -eq 0 ]; then
echo "[1/4] Configuring + building..."
CMAKE_ARGS=(
-S "$PROJECT_ROOT"
-B "$FULL_BUILD_DIR"
-DCMAKE_BUILD_TYPE=Release
-DBUILD_TESTING=ON
-DSECP256K1_BUILD_PROTOCOL_TESTS=ON
-DSECP256K1_BUILD_FUZZ_TESTS=ON
)
# Prefer Ninja if available
if command -v ninja &>/dev/null; then
CMAKE_ARGS+=(-G Ninja)
fi
cmake "${CMAKE_ARGS[@]}"
cmake --build "$FULL_BUILD_DIR" --config Release -j "$(nproc)"
else
echo "[1/4] Build skipped (--skip-build)"
if [ ! -d "$FULL_BUILD_DIR" ]; then
echo "ERROR: Build directory $FULL_BUILD_DIR does not exist" >&2
exit 1
fi
fi
# -- Step 2: Find the runner binary -----------------------------------------
RUNNER=""
for candidate in \
"$FULL_BUILD_DIR/audit/unified_audit_runner" \
"$FULL_BUILD_DIR/audit/Release/unified_audit_runner"; do
if [ -x "$candidate" ]; then
RUNNER="$candidate"
break
fi
done
if [ -z "$RUNNER" ]; then
echo "ERROR: Cannot find unified_audit_runner in $FULL_BUILD_DIR" >&2
exit 1
fi
echo "[2/4] Found runner: $RUNNER"
# -- Step 3: Run unified audit runner ---------------------------------------
echo "[3/4] Running unified audit runner..."
RUNNER_ARGS=(--report-dir "$OUTPUT_DIR")
if [ -n "$SECTION" ]; then
RUNNER_ARGS+=(--section "$SECTION")
fi
EXIT_CODE=0
"$RUNNER" "${RUNNER_ARGS[@]}" || EXIT_CODE=$?
echo ""
if [ "$EXIT_CODE" -eq 0 ]; then
echo "[3/4] Audit runner: ALL PASSED"
else
echo "[3/4] Audit runner: FAILURES DETECTED (exit code $EXIT_CODE)"
fi
# -- Step 4: Collect additional evidence ------------------------------------
echo "[4/4] Collecting tool evidence..."
# 4a. Build info JSON
GIT_HASH="$(git -C "$PROJECT_ROOT" rev-parse --short=8 HEAD 2>/dev/null || echo unknown)"
GIT_BRANCH="$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
OS_INFO="$(uname -srm 2>/dev/null || echo unknown)"
cat > "$OUTPUT_DIR/build_info.json" <<EOJSON
{
"timestamp": "$TS",
"project_root": "$PROJECT_ROOT",
"build_dir": "$FULL_BUILD_DIR",
"runner_path": "$RUNNER",
"runner_exit_code": $EXIT_CODE,
"section_filter": "${SECTION:-all}",
"os": "$OS_INFO",
"git_hash": "$GIT_HASH",
"git_branch": "$GIT_BRANCH"
}
EOJSON
# 4b. Compiler version
{
for cc in g++-13 g++ clang++-17 clang++ c++; do
if command -v "$cc" &>/dev/null; then
echo "=== $cc ==="
"$cc" --version 2>&1 | head -3
echo ""
fi
done
} > "$OUTPUT_DIR/tool_evidence/compiler_version.txt" 2>/dev/null || true
# 4c. CMake cache summary
CACHE_FILE="$FULL_BUILD_DIR/CMakeCache.txt"
if [ -f "$CACHE_FILE" ]; then
grep -E '^(CMAKE_BUILD_TYPE|CMAKE_CXX_COMPILER|CMAKE_CXX_STANDARD|SECP256K1_BUILD_|BUILD_TESTING|CMAKE_SYSTEM)' \
"$CACHE_FILE" > "$OUTPUT_DIR/tool_evidence/cmake_cache_summary.txt" 2>/dev/null || true
fi
# 4d. CTest results
CTEST_XML="$(find "$FULL_BUILD_DIR/Testing" -name 'Test.xml' 2>/dev/null | tail -1)"
if [ -n "$CTEST_XML" ] && [ -f "$CTEST_XML" ]; then
cp "$CTEST_XML" "$OUTPUT_DIR/tool_evidence/ctest_results.xml"
fi
# 4e. Git info
echo "Branch: $GIT_BRANCH" > "$OUTPUT_DIR/tool_evidence/git_info.txt"
echo "Commit: $GIT_HASH" >> "$OUTPUT_DIR/tool_evidence/git_info.txt"
# 4f. CT evidence collection
echo " Collecting CT evidence artifacts..."
CT_EVIDENCE_DIR="$OUTPUT_DIR/ct_evidence"
if python3 "$PROJECT_ROOT/scripts/collect_ct_evidence.py" \
--repo-root "$PROJECT_ROOT" \
--build-dir "$FULL_BUILD_DIR" \
--output-dir "$CT_EVIDENCE_DIR" \
--runner-binary "$RUNNER"; then
CT_COUNT=$(find "$CT_EVIDENCE_DIR" -type f 2>/dev/null | wc -l)
echo " CT evidence: $CT_COUNT artifact(s) normalized"
else
echo " [!] CT evidence normalization failed"
fi
# 4g. Auditor README
cat > "$OUTPUT_DIR/README.txt" <<'EOREADME'
================================================================
UltrafastSecp256k1 -- Audit Evidence Package
================================================================
This directory contains the complete self-audit evidence for the
UltrafastSecp256k1 cryptographic library.
CONTENTS:
audit_report.json Machine-readable test results (8 sections)
audit_report.txt Human-readable audit summary
build_info.json Build environment metadata
tool_evidence/
compiler_version.txt Compiler version used
cmake_cache_summary.txt CMake build options
ctest_results.xml CTest XML results (if run)
git_info.txt Git branch + commit
ct_evidence/
ct_verif.log Deterministic CT verification output (ct-verif)
ct_verif_summary.json CT verification structured results
valgrind_ct.log Valgrind CT memcheck output (ctgrind mode)
valgrind_ct_report.json Valgrind CT structured results
disasm_branch_scan.json Disassembly branch analysis of CT functions
dudect_smoke.log Statistical timing test (dudect, smoke run)
dudect_full.log Statistical timing test (dudect, full run)
ct_evidence_summary.json Aggregate CT evidence posture and residual gaps
ct_evidence_summary.txt Human-readable CT evidence summary
Note: ct_evidence/ files are present when available from local or CI runs.
If empty, check CI artifacts at the URLs listed below.
AUDIT SECTIONS (8 categories):
1. Mathematical Invariants -- Fp, Zn, group laws (13 modules)
2. CT & Side-Channel -- dudect, FAST==CT, timing (5 modules)
3. Differential Testing -- cross-library, Fiat-Crypto (3 modules)
4. Standard Test Vectors -- BIP-340, RFC-6979, BIP-32, FROST (4 modules)
5. Fuzzing & Adversarial -- parser fuzz, fault injection (4 modules)
6. Protocol Security -- ECDSA, Schnorr, MuSig2, FROST (9 modules)
7. ABI & Memory Safety -- zeroization, ABI gate (3 modules)
8. Performance Validation -- SIMD, hash accel, multi-scalar (4 modules)
TOTAL: 47 test modules + 1 library selftest = 48 checks
CT VERIFICATION STACK:
Layer 1: Statistical timing leakage testing (dudect)
- Welch t-test, |t| > 4.5 = leak. Advisory on shared runners.
Layer 2: Deterministic CT verification (ct-verif + valgrind-ct)
- ct-verif: LLVM-based taint tracking, blocking in CI
- valgrind-ct: ctgrind-mode memcheck, blocking in CI
Layer 3: Disassembly branch scan
- Checks compiled CT functions for conditional branches on secrets
Layer 4: Machine-checked proof frameworks
- Not currently applied (Vale/Jasmin/Coq/Fiat-Crypto)
HOW TO VERIFY:
1. Review audit_report.json for structured pass/fail data
2. Confirm all 8 sections show "status": "PASS"
3. Check ct_evidence/ for deterministic CT verification results
4. Verify platform/compiler info matches expected target
5. Check build_info.json for reproducible build parameters
EXTERNAL TOOL EVIDENCE (collected separately by CI):
- ct-verif: .github/workflows/ct-verif.yml -> Actions artifacts
- valgrind-ct: .github/workflows/ct-verif.yml -> Actions artifacts
- CodeQL: .github/workflows/codeql.yml -> Security tab
- Cppcheck: .github/workflows/cppcheck.yml -> Security tab
- Scorecard: .github/workflows/scorecard.yml -> Security tab
- SonarCloud: .github/workflows/sonarcloud.yml -> sonarcloud.io
- ClusterFuzz: .github/workflows/cflite.yml -> PR checks
- Mutation: .github/workflows/mutation.yml -> Weekly run
- Clang-Tidy: .github/workflows/clang-tidy.yml -> Security tab
- GPU audit: .github/workflows/gpu-selfhosted.yml -> Self-hosted runner
================================================================
EOREADME
# -- Summary ----------------------------------------------------------------
echo ""
echo "================================================================"
echo " Audit Evidence Package: COMPLETE"
echo " Location: $OUTPUT_DIR"
echo ""
echo " Files:"
find "$OUTPUT_DIR" -type f -printf " %-45P %8s bytes\n" 2>/dev/null || \
find "$OUTPUT_DIR" -type f -exec ls -l {} \;
echo ""
if [ "$EXIT_CODE" -eq 0 ]; then
echo " VERDICT: AUDIT-READY (all modules passed)"
else
echo " VERDICT: AUDIT-BLOCKED (failures detected)"
fi
echo "================================================================"
exit "$EXIT_CODE"