pqid-sdk
v0.1.2
Published
PQID SDK - Complete quantum-resistant authentication for web applications
Readme
PQID SDK
Quantum-Resistant Authentication for Web Applications
PQID SDK provides Dilithium ML-DSA-65 (NIST FIPS 204) post-quantum cryptography for secure, future-proof user authentication. Built for the quantum computing era, it protects long-lived sensitive data from both current and future cryptographic threats.
⚛️ Quantum Resistance First
Key Sizes (Quantum-Safe)
- Public Key: 1,952 bytes (vs 32 bytes for Ed25519)
- Private Key: 4,032 bytes (vs 32 bytes for Ed25519)
- Signature: 3,309 bytes (vs 64 bytes for Ed25519)
Algorithm: Dilithium ML-DSA-65
- NIST FIPS 204 compliant post-quantum signatures
- Immune to Shor's algorithm (quantum factoring attacks)
- Protected against Grover's algorithm via AES-256-GCM
- Future-proof against harvest-now/decrypt-later attacks
⚠️ Development Status
Current Status: Alpha - Core PQ functionality working
- ✅ Dilithium ML-DSA-65 quantum-resistant signatures fully implemented
- ✅ Deterministic identity generation and recovery
- ✅ OAuth credential verification (GitHub, Google, Apple)
- ✅ DID ownership proofs for secure credential association
- ⚠️ API Stability - Expect refinements before v1.0
- ⚠️ Performance - PQ operations are intentionally slower for security
Installation
npm install pqid-sdk
# or
pnpm add pqid-sdkDevelopment Setup
# Clone and setup
git clone <repository>
cd pqid-sdk
npm install
npm run build
npm test🚀 Quick Start
Browser Integration
The SDK automatically detects your environment and uses the best available authentication method:
import { requestAuth } from "pqid-sdk/browser";
async function authenticateUser() {
try {
const bundle = await requestAuth({
requested_claims: [
{ type: "age_over_18", purpose: "Verify adult content access" },
{ type: "good_standing", purpose: "Account status check" }
],
challenge: "your-server-challenge", // From your backend
audience: "https://yourapp.com"
});
// Send to your backend for verification
const response = await fetch("/api/auth/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(bundle)
});
const result = await response.json();
console.log("User authenticated:", result.did);
console.log("Verified claims:", result.claims);
} catch (error) {
console.error("Authentication failed:", error);
}
}SDK Environment Detection
The SDK automatically chooses the best authentication method:
🔌 PQID Wallet Extension (Production Recommended)
- Detection: Automatically detects
window.pqidextension API - Features: Full quantum-resistant wallet with secure key storage
- Fallback: Falls back to development wallet if extension unavailable
🧪 Development Wallet (Testing)
- Usage: Built-in wallet when extension not detected
- Algorithm: Dilithium ML-DSA-65 (same as production)
- Warning: Console warning when using development mode
🖥️ Server-Side (Testing)
- Usage: Node.js/test environments
- Features:
createTestAuthBundle()for automated testing
Server: Backend Verification
Critical Security: Never trust client-provided authentication data without server-side verification.
import { verifyAssertion, verifyCredentials } from "pqid-sdk/server";
app.post("/api/auth/verify", async (req, res) => {
const bundle = req.body;
// Step 1: Verify user identity (Dilithium signature validation)
const assertionResult = await verifyAssertion(bundle);
if (!assertionResult.ok) {
return res.status(401).json({ error: assertionResult.error });
}
// Step 2: Verify credentials from trusted issuers
const credentialResult = await verifyCredentials(bundle.credentials, {
trustedIssuers: ["did:pqid-issuer:main"], // Your trusted PQID issuers
expectedSubjectDid: assertionResult.did // Must match authenticated user
// issuerPublicKeys: optional for self-issued credentials
});
if (!credentialResult.ok) {
return res.status(401).json({
error: "invalid_credentials",
details: credentialResult.errors
});
}
// Success - establish authenticated session
req.session.did = assertionResult.did;
req.session.claims = credentialResult.claims;
res.json({
success: true,
did: assertionResult.did,
claims: credentialResult.claims
});
});🎫 Credential Types & Verification
Self-Issued Credentials
Users can create self-issued credentials signed with their own Dilithium keys:
// Accept self-issued credentials
const result = await verifyCredentials(bundle.credentials, {
trustedIssuers: [assertionResult.did], // Trust user's own DID
expectedSubjectDid: assertionResult.did
// No issuerPublicKeys needed - extracted from DID document
});Security Note: Self-issued credentials provide user-controlled claims but require application-specific trust evaluation.
OAuth-Derived Credentials
Third-party verification via OAuth providers (GitHub, Google, Apple):
// Verify OAuth credentials from PQID issuer
const result = await verifyCredentials(oauthCredentials, {
trustedIssuers: ['did:pqid-issuer:main'], // PQID issuer DID
expectedSubjectDid: userDID
});
// Access OAuth-verified claims
if (result.claims.email_verified) {
// Email ownership confirmed via OAuth
}
if (result.claims.github_account_age_over_180) {
// GitHub account >180 days old
}
if (result.claims.human_user) {
// Human interaction verified
}Supported Claim Types
| Claim Type | Description | Issuer |
|------------|-------------|---------|
| age_over_18 | Age verification | Self-issued or third-party |
| good_standing | Account status | Self-issued or third-party |
| email_verified | Email ownership | OAuth providers |
| github_account_age_over_180 | GitHub account age | PQID issuer via GitHub OAuth |
| google_account_age_over_365 | Google account age | PQID issuer via Google OAuth |
| apple_user | Apple user verification | PQID issuer via Apple Sign-In |
| human_user | Human interaction verified | OAuth providers |
Verification APIs
verifyAssertion(bundle)
Validates user identity and Dilithium signatures:
const result = await verifyAssertion(bundle);
// Returns: { ok: boolean, did?: string, error?: string }- ✅ Dilithium signature verification
- ✅ DID document validation
- ✅ 2-minute timestamp window
- ✅ Challenge/audience matching
verifyCredentials(credentials, options)
Validates credential authenticity:
const result = await verifyCredentials(credentials, {
trustedIssuers: ['did:pqid-issuer:main'],
expectedSubjectDid: userDID,
issuerPublicKeys?: { [issuerDID]: publicKeyBase64 } // Optional
});
// Returns: { ok: boolean, claims: {...}, errors: [...] }- ✅ Issuer trust validation
- ✅ Dilithium signature verification
- ✅ Expiration checking
- ✅ Subject DID matching
🛡️ Security Architecture
Quantum-Resistant Cryptography
- Algorithm: Dilithium ML-DSA-65 (NIST FIPS 204)
- Protection: Immune to Shor's algorithm (quantum factoring)
- Key Security: AES-256-GCM protects against Grover's algorithm
- Future-Proof: Prevents harvest-now/decrypt-later attacks
Trust Model
Client (Browser/Wallet)
- ✅ Generates Dilithium keypairs for quantum resistance
- ✅ Derives DID:
did:pqid:<base64url(publicKey)> - ✅ Signs assertions with Dilithium private keys
- ✅ Self-issues credentials or requests from trusted issuers
- ✅ User controls exactly which claims are shared
Server (Your Backend)
- ✅ MUST verify assertions with
verifyAssertion() - ✅ MUST verify credentials with
verifyCredentials() - ✅ MUST maintain trusted issuer whitelist
- ✅ MUST reject assertions >2 minutes old
- ✅ MUST validate server-generated challenges
Issuer (PQID Issuer Service)
- ✅ Issues Dilithium-signed verifiable credentials
- ✅ Provides OAuth-based third-party verification
- ✅ Supports credential revocation
- ✅ Discoverable via
.well-known/pqid-issuer.json
📊 Performance & Protocol Details
Dilithium ML-DSA-65 Performance
- Key Generation: ~100-200ms (intentionally slower for security)
- Signature Creation: ~50-100ms with 3.3KB output
- Signature Verification: Fast validation of PQ signatures
- Memory Usage: ~4KB per keypair (larger than classical crypto)
Protocol Specification
Version: pqid-auth-0.1.3
- Compatibility: Future versions increment for breaking changes
- Canonicalization: Fields sorted alphabetically before signing
- Timestamp Window: 2-minute validity for assertions
- Challenge Validity: Server-generated, single-use challenges
Credential Lifecycle
- Format: PQ-signed verifiable credentials (VC)
- Expiration:
validUntilfield (ISO 8601) - Default Lifetime: 24 hours (configurable)
- Revocation: Supported via issuer service
Authentication Flow
[Client] → requestAuth(requested_claims, challenge, audience)
↓
[Wallet] Generate Dilithium keys → Sign assertion → Create bundle
↓
[Server] verifyAssertion(bundle) → verifyCredentials(credentials)
↓
[Server] Validate challenge → Extract claims → Authenticate userReplay Protection
- ✅ Unique Challenges: Server generates per-request challenges
- ✅ Single Use: Challenges invalidated after verification
- ✅ Time Windows: 2-minute assertion validity
- ✅ Challenge Matching: Server validates challenge integrity
⚠️ Known Limitations
Alpha Software Considerations
- API Stability: Expect refinements before v1.0
- Production Testing: Thorough testing recommended before production use
- Documentation: May not cover all edge cases
Technical Limitations
- Large Signatures: 3.3KB vs 64 bytes (Ed25519) - expected for PQ security
- Key Storage: Browser wallets require secure storage solutions
- WebAssembly: Required for PQ crypto operations (modern browsers only)
- Performance: PQ operations intentionally slower than classical crypto
Missing Features (Planned)
- Credential Revocation: Real-time revocation checking
- Key Rotation: Automated key rotation workflows
- Backup/Recovery: Standardized wallet backup formats
- Multi-Device: Cross-device key synchronization
🔧 API Reference
Browser APIs
requestAuth(options: RequestAuthOptions): Promise<AuthResponseBundle>
Automatically detects environment and requests user authentication.
interface RequestAuthOptions {
requested_claims: RequestedClaim[]; // Required: claims to request
challenge?: string; // Optional: server challenge
audience?: string; // Optional: expected audience
purpose?: string; // Optional: authentication purpose
}
interface RequestedClaim {
type: ClaimType; // Claim type (age_over_18, email_verified, etc.)
purpose?: string; // Human-readable purpose
}Returns: Complete authentication bundle with Dilithium signatures.
Environment Detection
- Extension Present: Uses
window.pqid.requestAuth() - Extension Missing: Falls back to development wallet (with console warning)
- Server/Test: Uses
createTestAuthBundle()for testing
Server APIs
verifyAssertion(bundle: AuthResponseBundle): Promise<AssertionVerificationResult>
Verifies user identity and Dilithium signature authenticity.
interface AssertionVerificationResult {
ok: boolean;
did?: string; // User's DID if verification successful
error?: string; // Error message if verification failed
}Validates:
- ✅ Dilithium signature on assertion
- ✅ DID document structure and keys
- ✅ Timestamp within 2-minute window
- ✅ Challenge/audience matching
verifyCredentials(credentials: Credential[], options: VerifyCredentialsOptions): Promise<CredentialVerificationResult>
Verifies credential authenticity and extracts claims.
interface VerifyCredentialsOptions {
trustedIssuers: string[]; // Required: trusted issuer DIDs
expectedSubjectDid: string; // Required: expected subject DID
now?: Date; // Optional: current time (for testing)
issuerPublicKeys?: Record<string, string>; // Optional: custom issuer keys
}
interface CredentialVerificationResult {
ok: boolean;
claims: Record<string, any>; // Extracted claims
errors: CredentialVerificationError[]; // Any validation errors
}Validates:
- ✅ Issuer in trust list (or wildcard "*" for development)
- ✅ Dilithium signature verification
- ✅ Credential expiration
- ✅ Subject DID matching
Development & Testing APIs
createDevelopmentWallet(opts?): Promise<ServerWalletState>
Creates a server-side wallet for testing (uses Dilithium keys).
createTestAuthBundle(wallet, claims, opts?): Promise<AuthResponseBundle>
Generates test authentication bundles for automated testing.
getWalletState(): Promise<InternalWalletState>
Returns current development wallet state (browser only).
🧪 Testing
# Install dependencies
npm install
# Run test suite
npm test
# Build for distribution
npm run buildCurrent Status: Tests validate Dilithium crypto operations and authentication flows.
Coverage:
- ✅ Dilithium key generation and signing
- ✅ PQ credential verification
- ✅ DID document validation
- ✅ Authentication bundle creation
- ✅ Server-side verification workflows
🤝 Contributing
We welcome contributions to the PQID SDK! This is a critical security project protecting data from quantum threats.
Development Guidelines
- Security First: All changes must maintain quantum resistance
- Test Coverage: Add comprehensive tests for new features
- Documentation: Update README and inline docs for API changes
- Breaking Changes: Discuss in issues before implementing
- Code Style: Follow existing TypeScript patterns and security practices
Development Workflow
# Fork and clone
git clone https://github.com/your-org/pqid-sdk.git
cd pqid-sdk
# Install dependencies
npm install
# Run tests continuously during development
npm run dev
# Build and test before committing
npm run build
npm test
# Ensure Dilithium crypto operations work correctlySecurity Considerations
- Cryptography: Only NIST-approved post-quantum algorithms
- Key Handling: Never log or expose private keys
- Input Validation: Validate all inputs to prevent injection attacks
- Timing Attacks: Use constant-time operations where applicable
Reporting Issues
- Security Issues: Report privately to [email protected] (DO NOT open public issues)
- Bugs: Include reproduction steps and environment details
- Features: Describe use case and security implications
🗺️ Roadmap
Phase 1: Core PQ Infrastructure ✅
- ✅ Dilithium ML-DSA-65 implementation
- ✅ Basic authentication flows
- ✅ Self-issued credentials
- ✅ OAuth credential verification
Phase 2: Advanced Features (In Progress)
- 🚧 ZK Proofs: Zero-knowledge credential proofs
- 🚧 Personhood Blending: Multi-OAuth provider verification
- 🚧 Enhanced Recovery: Advanced wallet backup/restore
- 🚧 Key Rotation: Automated key lifecycle management
Phase 3: Production Readiness
- 📋 Performance Optimization: Faster PQ operations
- 📋 Enterprise Features: Audit logging, compliance tools
- 📋 Multi-Device Sync: Cross-device key management
- 📋 Revocation Checking: Real-time credential status
Phase 4: Ecosystem Expansion
- 📋 Additional PQ Algorithms: Kyber for key exchange
- 📋 React Hooks: Developer-friendly React integration
- 📋 Mobile Support: React Native implementation
- 📋 Enterprise Integration: SAML/OAuth bridges
📜 License
MIT License - See LICENSE file for details
🆘 Support & Resources
Documentation
- API Reference: This README and inline TypeScript types
- Architecture: See PQID repository for system documentation
- Examples: Check test files for usage patterns
Community
- Issues: GitHub Issues
- Discussions: Use GitHub Discussions for questions
- Security: Report privately to [email protected]
Related Projects
- PQID Wallet: Chrome extension with secure key storage
- PQID Issuer: Credential issuance service
- CIVIC DAO: Example application using PQID authentication
Built for the quantum computing era. Protecting long-lived sensitive data from future threats. ⚛️🛡️
