Skip to content

Klath123/Vajra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Vajra

A real-time, end-to-end encrypted chat application built around post-quantum cryptography. Messages are encrypted on the sender's device using CRYSTALS-Kyber for key encapsulation and AES-GCM for symmetric encryption, then signed with CRYSTALS-Dilithium. The server never sees plaintext.

Features

  • Post-quantum encryption — ML-KEM-768 (CRYSTALS-Kyber) for key encapsulation, AES-GCM for message encryption
  • Digital signatures — ML-DSA-65 (CRYSTALS-Dilithium) to authenticate every message
  • Passwordless login — WebAuthn with biometrics or hardware security keys
  • End-to-end encryption — private keys never leave the browser; the server stores only ciphertext
  • Real-time messaging — WebSocket-based with online status indicators and chat history

Tech Stack

Layer Technology
Frontend React + Vite
Backend FastAPI (Python)
Database MongoDB
Crypto (JS) @noble/post-quantum
Auth WebAuthn + JWT (HTTP-only cookies)

How It Works

Registration — the browser generates three key pairs: a WebAuthn credential, a Kyber key pair (encryption), and a Dilithium key pair (signing). Private keys stay in the browser; public keys go to the server.

Sending a message

  1. Fetch the recipient's Kyber public key from the server.
  2. Encapsulate to produce a one-time shared secret and a KEM ciphertext.
  3. Encrypt the plaintext with AES-GCM using the shared secret.
  4. Sign the plaintext with the sender's Dilithium private key.
  5. Send the KEM ciphertext, AES ciphertext, IV, and signature over WebSocket.

Receiving a message

  1. Decapsulate the KEM ciphertext with your Kyber private key to recover the shared secret.
  2. Decrypt with AES-GCM.
  3. Fetch the sender's Dilithium public key and verify the signature.

Getting Started

Prerequisites

  • Node.js 18+ and npm
  • Python 3.10+
  • MongoDB Atlas account or a local MongoDB instance
  • mkcert (or any tool that can issue a locally trusted TLS certificate)

TLS certificates

Both the frontend dev server and the backend need HTTPS locally because WebAuthn requires a secure context. Generate a certificate for localhost:

mkcert localhost

This creates localhost.pem and localhost-key.pem. Place copies in both backend/ and frontend/.

Backend

cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

Copy .env.example to .env and fill in your values:

cp .env.example .env
DATABASE_URL=mongodb+srv://<user>:<password>@cluster.mongodb.net/
SECRET_KEY=<long-random-string>
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080

RP_ID=localhost
RP_NAME=Vajra
FRONTEND_ORIGIN=https://localhost:5173

Start the server:

uvicorn src:app --reload --ssl-keyfile localhost-key.pem --ssl-certfile localhost.pem

The API is available at https://localhost:8000.

Frontend

cd frontend
npm install
cp .env.example .env
VITE_BACKEND_URL=https://localhost:8000
npm run dev

Open https://localhost:5173 in your browser.

Project Structure

vajra/
├── backend/
│   ├── src/
│   │   ├── __init__.py          # FastAPI app, router registration
│   │   ├── config.py            # Pydantic settings (reads .env)
│   │   ├── db/
│   │   │   └── main.py          # MongoDB client and collections
│   │   ├── models/
│   │   │   └── auth.py          # Pydantic request/response models
│   │   ├── routes/
│   │   │   ├── auth.py          # Registration and login endpoints
│   │   │   ├── chat.py          # WebSocket and message history
│   │   │   └── user.py          # Profile, connections, public keys
│   │   ├── utils/
│   │   │   ├── auth.py          # JWT creation/decoding, user lookup
│   │   │   ├── email.py         # Transactional email (optional)
│   │   │   ├── login.py         # WebAuthn login flow
│   │   │   └── webauthn.py      # WebAuthn registration flow
│   │   └── ws/
│   │       └── connection_manager.py  # WebSocket connection state
│   ├── middleware.py            # CORS configuration
│   ├── requirements.txt
│   └── .env.example
│
└── frontend/
    ├── src/
    │   ├── components/          # UI components (chat, sidebar, navbar)
    │   ├── context/             # Zustand stores
    │   ├── pages/               # Route-level page components
    │   └── utils/
    │       ├── crypto.js        # PQ crypto: keygen, encrypt, sign, verify
    │       ├── chatStorage.js   # IndexedDB wrapper for local message store
    │       └── base64.js        # Base64url helpers for WebAuthn
    ├── vite.config.js
    └── .env.example

Environment Variables Reference

Backend

Variable Description
DATABASE_URL MongoDB connection string
SECRET_KEY Secret used to sign JWTs
ALGORITHM JWT algorithm (use HS256)
ACCESS_TOKEN_EXPIRE_MINUTES Session duration in minutes
RP_ID WebAuthn relying party ID (your domain or localhost)
RP_NAME Display name shown during WebAuthn prompts
FRONTEND_ORIGIN Exact origin of the frontend (e.g. https://localhost:5173)

Frontend

Variable Description
VITE_BACKEND_URL Base URL of the FastAPI backend

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors