Skip to content

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.

ByteAuth is built on three fundamental principles:

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

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

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
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 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 │ │ │
│<───────────────────│ │ │
  1. Session Initialization

    When a user visits your login page, the client requests a new session:

    GET /api/byteauth/qr?mode=login
    Response: {
    "sid": "sess_abc123xyz",
    "challenge": "byteauth:login:example.com:1699876543:nonce_abc123",
    "qr": "https://example.com/webhook/login?s=sess_abc123xyz&c=...",
    "expiresAt": 1699876573
    }
  2. 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
  3. 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
  4. 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"
    }
    }
  5. 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
  6. 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"
    }

Challenges are structured strings that prevent replay attacks:

byteauth:{action}:{domain}:{timestamp}:{nonce}
ComponentDescriptionExample
actionlogin or registerlogin
domainYour registered domainexample.com
timestampUnix epoch seconds1699876543
nonceRandom 32-char stringa1b2c3d4e5f6...

Example:

byteauth:login:example.com:1699876543:a1b2c3d4e5f67890abcdef1234567890

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);
}
ParameterValuePurpose
Challenge lifetime30 secondsPrevents replay attacks
QR refresh interval30 secondsKeeps challenge fresh
Session lifetimeUntil page reloadMaintains user context
Polling interval5 secondsDetects auth quickly
  • Challenges include timestamps and random nonces
  • Each challenge can only be used once
  • Challenges expire after 30 seconds
  • Private keys never leave the device
  • Domain is displayed in ByteVault before signing
  • Signatures are domain-bound
  • Webhook URL is embedded in QR
  • TLS encrypts all communications
  • Signature includes domain
AspectPasswordsByteAuth
Can be phishedYesNo
Can be brute-forcedYesNo
Requires memoryYesNo
Database breach riskHighNone
User frictionHighLow
AspectWebAuthnByteAuth
Browser supportRequiredNot required
Cross-device authLimitedNative (QR scan)
Self-custodyNo (tied to platform)Yes
Bitcoin integrationNoYes
Backup/recoveryPlatform-dependentSeed phrase
AspectLNURL-authByteAuth
Requires Lightning walletYesNo
Network dependencyLightning networkNone
Biometric requirementNoYes
Liveness detectionNoYes
Integrated paymentsLightning onlyMultiple

Handle authentication errors appropriately:

ErrorHTTP CodeAction
Challenge expired408Refresh QR code
Invalid signature406Reject authentication
User not found404Prompt registration
Server error500Retry with backoff
  1. Always verify signatures — Never skip cryptographic verification
  2. Check timestamps — Reject challenges older than 30 seconds
  3. Use HTTPS — Encrypt all webhook communications
  4. Log authentication events — Maintain audit trail
  5. Implement rate limiting — Prevent brute-force attempts
  6. Handle errors gracefully — Guide users through issues