Author SHA1 Message Date
sneak 3486d46998 docs: TODO.md Next Step names open milestone work, not tagging (closes #771)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
Tags and releases are the owner's call; no repo document tells him when
to tag.

Model: opus-5-5
2026-11-11 01:06:11 +00:00
clawbot 02f14143eb docs: TODO.md holds open work only (closes #769)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
Removes the Completed Steps work log and the v0.1.0 tagging date from
Status. Every open item the log mentioned is a tracker issue. The
Workflow bullet that named the removed section now says to record no
finished work in this file.

Model: opus-5-5
2026-11-11 02:04:13 +01:00
clawbot b87c03be11 fix: build hashes and recovery-phrase entropy come from ethers (closes #758)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
build.js and script/lib/package.js hash with sha256 from ethers, with the
0x prefix stripped so the build receipt and SHA256SUMS keep bare lowercase
hex. generateMnemonic() takes its 16 bytes of entropy from randomBytes in
ethers. The README Crypto policy no longer lists these as exceptions.

Model: opus-5-5
2026-11-11 00:42:18 +01:00
6 changed files with 37 additions and 1958 deletions

No files matched your search

+4 -5
View File
@@ -1647,11 +1647,10 @@ The development dependencies ship nowhere:
### Crypto policy
Hashing, key derivation, signing and encryption go through `ethers` or
`libsodium-wrappers-sumo`. No primitive is implemented in this repository. A new
recovery phrase draws its random bytes from the browser's
`crypto.getRandomValues()`. The build tooling, `build.js` and `script/lib/`,
hashes files with Node's `crypto`; none of it ships in the extension.
In the extension, hashing, key derivation, signing and encryption go through
`ethers` or `libsodium-wrappers-sumo`. A new recovery phrase takes its random
bytes from `ethers`. `build.js` and `script/lib/package.js` also hash files with
`ethers`. No primitive is implemented in this repository.
### Content Security Policy
+6 -1938
View File
File diff suppressed because it is too large. Load diff
+3 -5
View File
@@ -1,8 +1,8 @@
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const { execSync } = require("child_process");
const esbuild = require("esbuild");
const { sha256 } = require("ethers");
const { resolveVersion } = require("./script/lib/version");
const {
BACKGROUND_ENTRY_PREFIX,
@@ -314,10 +314,8 @@ function copyIcons(distDir) {
}
function sha256File(absPath) {
return crypto
.createHash("sha256")
.update(fs.readFileSync(absPath))
.digest("hex");
// ethers prefixes the hex with 0x; the receipt holds bare hex.
return sha256(fs.readFileSync(absPath)).slice(2);
}
// Write the receipt for the files this build emitted. Deliberately records no
+9 -3
View File
@@ -25,9 +25,9 @@
"use strict";
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const ethers = require("ethers");
const { readZip, writeZip } = require("./zip");
const { resolveVersion } = require("./version");
@@ -60,8 +60,9 @@ function fail(message) {
throw new Error(message);
}
// Lowercase hex without the 0x prefix ethers adds, as sha256sum prints it.
function sha256(buf) {
return crypto.createHash("sha256").update(buf).digest("hex");
return ethers.sha256(buf).slice(2);
}
// Every regular file under dir, as archive-root-relative forward-slashed
@@ -291,4 +292,9 @@ if (require.main === module) {
}
}
module.exports = { checkSelfContained, htmlReferences, manifestReferences };
module.exports = {
checkSelfContained,
htmlReferences,
manifestReferences,
sha256,
};
+2 -5
View File
@@ -1,7 +1,7 @@
// Wallet operations: mnemonic generation, HD derivation, signing.
// All crypto delegated to ethers.js.
const { Mnemonic, HDNodeWallet, Wallet } = require("ethers");
const { Mnemonic, HDNodeWallet, Wallet, randomBytes } = require("ethers");
const { DEBUG, DEBUG_MNEMONIC, BIP44_ETH_PATH } = require("./constants");
function generateMnemonic() {
@@ -10,10 +10,7 @@ function generateMnemonic() {
// settings toggle drives, which would let a user of a release build turn
// the hardcoded, publicly known test phrase back on for real wallets.
if (DEBUG) return DEBUG_MNEMONIC;
const m = Mnemonic.fromEntropy(
globalThis.crypto.getRandomValues(new Uint8Array(16)),
);
return m.phrase;
return Mnemonic.fromEntropy(randomBytes(16)).phrase;
}
// Every extended key (xprv or xpub) entering the app goes through this.
+13 -2
View File
@@ -1,4 +1,5 @@
// The release archives: the zip container, and the self-containment rule.
// The release archives: the zip container, the self-containment rule, and the
// digest format in release/SHA256SUMS.
//
// script/package produces one archive per browser and script/lib/package.js
// decides what goes in it. The trap that rule exists for is real and specific:
@@ -11,12 +12,14 @@
// So the packager resolves every reference in the manifest and in every HTML
// document, and fails on any that leaves the extension root. These are the
// cases for that, plus the archive format itself — new code, and the thing the
// artifact is made of.
// artifact is made of. One more case checks the digest format in
// release/SHA256SUMS.
const {
checkSelfContained,
htmlReferences,
manifestReferences,
sha256,
} = require("../script/lib/package");
const { readZip, writeZip } = require("../script/lib/zip");
@@ -142,6 +145,14 @@ describe("archive self-containment", () => {
});
});
// release/SHA256SUMS is checked with `sha256sum -c`, which needs the digest
// as bare lowercase hex. The expected value is the FIPS 180-2 digest of "abc".
test("sha256 prints the digest as sha256sum does", () => {
expect(sha256(Buffer.from("abc"))).toBe(
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
);
});
describe("the zip container", () => {
const files = [
{ name: "manifest.json", data: Buffer.from('{"a":1}') },