Add ethers.js and libsodium, document crypto policy
All checks were successful
check / check (push) Successful in 21s
All checks were successful
check / check (push) Successful in 21s
Runtime deps: ethers 6.16.0 (all Ethereum operations) and libsodium-wrappers-sumo 0.8.2 (Argon2id + XSalsa20-Poly1305 for encrypting secrets at rest). README now documents all dependencies with versions/licenses, a crypto policy forbidding raw primitives in application code, and the updated encryption scheme.
This commit is contained in:
79
README.md
79
README.md
@@ -48,22 +48,18 @@ separate output directories.
|
||||
src/
|
||||
background/ — service worker / background script
|
||||
index.js — extension lifecycle, message routing
|
||||
wallet.js — wallet management (create, import, derive)
|
||||
wallet.js — wallet management (create, import, derive via ethers.js)
|
||||
provider.js — EIP-1193 JSON-RPC provider implementation
|
||||
transaction.js — transaction construction and signing
|
||||
popup/ — popup UI (the main wallet interface)
|
||||
index.html
|
||||
index.js
|
||||
components/ — UI components (account list, send form, etc.)
|
||||
styles/ — CSS (Tailwind)
|
||||
content/ — content script injected into web pages
|
||||
index.js — injects the provider into page context
|
||||
inpage.js — the window.ethereum provider object
|
||||
shared/ — shared utilities
|
||||
crypto.js — BIP-39 mnemonic, HD key derivation, signing
|
||||
storage.js — encrypted storage abstraction
|
||||
vault.js — encrypted storage via libsodium
|
||||
constants.js — chain IDs, default RPC endpoints, ERC-20 ABI
|
||||
rpc.js — JSON-RPC client for Ethereum nodes
|
||||
manifest/
|
||||
chrome.json — Manifest V3 for Chrome
|
||||
firefox.json — Manifest V2/V3 for Firefox
|
||||
@@ -197,32 +193,75 @@ What the extension does NOT do:
|
||||
The user's RPC endpoint is the single point of external communication. Users who
|
||||
want maximum privacy can point it at their own Ethereum node.
|
||||
|
||||
### Dependencies
|
||||
|
||||
AutistMask uses two runtime libraries. All cryptographic operations are
|
||||
delegated to these libraries — see the Crypto Policy section below.
|
||||
|
||||
| Package | Version | License | Purpose |
|
||||
| ------------------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ethers` | 6.16.0 | MIT | All Ethereum operations: BIP-39 mnemonic generation/validation, BIP-32/BIP-44 HD key derivation (`m/44'/60'/0'/0/n`), secp256k1 signing, transaction construction, ERC-20 contract interaction, JSON-RPC communication, address derivation (keccak256). |
|
||||
| `libsodium-wrappers-sumo` | 0.8.2 | ISC | Password-based encryption of secrets at rest: Argon2id key derivation (`crypto_pwhash`), authenticated encryption (`crypto_secretbox` / XSalsa20-Poly1305). |
|
||||
|
||||
Dev dependencies (not shipped in extension):
|
||||
|
||||
| Package | Version | License | Purpose |
|
||||
| ------------------ | ------- | ------- | --------------- |
|
||||
| `tailwindcss` | 4.2.1 | MIT | CSS compilation |
|
||||
| `@tailwindcss/cli` | 4.2.1 | MIT | Tailwind CLI |
|
||||
| `jest` | 30.2.0 | MIT | Test runner |
|
||||
| `prettier` | 3.8.1 | MIT | Code formatter |
|
||||
|
||||
### Crypto Policy
|
||||
|
||||
**No raw crypto primitives in application code.** If the strings `aes`, `sha`,
|
||||
`pbkdf`, `hmac`, `encrypt`, `decrypt`, `hash`, `cipher`, `digest`, `sign`
|
||||
(case-insensitive) appear in our own source code (outside of `node_modules/`),
|
||||
it is almost certainly a bug. All cryptographic operations must go through
|
||||
`ethers` or `libsodium-wrappers-sumo`. This policy exists because:
|
||||
|
||||
- Rolling your own crypto is the single most common source of security
|
||||
vulnerabilities in wallet software.
|
||||
- Both libraries are widely audited and battle-tested.
|
||||
- Keeping crypto out of application code makes security review tractable:
|
||||
reviewers only need to verify that we call the libraries correctly, not that
|
||||
we implemented crypto correctly.
|
||||
|
||||
Exceptions require explicit authorization in a code comment referencing this
|
||||
policy.
|
||||
|
||||
### Key Decisions
|
||||
|
||||
- **No framework**: The popup UI is vanilla JS and HTML. The extension is small
|
||||
enough that a framework adds unnecessary complexity and attack surface.
|
||||
- **Encrypted storage**: Recovery phrases and private keys are encrypted at rest
|
||||
in the extension's local storage. The encryption scheme:
|
||||
- The user's password is run through PBKDF2-SHA256 (600,000 iterations) with
|
||||
a random salt to derive a 256-bit encryption key.
|
||||
- The encryption key + a random IV encrypt the secret material using
|
||||
AES-256-GCM.
|
||||
- Stored blob: `{ salt, iv, ciphertext, authTag }`.
|
||||
in the extension's local storage using libsodium. The encryption scheme:
|
||||
- The user's password is run through Argon2id (`crypto_pwhash`) to derive a
|
||||
256-bit encryption key. Argon2id is memory-hard, making GPU/ASIC brute
|
||||
force attacks expensive.
|
||||
- The derived key encrypts the secret material using XSalsa20-Poly1305
|
||||
(`crypto_secretbox`), which provides authenticated encryption (the
|
||||
ciphertext cannot be tampered with without detection).
|
||||
- Stored blob: `{ salt, nonce, ciphertext }` (the auth tag is part of the
|
||||
`crypto_secretbox` output).
|
||||
- **The password is NOT used in address derivation.** It exists solely to
|
||||
protect the recovery phrase / private key on disk. Anyone with the
|
||||
recovery phrase can restore the wallet on any device without this
|
||||
password. This matches MetaMask's behavior.
|
||||
- **BIP-39 / BIP-44**: Standard mnemonic generation and HD key derivation
|
||||
(`m/44'/60'/0'/0/n`) for Ethereum address compatibility. The BIP-39 passphrase
|
||||
is always empty (matching MetaMask and most wallet software). The user's
|
||||
password is completely separate and has no effect on which addresses are
|
||||
generated.
|
||||
- **BIP-39 / BIP-44 via ethers.js**: Mnemonic generation, validation, and HD key
|
||||
derivation (`m/44'/60'/0'/0/n`) are handled entirely by ethers.js. The BIP-39
|
||||
passphrase is always empty (matching MetaMask and most wallet software). The
|
||||
user's password is completely separate and has no effect on which addresses
|
||||
are generated.
|
||||
- **ethers.js for everything Ethereum**: Transaction construction, signing, gas
|
||||
estimation, RPC communication, ERC-20 contract calls, and address derivation
|
||||
are all handled by ethers.js. This means zero hand-rolled Ethereum logic.
|
||||
- **EIP-1193 provider**: The content script injects a `window.ethereum` object
|
||||
that implements the EIP-1193 provider interface, enabling web3 site
|
||||
connectivity.
|
||||
- **Minimal RPC**: The extension communicates with Ethereum nodes via JSON-RPC.
|
||||
The default endpoint is configurable. No Infura dependency — users can point
|
||||
it at any Ethereum JSON-RPC endpoint.
|
||||
- **Minimal RPC**: The extension communicates with Ethereum nodes via JSON-RPC
|
||||
through ethers.js's `JsonRpcProvider`. The default endpoint is configurable.
|
||||
No Infura dependency — users can point it at any Ethereum JSON-RPC endpoint.
|
||||
|
||||
### Supported Functionality
|
||||
|
||||
|
||||
Reference in New Issue
Block a user