Spaces:
Sleeping
Sleeping
| title: SecureLens | |
| emoji: π | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: mit | |
| short_description: TRUE FHE Privacy-Preserving Pneumonia Detection (CKKS) | |
| <div align="center"> | |
| # π SecureLens | |
| ### TRUE Fully Homomorphic Encryption for Medical AI | |
| [](https://huggingface.co/spaces/paulamartya25/SecureLens) | |
| [](https://securelens-1-m5kt.onrender.com/health) | |
| [](https://python.org) | |
| [](https://pytorch.org) | |
| [](https://github.com/OpenMined/TenSEAL) | |
| [](LICENSE) | |
| **Privacy-Preserving Pneumonia Detection β the server computes on encrypted data and is mathematically unable to decrypt it.** | |
| </div> | |
| --- | |
| ## ποΈ TRUE FHE Architecture β Two Physical Machines | |
| ``` | |
| ββββββββββββββββββββββββββββββββββββ HTTPS β ciphertext only ββββββββββββββββββββββββββββββββββββ | |
| β CLIENT β HuggingFace Spaces β ββββββββββββββββββββββββββΊ β SERVER β Render.com β | |
| β paulamartya25/SecureLens β β securelens-1-m5kt.onrender.com β | |
| β β β β | |
| β β ResNet-18 extracts features β β β W1 @ enc(x) + b1 [HE math] β | |
| β β CKKS encrypt β 326 KB cipher β ββββββββββββββββββββββββββ β β W2 @ enc(h) + b2 [HE math] β | |
| β β Secret key β HERE ONLY β encrypted logits β β NO secret key β | |
| β β Decrypt result locally β β β NEVER decrypts β | |
| β β β β Cannot see plaintext β | |
| β Machine A (USA) β β Machine B (Singapore) β | |
| ββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ | |
| Two physically separate machines β different companies β TRUE FHE privacy guarantee | |
| ``` | |
| ### Why This Matters | |
| | Approach | Server sees patient data? | Privacy guaranteed by? | | |
| |----------|--------------------------|------------------------| | |
| | Traditional ML | β Yes β raw image | β Nothing | | |
| | Encrypted Transport (HTTPS) | β Yes β after decryption | β Trust only | | |
| | **SecureLens TRUE FHE** | **β Never β only ciphertext** | **β Mathematics** | | |
| --- | |
| ## β¨ Features | |
| ### 5-Tab Gradio Interface | |
| | Tab | Description | | |
| |-----|-------------| | |
| | π **TRUE FHE Classification** | Upload X-ray β encrypt locally β server computes on ciphertext β local decrypt β diagnosis | | |
| | βοΈ **Attack Demo** | Adversarial robustness testing β noise, blur, brightness, contrast, FGSM, combined | | |
| | π **FHE vs Traditional** | Side-by-side performance & timing comparison | | |
| | π§ **GradCAM** | Explainable AI β gradient-weighted class activation maps | | |
| | π **Model Evaluation** | Accuracy, Precision, Recall, F1, ROC-AUC, Confusion Matrix | | |
| ### Security & Reliability | |
| - π **128-bit CKKS encryption** via TenSEAL | |
| - π **Secret key physically isolated** on client machine | |
| - β‘ **Wake Server button** β shows live server status before demo | |
| - π **Background keep-alive** β pings server every 10 min | |
| - π€ **UptimeRobot** β external monitor pings every 5 min | |
| - β **Auto fallback** β gracefully falls back to in-process if server unreachable | |
| --- | |
| ## π¬ Technical Architecture | |
| ### Model Pipeline | |
| ``` | |
| Input X-Ray Image (224Γ224Γ3) | |
| β | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββ | |
| β ResNet-18 Backbone β β Pretrained on ImageNet | |
| β (feature extractor) β | |
| β Global Average Pooling β | |
| β Output: 512-dim feature vector β | |
| ββββββββββββββββ¬βββββββββββββββββββ | |
| β Plaintext features (client only) | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββ | |
| β CKKS Encryption (CLIENT SIDE) β β Secret key generated here | |
| β enc(features) = 326 KB cipher β β Never leaves this machine | |
| ββββββββββββββββ¬βββββββββββββββββββ | |
| β Ciphertext sent over HTTPS | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββ | |
| β FHE Server (Render.com) β β Different physical machine | |
| β β | |
| β Layer 1: W1 @ enc(x) + b1 β β Pure homomorphic math | |
| β Layer 2: W2 @ enc(h) + b2 β β Still on ciphertext | |
| β β | |
| β Returns: enc(logits) β β Never decrypted | |
| ββββββββββββββββ¬βββββββββββββββββββ | |
| β Encrypted logits returned | |
| βΌ | |
| βββββββββββββββββββββββββββββββββββ | |
| β Client Decryption β β Uses secret key (client only) | |
| β Softmax β Prediction β | |
| β Display: Normal / Pneumonia β | |
| βββββββββββββββββββββββββββββββββββ | |
| ``` | |
| ### Why No ReLU in the FHE Head? | |
| ReLU requires value comparison on ciphertext β computationally intractable in CKKS. The linear head (no non-linearity) is the standard approach for FHE-compatible neural networks. Accuracy is preserved because the ResNet-18 backbone handles all non-linear feature extraction. | |
| ### CKKS Parameters | |
| | Parameter | Value | Reason | | |
| |-----------|-------|--------| | |
| | Polynomial modulus degree | 8192 | 128-bit security | | |
| | Coefficient modulus bits | [60, 40, 40, 60] | 2 multiplication levels | | |
| | Global scale | 2β΄β° | Precision balance | | |
| | Security level | 128-bit | SEAL library standard | | |
| | Ciphertext size | ~326 KB | 512-dim vector | | |
| --- | |
| ## π Project Structure | |
| ``` | |
| SecureLens/ | |
| βββ app.py # HF Spaces entry point | |
| βββ app_gradio_enhanced_FOR_HF.py # Main 5-tab Gradio interface | |
| β # β fhe_server_infer() calls Render over HTTP | |
| β # β warm_up_server() for Wake button | |
| β # β _keep_alive_loop() background thread | |
| βββ requirements.txt # Client dependencies | |
| βββ Dockerfile # Client Docker config | |
| β | |
| βββ server/ # π TRUE FHE Server (Render.com) | |
| β βββ server_fhe.py # Flask API β HE inference only, no decrypt | |
| β βββ feature_weights.json # W1 matrix (256Γ512) | |
| β βββ linear_weights.json # W2 matrix (2Γ256) | |
| β βββ requirements.txt # flask, tenseal, numpy only (no torch!) | |
| β βββ Dockerfile # Render.com Docker config | |
| β | |
| βββ crypto_layer/ | |
| β βββ ckks_engine.py # CKKS engine β encrypt/decrypt (CLIENT ONLY) | |
| β | |
| βββ cloud_server/ | |
| β βββ server.py # Flask server for local deployment | |
| β βββ client_pipeline.py # Native Python client (true FHE locally) | |
| β βββ train_model_fhe_compatible.py # SecureLensNetFHE β FHE-compatible model | |
| β βββ models/ | |
| β β βββ best_model.pth # Trained weights (Git LFS) | |
| β β βββ feature_weights.json # Exported W1 (Git LFS) | |
| β β βββ linear_weights.json # Exported W2 | |
| β βββ encrypted_inference/ | |
| β βββ he_inference.py # HE engine β NEVER calls .decrypt() | |
| β | |
| βββ client/ | |
| βββ templates/ # HTML templates (Flask web UI version) | |
| ``` | |
| --- | |
| ## π Run It Yourself | |
| ### Option 1 β Live Demo (No Setup) | |
| π **[huggingface.co/spaces/paulamartya25/SecureLens](https://huggingface.co/spaces/paulamartya25/SecureLens)** | |
| ### Option 2 β Local (True Physical Separation) | |
| ```bash | |
| # Clone repo | |
| git clone https://github.com/paulamartya25/SecureLens-.git | |
| cd SecureLens- | |
| # Terminal 1 β Run the FHE server (Machine B) | |
| cd server/ | |
| pip install -r requirements.txt | |
| python server_fhe.py | |
| # β Running on http://localhost:10000 | |
| # Terminal 2 β Run the Gradio client (Machine A) | |
| cd .. | |
| pip install -r requirements.txt | |
| FHE_SERVER_URL=http://localhost:10000 python app.py | |
| # β Open http://localhost:7860 | |
| ``` | |
| ### Option 3 β Docker | |
| ```bash | |
| # Server | |
| docker build -t securelens-server ./server/ | |
| docker run -p 10000:10000 securelens-server | |
| # Client (in another terminal) | |
| docker build -t securelens-client . | |
| docker run -p 7860:7860 -e FHE_SERVER_URL=http://host.docker.internal:10000 securelens-client | |
| ``` | |
| ### Option 4 β Native Python Client (Full True FHE) | |
| ```bash | |
| # Uses client_pipeline.py β secret key truly local | |
| python cloud_server/client_pipeline.py cloud_server/models/best_model.pth your_xray.jpg | |
| ``` | |
| --- | |
| ## π οΈ Technology Stack | |
| | Component | Technology | Purpose | | |
| |-----------|-----------|---------| | |
| | FHE | [TenSEAL](https://github.com/OpenMined/TenSEAL) (CKKS) | Homomorphic encryption | | |
| | Deep Learning | PyTorch 2.0.1, ResNet-18 | Feature extraction | | |
| | Web Interface | Gradio 3.50.2 | 5-tab demo UI | | |
| | FHE Server | Flask + Gunicorn | HE inference API | | |
| | Client Hosting | HuggingFace Spaces (Docker) | Public demo | | |
| | Server Hosting | Render.com (Docker) | Separate FHE server | | |
| | Uptime | UptimeRobot | Keep-alive monitoring | | |
| --- | |
| ## π How CKKS Homomorphic Encryption Works | |
| ```python | |
| # Standard ML inference (NOT private): | |
| features = model(xray) # plaintext | |
| logits = W @ features + b # plaintext | |
| prediction = softmax(logits) | |
| # SecureLens FHE inference (PRIVATE): | |
| features = backbone(xray) # plaintext β CLIENT ONLY | |
| enc_x = ckks.encrypt(features) # 326 KB ciphertext β client | |
| # Server receives enc_x β cannot see features | |
| enc_h = enc_x.dot(W1) + b1 # homomorphic dot product on ciphertext | |
| enc_logits = enc_h.dot(W2) + b2 # still encrypted | |
| # Client receives enc_logits β server never saw plaintext | |
| logits = ckks.decrypt(enc_logits) # secret key on client only | |
| prediction = softmax(logits) # Normal / Pneumonia | |
| ``` | |
| --- | |
| ## β οΈ Disclaimer | |
| Research prototype demonstrating FHE in medical AI. **Not intended for clinical use.** | |
| --- | |
| <div align="center"> | |
| **SecureLens** β Proving that AI can be both intelligent and private. | |
| *CKKS Β· TenSEAL Β· PyTorch Β· ResNet-18 Β· 128-bit Security* | |
| Built by [Amartya Paul](https://github.com/paulamartya25) | |
| </div> | |