Blind Compliance Oracle
Patients submit real health data. Sponsors define hidden thresholds. Neither party sees the other's raw values. A cryptographic oracle proves compliance without revealing anything.
The Problem: Gaming & Spoofing
Traditional compliance systems expose exact thresholds to patients:
Program: "Walk at least 8,000 steps daily"
Patient: [fabricates 8,001 steps]
Result: ✓ Compliant (but data is worthless)
If patients know exactly what qualifies, they can fabricate data that passes verification but carries no scientific value. This destroys the dataset's integrity and wastes sponsor funding.
The Solution: Threshold-Blind Submission
The Blind Compliance Oracle separates what to submit from how much qualifies:
| What the patient sees | What's hidden |
|---|---|
| "Submit your activity data weekly" | Threshold: ≥ 5,000 steps |
| "Submit your vitals monthly" | Threshold: systolic BP ≤ 140 |
| "Submit glucose readings" | Threshold: fasting glucose 70-130 mg/dL |
The patient knows the category of data to submit but never the exact threshold that determines compliance.
Architecture
Patient Device Compliance Oracle Sponsor
───────────── ───────────────── ───────
Define thresholds
↓
Poseidon(salt, threshold, comparator)
→ requirementCommitment (published)
Store encrypted thresholds (oracle-only)
"Submit vitals weekly"
← See only data categories
Collect health data
↓
Poseidon(salt, dataType, value)
→ dataCommitment
NaCl.box(value, oraclePublicKey)
→ encryptedPayload
Send(commitment + encrypted) Decrypt payload (oracle key)
Compare value vs hidden threshold
Generate proof of result
→ complianceProof (HMAC or Groth16)
← pass/fail + proof Store in ComplianceLog
Anchor in Merkle tree
Award credits if fulfilled
Commitment Scheme
Requirement Commitment (Sponsor Side)
reqCommitment = Poseidon(
sponsorSalt[0..1], // 32-byte random salt (oracle-only)
dataTypeHash, // Poseidon(UTF-8 bytes of dataType)
scaledThreshold, // Integer-scaled threshold value
comparator // 0=GTE, 1=LTE, 2=EQ, 3=RANGE
)
Published to patients: the commitment hash (opaque 32 bytes). Stored encrypted: the plaintext threshold + salt (oracle decrypts at evaluation time).
Data Commitment (Patient Side)
dataCommitment = Poseidon(
patientSalt[0..1], // 32-byte random salt (stored locally)
dataTypeHash, // Same encoding as requirement
scaledValue // Patient's actual value (integer-scaled)
)
This proves the patient committed to a specific value before seeing the result.
Value Scaling Convention
All values are scaled to integers for field arithmetic:
| Data Type | Scale Factor | Example |
|---|---|---|
| Steps | ×1 | 8000 → 8000 |
| Blood pressure (mmHg) | ×10 | 120.5 → 1205 |
| Weight (kg) | ×100 | 72.5 → 7250 |
| Glucose (mg/dL) | ×10 | 100.5 → 1005 |
| Duration (minutes) | ×1 | 45 → 45 |
| Boolean | ×1 | 1 → 1 |
| HbA1c (%) | ×100 | 6.5 → 650 |
Comparator Types
| Code | Symbol | Usage |
|---|---|---|
| 0 | ≥ (GTE) | Minimum thresholds (steps, exercise) |
| 1 | ≤ (LTE) | Maximum thresholds (blood pressure, glucose) |
| 2 | = (EQ) | Exact match (boolean flags) |
| 3 | [min, max] (RANGE) | Within range (fasting glucose 70-130) |
Proof Types
Phase 1: HMAC Oracle Proof (Current)
The trusted oracle evaluates compliance and signs the result with HMAC-SHA256:
proofPayload = "${fulfilled}|${timestamp}|${SHA256(value)}|${dataCommitment}"
proof = HMAC-SHA256(oracleSecret, proofPayload)
proofHash = SHA256(proof) // Anchored in Merkle tree
Trust model: The oracle is trusted to evaluate honestly. Proofs are immutable once anchored.
Phase 2: Groth16 ZK Proof (Planned)
A zero-knowledge circuit proves compliance without trusting any party:
Public inputs: dataCommitment, reqCommitment, result (0 or 1)
Private inputs: patientSalt, sponsorSalt, scaledValue, threshold, comparator, dataTypeHash
Circuit constraints:
1. dataCommitment == Poseidon(patientSalt, dataTypeHash, scaledValue)
2. reqCommitment == Poseidon(sponsorSalt, dataTypeHash, threshold, comparator)
3. compare(scaledValue, threshold, comparator) == result
Trust model: Trustless — anyone can verify the proof. Neither patient nor sponsor needs to trust the oracle.
Circuit files: {userData}/bia-circuits/blind-compliance-v1/
Phase 3: Homomorphic Encryption (Future)
Compute compliance on encrypted data without decrypting:
HE.encrypt(patientValue, programPublicKey) → ciphertext
HE.compare(ciphertext, encryptedThreshold) → encryptedResult
HE.decrypt(encryptedResult, oraclePrivateKey) → boolean
Planned operations: HE_SUM (rolling averages), HE_COMPARE, HE_RANGE, HE_MEAN.
Auto-Compliance Cron
A background job evaluates pending submissions every minute:
- Query all
BlindSubmissionrecords whereevaluated = false - For each submission:
- Decrypt patient value (AES-256-GCM / NaCl.box)
- Look up requirement threshold
- Compare using the requirement's comparator
- Generate proof
- Award credits if fulfilled
- Create backward-compatible
ComplianceLogentry - Update enrollment compliance score and streak
- Log results for monitoring
Dynamic Pricing
Credit awards are dynamically adjusted based on:
| Factor | Effect | Rationale |
|---|---|---|
| Enrollment saturation < 25% | +30% bonus | Reward early adopters |
| Enrollment saturation > 90% | -10% | Near capacity, less marginal value |
| Rarity score 5 (Ultra-Rare) | +50% permanent | Rare disease data is exceptionally valuable |
| Program fully funded | +10% | Higher payout confidence |
| Program seeking sponsor | -15% | Credits are promises, not cash |
| First from a country | +50% geo bonus | Geographic diversity is critical for AI |
| Under 2% from country | +30% geo bonus | Underrepresented population |
Sponsor Self-Service
Sponsors interact with the system through these endpoints:
| Endpoint | Method | Purpose |
|---|---|---|
/api/SponsorPrograms | POST | Create program with blinded requirements |
/api/SponsorPrograms/{id}/fund | PATCH | Deposit funds to escrow |
/api/SponsorPrograms/my-programs | GET | List sponsor's programs |
/api/SponsorPrograms/{id}/dashboard | GET | Aggregate compliance dashboard |
Privacy guarantee: Sponsors NEVER see individual patient data. Dashboard shows only:
- Aggregate compliance rates
- Geographic distribution (country-level counts)
- Budget metrics (committed / deposited / spent / remaining)
- Total submissions and fulfillment rate
Notification Events
| Event | Recipient | Trigger |
|---|---|---|
enrollment_confirmed | Patient | After successful enrollment |
compliance_pass | Patient | Oracle verifies submission as compliant |
compliance_fail | Patient | Submission doesn't meet hidden criteria |
submission_due | Patient | 24h before deadline |
program_funded | All enrollees | Sponsor deposits funds |
payout_ready | Patient | Credits converted to payout |
streak_milestone | Patient | Consecutive compliance periods |
compliance_dropping | Patient | Score falling toward tier downgrade |
Client Integration
Web (Ever OMA React Web)
import BlindSubmissionPanel from 'containers/DataPrograms/BlindSubmissionPanel';
import SponsorDashboard from 'containers/DataPrograms/SponsorDashboard';
// Patient view: submit data with hidden thresholds
<BlindSubmissionPanel enrollmentId={id} programId={pid} />
// Sponsor view: aggregate dashboard
<SponsorDashboard />
Mobile (React Native)
import BlindSubmissionSheet from 'screens/DataStaking/BlindSubmissionSheet';
<BlindSubmissionSheet
enrollmentId={id}
programId={pid}
onDismiss={() => setVisible(false)}
/>
Sovereign Wallet (Electron + edh-core)
import BlindSubmissionPanel from './panels/BlindSubmissionPanel'
// Uses real Poseidon commitments via edh-core
// Uses NaCl.box for oracle encryption
<BlindSubmissionPanel enrollmentId={id} programId={pid} />
Security Properties
| Property | Mechanism | Guarantee |
|---|---|---|
| Anti-spoofing | Hidden thresholds | Patients can't fabricate data to match unknown criteria |
| Data privacy | NaCl.box encryption | Only oracle decrypts raw values |
| Commitment binding | Poseidon commitment | Patient can't change value after submission |
| Proof immutability | Merkle anchoring | Proofs are tamper-evident once anchored |
| Sponsor blindness | Aggregate-only dashboard | Sponsors never see individual data |
| Verifiability | HMAC/Groth16 proofs | Anyone can verify compliance was evaluated honestly |
Implementation Files
| Repo | File | Purpose |
|---|---|---|
| edh-central | ever-edh-core/src/bio/blind-compliance.ts | Core crypto: commitments, proofs, ZK circuit |
| backend | src/research/entities/requirement-commitment.entity.ts | Sponsor's blinded requirements |
| backend | src/research/entities/blind-submission.entity.ts | Patient's committed submissions |
| backend | src/research/entities/sponsor-program.entity.ts | Sponsor self-service record |
| backend | src/research/blind-compliance.service.ts | Oracle evaluation, cron, pricing, notifications |
| backend | src/research/blind-compliance.controller.ts | API endpoints |
| web | app/containers/DataPrograms/BlindSubmissionPanel.js | Web submission UI |
| web | app/containers/DataPrograms/SponsorDashboard.js | Sponsor dashboard UI |
| mobile | app/screens/DataStaking/BlindSubmissionSheet.js | Mobile submission UI |
| wallet | src/renderer/src/panels/BlindSubmissionPanel.tsx | Desktop wallet submission |
Roadmap
- Phase 1: HMAC oracle proof (trusted oracle, AES-256-GCM encryption)
- Phase 2: Groth16 ZK circuit (
blind-compliance-v1) — trustless verification - Phase 3: TFHE/SEAL homomorphic encryption — compute on encrypted data
- Phase 4: Federated compliance — oracle runs in TEE (Intel SGX / ARM TrustZone)