Prove vulnerabilities exist without revealing how to exploit them.
Phantom is a revolutionary Julia framework that enables security researchers to:
- Prove vulnerability existence without revealing exploit details
- Anonymous disclosure with cryptographic guarantees
- Time-locked reveals for coordinated disclosure
- Immutable audit trails for accountability
- Blockchain anchoring for timestamping proofs
Traditional vulnerability disclosure creates a dilemma:
- Reveal details → Attackers exploit before patch
- Keep secret → Vendors may ignore
- Partial disclosure → Insufficient proof
Phantom uses Zero-Knowledge Proofs to create cryptographic attestations that:
- ✅ Prove you found a real vulnerability
- ✅ Prove its severity level
- ✅ Prove you have a working exploit
- ❌ WITHOUT revealing how to exploit it
using Pkg
Pkg.add(url="https://github.com/yourusername/Phantom.jl")using Phantom
# Create a vulnerability commitment
details = VulnerabilityDetails(
title = "SQL Injection in Login",
description = "Authentication bypass via malicious input",
affected_systems = ["api.example.com"],
severity = VULN_CRITICAL,
vuln_type = TYPE_INJECTION,
proof_of_concept = "' OR '1'='1",
steps_to_reproduce = ["Navigate to login", "Enter payload", "Access granted"]
)
# Create commitment (hashes details without revealing)
commitment = create_vulnerability_commitment(details)
# Generate ZK proof of severity
severity_proof = generate_severity_proof(
commitment,
VULN_CRITICAL,
VULN_HIGH # Proves severity >= HIGH
)
# Verify proof (anyone can verify without seeing details)
is_valid = verify_severity_proof(severity_proof, VULN_HIGH)
# Returns: true (proves severity is at least HIGH)A commitment cryptographically binds to vulnerability details without revealing them:
# Commitment structure
struct VulnerabilityCommitment
severity_commitment # H(severity || nonce)
type_commitment # H(type || nonce)
description_commitment # H(description || nonce)
proof_commitment # H(proof_of_concept || nonce)
metadata_hash # H(all_metadata)
endProperties:
- Binding: Cannot change details after commitment
- Hiding: Cannot determine details from commitment
- Verifiable: Can prove properties without revealing
Phantom supports multiple proof types:
# Prove severity without revealing exact level
severity_proof = generate_severity_proof(commitment, actual_severity, threshold)
# Prove discovery before a date
timeline_proof = generate_timeline_proof(commitment, discovery_date)
# Prove working exploit exists
exploit_proof = generate_exploitability_proof(commitment, has_poc=true)
# Combine multiple claims
composite = create_composite_proof([
severity_proof,
timeline_proof,
exploit_proof
])Report vulnerabilities without revealing your identity:
# Generate anonymous keypair
keypair = generate_schnorr_keypair()
# Create ring of authorized reporters (e.g., verified researchers)
authorized_ring = [researcher1.public_key, researcher2.public_key, ...]
# Create anonymous report
report = create_anonymous_report(
commitment,
keypair,
authorized_ring
)
# Report proves membership without revealing which researcher you areControl information release over time:
# Define disclosure policy
policy = DisclosurePolicy(
name = "90-day-standard",
vendor_notify_delay = Day(0), # Immediate vendor notification
partial_disclosure_delay = Day(45), # Partial details at 45 days
full_disclosure_delay = Day(90) # Full disclosure at 90 days
)
# Create staged disclosure
disclosure = create_staged_disclosure(policy, commitment, details)
# Advance through stages
advance_disclosure!(disclosure) # To VENDOR_NOTIFIED
advance_disclosure!(disclosure) # To PARTIAL_DISCLOSURE (reveals type)
advance_disclosure!(disclosure) # To FULL_DISCLOSURE (reveals all)Phantom uses BN254 (alt_bn128) for efficient pairing operations:
# Field arithmetic
a = FieldElement(123456789)
b = FieldElement(987654321)
c = a + b # Modular addition
d = a * b # Modular multiplication
# Curve operations
P = G1_GENERATOR
Q = scalar * P # Scalar multiplication# Pedersen commitments (homomorphic)
params = generate_pedersen_params()
commitment = pedersen_commit(params, value, nonce)
# Hash commitments
commitment = hash_commit(data)
# Vector commitments (Merkle-based)
vc = create_vector_commitment(items)
proof = generate_membership_proof(vc, index)# Schnorr signatures
keypair = generate_schnorr_keypair()
signature = schnorr_sign(keypair, message)
valid = schnorr_verify(keypair.public_key, message, signature)
# Ring signatures (anonymous)
ring_sig = ring_sign(my_key, ring_of_public_keys, message)
valid = ring_verify(ring_of_public_keys, message, ring_sig)
# Blind signatures
blinded = blind_message(message, blinding_factor)
blind_sig = blind_sign(signer_key, blinded)
signature = unblind_signature(blind_sig, blinding_factor)Every action creates an immutable audit entry:
# Create audit trail
trail = create_audit_trail()
# Log events
add_audit_event!(trail, AUDIT_COMMITMENT_CREATED, commitment.id, details)
add_audit_event!(trail, AUDIT_PROOF_GENERATED, proof.id, details)
# Verify integrity
result = verify_audit_trail(trail)
println("Valid: ", result.valid)
println("Errors: ", result.errors)Anchor proofs to public blockchains for timestamping:
# Configure blockchain
config = ethereum_config(
"https://mainnet.infura.io/v3/YOUR_KEY",
timestamp_contract = "0x..."
)
# Anchor proof
anchor = anchor_to_ethereum(config, proof.commitment.metadata_hash)
# Verify anchor
is_valid = verify_ethereum_anchor(config, anchor)# Configure API
api_config = PhantomAPIConfig(
base_url = "https://api.phantom.security",
api_version = "v1",
auth_method = :api_key,
api_key = "your_key"
)
# Submit proof
response = submit_proof(api_config, proof)
# Verify remotely
status = verify_proof_remote(api_config, proof.id)Phantom protects against:
- ✅ Information leakage before authorized disclosure
- ✅ Reporter identity exposure
- ✅ Proof forgery
- ✅ Timeline manipulation
- ✅ Audit trail tampering
Phantom does NOT protect against:
- ❌ Side-channel attacks during proof generation
- ❌ Malicious trusted setup (use MPC setup)
- ❌ Quantum computers (use post-quantum upgrades)
- Generate fresh nonces for every commitment
- Use hardware security modules for key storage
- Verify proofs client-side before trusting
- Anchor important proofs to multiple blockchains
- Keep details encrypted until disclosure time
Phantom/
├── src/
│ ├── Phantom.jl # Main module
│ ├── crypto/
│ │ ├── primitives.jl # Field/curve arithmetic
│ │ ├── commitments.jl # Commitment schemes
│ │ ├── zksnark.jl # ZK-SNARK proofs
│ │ └── signatures.jl # Signature schemes
│ ├── core/
│ │ ├── vulnerability.jl # Vulnerability structures
│ │ ├── proof.jl # Proof generation
│ │ └── disclosure.jl # Disclosure policies
│ ├── anonymous/
│ │ ├── reporter.jl # Anonymous reporting
│ │ └── mixer.jl # Transaction mixing
│ ├── audit/
│ │ ├── trail.jl # Audit trails
│ │ └── verification.jl # Audit verification
│ ├── integration/
│ │ ├── api.jl # REST API
│ │ └── blockchain.jl # Blockchain anchoring
│ └── utils/
│ ├── helpers.jl # Utility functions
│ └── serialization.jl # Serialization
└── test/
└── runtests.jl
- Researcher finds vulnerability
- Creates commitment and proof
- Submits anonymous report with proof
- Vendor verifies proof is valid
- Researcher claims bounty anonymously
- Multiple researchers find same bug
- Each creates commitment
- Proofs show same vulnerability without revealing
- Coordinate disclosure timeline
- Release in synchronized manner
- Create protected disclosure with dead man's switch
- Encrypt details for escrow parties
- If whistleblower goes silent, disclosure triggers
- Full anonymity throughout process
Contributions welcome! Areas of interest:
- Post-quantum ZK proof schemes
- Additional blockchain integrations
- Formal verification of circuits
- Performance optimizations
- Additional commitment schemes
MIT License - see LICENSE for details.
- BN254 curve implementation inspired by ethereum/py_pairing
- ZK-SNARK design based on Groth16
- Ring signatures based on CryptoNote
Built with 👻 for the security research community