Skip to content

ShreyashSri/SiMG

Repository files navigation

SiMG

SiMG is an Electron desktop application that cryptographically verifies medical DICOM images before they reach an AI inference model. It catches supply chain attacks and adversarial converter compromises by treating the DICOM-to-image converter as an untrusted process, fingerprinting the raw DICOM independently, and comparing the two outputs before any diagnosis runs.

Why This Exists

Medical AI pipelines rely on open-source DICOM-to-image converters (pydicom, SimpleITK, etc.) as an unaudited bridge between scanner output and deep learning inference. A compromised converter can embed imperceptible adversarial perturbations into every image it converts, causing systematic and silent misdiagnosis.

Known CVEs confirm this attack class is real:

  • CVE-2024-23912: DICOM parser memory corruption
  • CVE-2019-11687: malformed DICOM triggers arbitrary code execution
  • CVE-2024-23913: DICOM metadata injection

SiMG addresses this by independently fingerprinting the raw DICOM data and verifying the converter output against that fingerprint before inference.

Pipeline Overview

The pipeline runs in four stages:

SiMG Pipeline Architecture

  1. Fingerprint + Convert (parallel): The C++ anchor engine reads the raw DICOM, computes a perceptual hash (DCT-pHash), radial ring descriptors, and a histogram, then signs the result with ECDSA P-256 and writes a .simg reference file. In parallel, the Python converter (pydicom) converts the DICOM to PNG.

  2. Verify: The verifier runs inside a namespace sandbox (user + network + PID isolation). It reads the .simg file, validates the ECDSA signature, re-derives all three descriptors from the converted PNG, and computes a weighted similarity score. If the score falls below 0.85, the pipeline halts with a security failure.

  3. Infer: If verification passes, the verified PNG is sent to a Gemini-backed inference operator that classifies the medical image.

  4. Result: The Electron UI displays either the diagnosis result or the specific failure type (security failure vs pipeline error), so security incidents are never silently absorbed as generic errors.

Project Structure

SiMG/
  converter/           Python DICOM-to-PNG converters (clean + evil simulator)
  desktop/             Electron app (TypeScript + React)
  fingerprint/
    anchor/            C++ anchor engine (DICOM reader, pHash, rings, SIMG writer)
    verifier/          C++ verifier (SIMG reader, comparator, PNG loader)
  inference-pipeline/  Python inference operators (Guardian check + Gemini inference)
  keys/                ECDSA P-256 key pair (private.pem must be generated locally)
  pipelines/           Shell trigger scripts for each pipeline stage
  sandbox/             Namespace sandbox wrapper for the verifier
  simg.sh              Standalone CLI pipeline runner
  test_converters.py   Converter test suite

Prerequisites

System packages

Install these before building:

sudo apt update
sudo apt install cmake build-essential libssl-dev libpng-dev libjpeg-dev

Runtime requirements

  • Linux: namespace isolation (unshare) is used for the verification sandbox. Windows users must use WSL2, as native Windows does not support Linux kernel namespaces.
  • Python 3.10+: required for the converter and inference pipeline
  • Node.js 20+: required for the Electron desktop app
  • Gemini API key: required for inference (set in inference-pipeline/.env)

Setup

1. Generate ECDSA keys

The anchor signs fingerprints with a private key. The verifier checks signatures with the corresponding public key. Generate a fresh key pair before first use:

cd keys/
openssl ecparam -name prime256v1 -genkey -noout -out private.pem
openssl ec -in private.pem -pubout -out public.pem

private.pem is gitignored and must never be committed. Only public.pem is needed at runtime for verification.

2. Set up the converter

cd converter/
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

3. Set up the inference pipeline

cd inference-pipeline/
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Create a .env file in inference-pipeline/ with your Gemini API key:

GEMINI_API_KEY=your_key_here

4. Build the C++ binaries

From the repo root:

cd fingerprint/anchor
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

cd ../verifier
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

Or use the helper script from the desktop directory:

cd desktop/
npm run build:cpp

5. Build and run the desktop app

cd desktop/
npm install
npm run build
npm start

Drop a DICOM file into the UI to run the full pipeline.

CLI Usage

You can also run the pipeline without the desktop app:

# Clean converter (should PASS verification)
./simg.sh /path/to/scan.dcm 0

# Evil converter: simulates a supply chain attack (should FAIL)
./simg.sh /path/to/scan.dcm 1

Running Tests

The converter test suite validates that the clean converter is deterministic, the evil converter produces imperceptible but detectable perturbations, and histogram divergence is measurable:

python3 test_converters.py

SIMG Fingerprint Format

ref.simg is a fixed-size 760-byte binary file written by the anchor and verified before inference.

Field Offset Size Description
Magic 0 4 B 0x534D4947 ("SIMG")
Version 4 2 B Format version (currently 1)
pHash 8 8 B 64-bit DCT perceptual hash
Ring descriptors 16 64 B 8-zone radial mean + stddev
Histogram 80 512 B 64-bin normalised intensity histogram
SHA-256 592 32 B Hash of all fields above
ECDSA signature 624 72 B DER-encoded P-256 signature over SHA-256

Verification Score

The verifier computes three descriptors from the converted PNG and compares them against the reference in ref.simg:

score = 0.4 * phash_score + 0.3 * ring_score + 0.3 * hist_score
Component Metric Scoring
pHash Hamming distance 1 - (hamming / tolerance)
Ring descriptors Max zone deviation 1 - (deviation / tolerance)
Histogram Symmetric KL divergence 1 - (kl / tolerance)

Threshold is 0.85. A score below this halts the pipeline with SECURITY FAILURE.

Trust Model

Component Trust Reason
Anchor engine Trusted Built from audited C++ source
Public key Trusted Committed to repo, read-only
Converter (pydicom) Untrusted Treated as potentially compromised
Verifier Trusted Runs inside namespace sandbox
Inference pipeline Untrusted runtime Isolated execution, no network

The private key never leaves the signing host and is never committed to version control.

Failure Modes

Type Log prefix Meaning
Security failure [GUARDIAN] SECURITY FAILURE Converter output does not match anchor fingerprint
Pipeline failure [MONAI] PIPELINE ERROR Runtime or model error during inference

These are surfaced separately in the UI so security incidents are never absorbed as generic errors.

About

A cross-platform Electron application that cryptographically verifies medical DICOM images before they reach an AI inference model, catching supply chain attacks, adversarial converter compromises, and pipeline failures as two distinct, separately surfaced error classes.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors