Authentication Flow
Authentication Flow
Section titled “Authentication Flow”ByteAuth implements a challenge-response authentication protocol using Bitcoin’s elliptic curve cryptography. This page provides an in-depth look at the protocol, its security properties, and how it compares to other authentication methods.
Core Philosophy
Section titled “Core Philosophy”ByteAuth is built on three fundamental principles:
1. Self-Sovereign Identity
Section titled “1. Self-Sovereign Identity”Users own their cryptographic identity. Unlike centralized authentication providers (Google, Facebook, etc.), ByteAuth ensures:
- No vendor lock-in — Your identity isn’t tied to any company
- True portability — Recover your identity on any device with your seed phrase
- Privacy by design — Each domain gets a unique key pair, preventing cross-site tracking
2. Bitcoin-Grade Security
Section titled “2. Bitcoin-Grade Security”We chose Bitcoin’s cryptographic primitives because they’re the most battle-tested in the world:
- secp256k1 curve — Securing $1+ trillion in Bitcoin value
- ECDSA signatures — Proven secure since Bitcoin’s launch in 2009
- SHA-256 hashing — NSA-designed, cryptographically secure
3. Zero Knowledge
Section titled “3. Zero Knowledge”Your server never sees the user’s private key:
- Private keys are generated on-device and never leave
- Only public keys are shared (they’re public by design)
- Signatures prove identity without revealing secrets
The Protocol
Section titled “The Protocol”Sequence Diagram
Section titled “Sequence Diagram”┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐│ User │ │ Browser │ │ Server │ │ByteVault│└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ Visit login page │ │ │ │───────────────────>│ │ │ │ │ │ │ │ │ Request QR code │ │ │ │───────────────────>│ │ │ │ │ │ │ │ Return QR data │ │ │ │<───────────────────│ │ │ │ │ │ │ Display QR code │ │ │ │<───────────────────│ │ │ │ │ │ │ │ Scan QR │ │ │ │────────────────────────────────────────────────────────────>│ │ │ │ │ │ │ │ Biometric prompt │ │<────────────────────────────────────────────────────────────│ │ │ │ │ │ Confirm identity │ │ │ │────────────────────────────────────────────────────────────>│ │ │ │ │ │ │ │ POST webhook │ │ │ │<───────────────────│ │ │ │ │ │ │ │ Verify signature │ │ │ │────┐ │ │ │ │ │ │ │ │ │<───┘ │ │ │ │ │ │ │ │ 200 OK │ │ │ │───────────────────>│ │ │ │ │ │ │ Poll status │ │ │ │───────────────────>│ │ │ │ │ │ │ │ Authenticated! │ │ │ │<───────────────────│ │ │ │ │ │ │ Redirect to app │ │ │ │<───────────────────│ │ │Step-by-Step Breakdown
Section titled “Step-by-Step Breakdown”-
Session Initialization
When a user visits your login page, the client requests a new session:
GET /api/byteauth/qr?mode=loginResponse: {"sid": "sess_abc123xyz","challenge": "byteauth:login:example.com:1699876543:nonce_abc123","qr": "https://example.com/webhook/login?s=sess_abc123xyz&c=...","expiresAt": 1699876573} -
QR Code Display
The QR code encodes:
- Your webhook URL
- Session identifier
- Cryptographic challenge
- Timestamp
byteauth://auth?webhook=https://example.com/webhook/login&session=sess_abc123xyz&challenge=byteauth:login:example.com:1699876543:nonce_abc123&ts=1699876543 -
ByteVault Processing
When the user scans:
- ByteVault parses the QR data
- Displays your domain name for verification
- Prompts for biometric authentication
- Derives the domain-specific private key
- Signs the challenge with ECDSA/SHA256
-
Webhook Delivery
ByteVault POSTs to your webhook:
{"public_key": "04a1b2c3d4e5f6789...","signature": "3045022100abc123...","challenge": "byteauth:login:example.com:1699876543:nonce_abc123","timestamp": 1699876545,"device_info": {"platform": "ios","version": "2.1.0","device_id": "device_xyz"}} -
Signature Verification
Your server:
- Validates the challenge exists and hasn’t expired
- Verifies the ECDSA signature
- Looks up or creates the user by public key
- Marks the session as authenticated
-
Client Notification
The browser polls for status every 5 seconds:
GET /api/byteauth/check?sid=sess_abc123xyz// When authenticated:Response: {"status": "authenticated","user_id": 12345,"redirect": "/dashboard"}
Challenge Format
Section titled “Challenge Format”Challenges are structured strings that prevent replay attacks:
byteauth:{action}:{domain}:{timestamp}:{nonce}| Component | Description | Example |
|---|---|---|
action | login or register | login |
domain | Your registered domain | example.com |
timestamp | Unix epoch seconds | 1699876543 |
nonce | Random 32-char string | a1b2c3d4e5f6... |
Example:
byteauth:login:example.com:1699876543:a1b2c3d4e5f67890abcdef1234567890Signature Verification
Section titled “Signature Verification”ECDSA signature verification in JavaScript:
import { ec as EC } from 'elliptic';import crypto from 'crypto';
const secp256k1 = new EC('secp256k1');
function verifySignature(publicKeyHex, signatureHex, message) { // Hash the message with SHA-256 const hash = crypto.createHash('sha256').update(message).digest();
// Create key from public key hex const key = secp256k1.keyFromPublic(publicKeyHex, 'hex');
// Verify the signature return key.verify(hash, signatureHex);}Timing Parameters
Section titled “Timing Parameters”| Parameter | Value | Purpose |
|---|---|---|
| Challenge lifetime | 30 seconds | Prevents replay attacks |
| QR refresh interval | 30 seconds | Keeps challenge fresh |
| Session lifetime | Until page reload | Maintains user context |
| Polling interval | 5 seconds | Detects auth quickly |
Security Properties
Section titled “Security Properties”Replay Attack Prevention
Section titled “Replay Attack Prevention”- Challenges include timestamps and random nonces
- Each challenge can only be used once
- Challenges expire after 30 seconds
Phishing Resistance
Section titled “Phishing Resistance”- Private keys never leave the device
- Domain is displayed in ByteVault before signing
- Signatures are domain-bound
Man-in-the-Middle Protection
Section titled “Man-in-the-Middle Protection”- Webhook URL is embedded in QR
- TLS encrypts all communications
- Signature includes domain
Comparison with Other Methods
Section titled “Comparison with Other Methods”vs. Traditional Passwords
Section titled “vs. Traditional Passwords”| Aspect | Passwords | ByteAuth |
|---|---|---|
| Can be phished | Yes | No |
| Can be brute-forced | Yes | No |
| Requires memory | Yes | No |
| Database breach risk | High | None |
| User friction | High | Low |
vs. WebAuthn/Passkeys
Section titled “vs. WebAuthn/Passkeys”| Aspect | WebAuthn | ByteAuth |
|---|---|---|
| Browser support | Required | Not required |
| Cross-device auth | Limited | Native (QR scan) |
| Self-custody | No (tied to platform) | Yes |
| Bitcoin integration | No | Yes |
| Backup/recovery | Platform-dependent | Seed phrase |
vs. LNURL-auth (Lightning)
Section titled “vs. LNURL-auth (Lightning)”| Aspect | LNURL-auth | ByteAuth |
|---|---|---|
| Requires Lightning wallet | Yes | No |
| Network dependency | Lightning network | None |
| Biometric requirement | No | Yes |
| Liveness detection | No | Yes |
| Integrated payments | Lightning only | Multiple |
Error Handling
Section titled “Error Handling”Handle authentication errors appropriately:
| Error | HTTP Code | Action |
|---|---|---|
| Challenge expired | 408 | Refresh QR code |
| Invalid signature | 406 | Reject authentication |
| User not found | 404 | Prompt registration |
| Server error | 500 | Retry with backoff |
Best Practices
Section titled “Best Practices”- Always verify signatures — Never skip cryptographic verification
- Check timestamps — Reject challenges older than 30 seconds
- Use HTTPS — Encrypt all webhook communications
- Log authentication events — Maintain audit trail
- Implement rate limiting — Prevent brute-force attempts
- Handle errors gracefully — Guide users through issues