You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Architecture.md
+16-15Lines changed: 16 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,8 +16,8 @@ LazorKit is a high-performance smart wallet on Solana with passkey (WebAuthn) au
16
16
17
17
### Replay Protection
18
18
19
-
-**Secp256r1 (Primary: Odometer Counter)**: Program-controlled u64 counter per authority. Client submits `stored_counter + 1`. The WebAuthn hardware counter is intentionally NOT used -- synced passkeys (iCloud, Google) return unreliable values. Counter is committed only after successful signature verification.
20
-
-**Secp256r1 (Secondary: SlotHashes Liveness)**: Slot from auth_payload must appear in SlotHashes sysvar (valid within 150 slots). Provides freshness without stateful nonces.
19
+
-**Secp256r1 (Primary: Odometer Counter)**: Program-controlled u32 counter per authority. Client submits `stored_counter + 1`. The WebAuthn hardware counter is intentionally NOT used -- synced passkeys (iCloud, Google) return unreliable values. Counter is committed only after successful signature verification.
20
+
-**Secp256r1 (Secondary: Clock-based Slot Freshness)**: Slot from auth_payload must be within 150 slots of `Clock::get()`. Provides freshness without stateful nonces or the SlotHashes sysvar.
21
21
-**Secp256r1 (CPI Protection)**: stack_height check prevents authentication via CPI.
22
22
-**Secp256r1 (Signature Binding)**: Challenge hash binds signature to specific instruction, payer, accounts, counter, and program_id.
23
23
-**Ed25519**: Standard Solana runtime signer verification. No counter needed.
- Session Execute is cheaper — only 1 instruction, no precompile, no auth payload
24
+
- Session Execute is cheaper -- only 1 instruction, no precompile, no auth payload
25
25
- All operations fit well within Solana's 200,000 CU default budget
26
26
- Transaction sizes are well within Solana's 1,232-byte limit
27
27
28
28
---
29
29
30
+
## Transaction Size Optimization (v2)
31
+
32
+
The Secp256r1 Execute transaction was optimized from **708 bytes to 658 bytes** (50 bytes saved) via three changes:
33
+
34
+
| Optimization | Bytes Saved | Details |
35
+
|---|---|---|
36
+
| Drop SlotHashes sysvar |~32 bytes | Use `Clock::get()` for slot freshness instead of SlotHashes sysvar lookup. Removes 1 account from the transaction. |
37
+
| u32 counter (was u64) |~4 bytes | 4 billion operations per authority is sufficient. Saves 4 bytes in auth payload + 4 bytes in challenge hash. |
38
+
| rpId stored on-chain |~14 bytes | rpId (e.g. "example.com") stored on authority account at creation time, no longer sent per-tx. |
39
+
40
+
**Security impact:** None. The odometer counter remains the primary replay protection. Slot freshness via `Clock::get()` provides the same age check (150-slot window) without requiring the SlotHashes sysvar account.
41
+
42
+
---
43
+
30
44
## LazorKit vs Normal SOL Transfer
31
45
32
46
| Metric | Normal Transfer | LazorKit Secp256r1 | LazorKit Session | Notes |
33
47
|---|---|---|---|---|
34
-
| Compute Units | 150 |9,316|7,483 | Session uses Ed25519 signer (no precompile) |
35
-
| Transaction Size | 215 bytes |708 bytes | 452 bytes | Session tx is smaller (no precompile ix) |
36
-
| Instruction Data | 12 bytes |271 bytes | 20 bytes | Session has no auth payload |
0 commit comments