Rust and WASM did-method-plc tools and structures
1# plc-audit WASM Implementation 2 3This is a JavaScript implementation of the `plc-audit` binary that uses WebAssembly for cryptographic operations. It fetches and validates DID audit logs from plc.directory. 4 5## Prerequisites 6 7- **Rust** (stable toolchain) 8- **wasm-pack** - Install with: `cargo install wasm-pack` 9- **Node.js** (v18 or later) - For running the JavaScript tool 10 11## Building 12 13### 1. Build the WASM Module 14 15From the project root directory: 16 17```bash 18# Build WASM module with wasm feature 19wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm 20 21# Or use the provided build script 22./wasm/build.sh 23``` 24 25This will: 26- Compile the Rust library to WebAssembly 27- Generate JavaScript bindings 28- Create a `wasm/pkg/` directory with the WASM module and TypeScript definitions 29 30### 2. Install Node.js Dependencies 31 32```bash 33cd wasm 34npm install 35``` 36 37## Usage 38 39The JavaScript version supports the same command-line interface as the Rust binary: 40 41### Basic Validation 42 43Validate a DID and show detailed output: 44 45```bash 46node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur 47``` 48 49### Verbose Mode 50 51Show all operations and detailed cryptographic validation steps: 52 53```bash 54node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur --verbose 55# or 56node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur -v 57``` 58 59Output includes: 60- Operation index and CID 61- Creation timestamp 62- Operation type (Genesis/Update) 63- Previous operation reference 64- Step-by-step chain linkage validation 65- Detailed signature verification with rotation key tracking 66 67### Quiet Mode 68 69Only show validation result (useful for scripts): 70 71```bash 72node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur --quiet 73# or 74node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur -q 75``` 76 77Output: `✅ VALID` or error message 78 79### Custom PLC Directory 80 81Use a custom PLC directory server: 82 83```bash 84node plc-audit.js did:plc:example --plc-url https://custom.plc.directory 85``` 86 87## What is Validated? 88 89The WASM version performs the same comprehensive validation as the Rust binary: 90 911. **DID Format Validation** 92 - Checks prefix is `did:plc:` 93 - Verifies identifier is exactly 24 characters 94 - Ensures only valid base32 characters (a-z, 2-7) 95 962. **Chain Linkage Verification** 97 - First operation must be genesis (prev = null) 98 - Each subsequent operation's `prev` field must match previous operation's CID 99 - No breaks in the chain 100 1013. **Cryptographic Signature Verification** 102 - Each operation's signature is verified using rotation keys 103 - Genesis operation establishes initial rotation keys 104 - Later operations can rotate keys 105 - Identifies which specific rotation key verified each signature 106 107## Example Output 108 109### Standard Mode 110 111``` 112🔍 Fetching audit log for: did:plc:z72i7hdynmk6r22z27h6tvur 113 Source: https://plc.directory 114 115📊 Audit Log Summary: 116 Total operations: 4 117 Genesis operation: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm 118 Latest operation: bafyreifn4pkect7nymne3sxkdg7tn7534msyxcjkshmzqtijmn3enyxm3q 119 120🔐 Validating operation chain... 121✅ Validation successful! 122 123📄 Final DID State: 124 Rotation keys: 2 125 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg 126 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK 127``` 128 129### Verbose Mode 130 131Shows detailed step-by-step validation: 132 133``` 134Step 1: Chain Linkage Validation 135================================ 136 [1] Checking prev reference... 137 Expected: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm 138 Actual: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm 139 ✅ Match - chain link valid 140 [2] Checking prev reference... 141 Expected: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq 142 Actual: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq 143 ✅ Match - chain link valid 144 ... 145 146✅ Chain linkage validation complete 147 148Step 2: Cryptographic Signature Validation 149========================================== 150 [0] Genesis operation - extracting rotation keys 151 Rotation keys: 2 152 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg 153 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK 154 ⚠️ Genesis signature cannot be verified (bootstrapping trust) 155 [1] Validating signature... 156 CID: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq 157 Signature: 1mEWzRtFOgeRXH-YCSPTxb990JOXxa__n8Qw6BOKl7Ndm6OFFmwYKiiMqMCpAbxpnGjF5abfIsKc7u3a77Cbnw 158 Available rotation keys: 2 159 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg 160 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK 161 Parsed verifying keys: 2/2 162 ✅ Signature verified with rotation key [1] 163 did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK 164 ... 165 166✅ Cryptographic signature validation complete 167``` 168 169## Architecture 170 171The WASM implementation divides responsibilities: 172 173- **JavaScript** (`plc-audit.js`): 174 - Command-line argument parsing 175 - HTTP requests to plc.directory 176 - Console output formatting 177 - Control flow and orchestration 178 179- **WASM** (Rust compiled to WebAssembly): 180 - DID parsing and validation 181 - Operation parsing from JSON 182 - Cryptographic signature verification (P-256 and secp256k1) 183 - Rotation key management 184 - All security-critical operations 185 186## Performance 187 188The WASM version has comparable performance to the native Rust binary: 189 190- **WASM module size**: ~200KB (optimized) 191- **Validation time**: ~200-500ms for typical DIDs (4-10 operations) 192- **Startup overhead**: ~50-100ms for WASM initialization 193 194## Troubleshooting 195 196### Build Errors 197 198If you encounter build errors: 199 200```bash 201# Ensure wasm32-unknown-unknown target is installed 202rustup target add wasm32-unknown-unknown 203 204# Clean and rebuild 205rm -rf wasm/pkg 206wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm 207``` 208 209### Runtime Errors 210 211If you get "Module not found" errors: 212 213```bash 214# Ensure the WASM module is built 215ls wasm/pkg/atproto_plc_bg.wasm 216 217# If missing, rebuild 218wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm 219``` 220 221### Node.js Version 222 223Ensure you're using Node.js v18 or later: 224 225```bash 226node --version # Should be v18.0.0 or higher 227``` 228 229## Comparison with Rust Binary 230 231| Feature | Rust Binary | WASM/JavaScript | 232|---------|-------------|-----------------| 233| Performance | Native speed | ~2-3x slower | 234| Binary Size | 1.5MB | ~200KB WASM | 235| Dependencies | None (static) | Node.js runtime | 236| Platform | Per-platform compilation | Universal (runs anywhere with Node.js) | 237| Use Case | Production servers, CLI | Cross-platform, web integration | 238 239## Integration Examples 240 241### Use in a Node.js Application 242 243```javascript 244import { WasmDid, WasmOperation, WasmVerifyingKey } from './pkg/atproto_plc.js'; 245 246async function validateDid(didString) { 247 // Parse DID 248 const did = WasmDid.parse(didString); 249 250 // Fetch audit log 251 const response = await fetch(`https://plc.directory/${did.did}/log/audit`); 252 const auditLog = await response.json(); 253 254 // Parse operations 255 const operations = auditLog.map(entry => ({ 256 operation: WasmOperation.fromJson(JSON.stringify(entry.operation)), 257 cid: entry.cid, 258 })); 259 260 // Validate chain 261 for (let i = 1; i < operations.length; i++) { 262 const prev = operations[i].operation.prev(); 263 if (prev !== operations[i - 1].cid) { 264 throw new Error('Chain linkage broken'); 265 } 266 } 267 268 return true; 269} 270``` 271 272### Use in Browser (with bundler) 273 274```javascript 275// Build with web target instead 276// wasm-pack build --target web --out-dir wasm/pkg --features wasm 277 278import init, { WasmDid } from './pkg/atproto_plc.js'; 279 280await init(); // Initialize WASM 281 282const did = WasmDid.parse('did:plc:ewvi7nxzyoun6zhxrhs64oiz'); 283console.log('Valid DID:', did.did); 284``` 285 286## License 287 288Dual-licensed under MIT or Apache-2.0, same as the parent library.