chore(hash): the synchronous SHA-256 is @noble/hashes, not hand-written code of unrecorded origin - #317
Merged
Conversation
…en code of unrecorded origin Part of #301, the second step. The pure-JS SHA-256 in src/model/workspace.ts (sha256Js) cites only FIPS 180-4, and the repository's record does not say where its text came from, so it could not be listed with a notice. It is not just a fallback: the synchronous revision and proposal digest (digestOfCanonical, 17 product call sites) always uses it. It is replaced by @noble/hashes 2.4.0 (MIT, no dependencies), which gives the same bytes. - package.json: "@noble/hashes": "2.4.0", exact. The lockfile gains that one package and nothing else. - src/model/workspace.ts: sha256Js keeps its name and synchronous signature; its body is toHex(sha256(bytes)) with sha256 imported from '@noble/hashes/sha2.js'. sha256Hex still uses Web Crypto first. fullContentDigest is left as it is. - The digests are byte-identical. src/model/sha256Baseline.fixture.ts was recorded with the replaced code on main 44af9a4, before the change: 205 hash vectors (every length 0 to 200, and 1,000 to 1 MiB) and the 4 published vectors, the semantic, content and full-content digests of the 12 example diagrams, and what the import layer's reader makes of the 8 example revision and proposal files. sha256Baseline.test.ts checks all of it against the new code, and against Web Crypto, and with Web Crypto removed. - check:share-crypto keeps "no cryptography library" with one narrow exception, held in scripts/share-crypto-noble.mjs and tested on 38 made-up cases: exactly @noble/hashes 2.4.0 in dependencies, one copy in the lockfile with no dependencies, one importer (src/model/workspace.ts), one path ('@noble/hashes/sha2.js'), one name (sha256); no other product file, unit test, end-to-end spec or script may import it; and src/model/shareProtected.ts may not reach it, the workspace or revision hashes, directly or through another module, nor name those functions. The Web-Crypto-only checks on protected links are unchanged. - The specs' requirement of a bundled pure-JS SHA-256 is still met, so they are unchanged. - Declared internal; the version stays 0.17.1 and there is no release note. Bundle: +3,731 bytes of JavaScript (+1,444 gzipped) in the web and PWA builds, +3,847 bytes in the portable file. Bundled modules of the package: sha2.js, _md.js, _u64.js and utils.js.
Deploying cozy-loop-studio with
|
| Latest commit: |
c463c62
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d6d5613a.cozy-loop-studio.pages.dev |
| Branch Preview URL: | https://chore-sha256-noble.cozy-loop-studio.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #301 — the second step, after decision 1 (#316).
Why
The pure-JS SHA-256 in
src/model/workspace.ts(sha256Js) cites only FIPS 180-4, and the repository's record does not say where its text came from, so it could not go into the notice list. It is not only a fallback: the synchronous revision and proposal digest (digestOfCanonical, 17 product call sites) always uses it, whether or not the page has Web Crypto. Removing it would mean making the revision pipeline asynchronous, so it is replaced instead by@noble/hashes(MIT, no dependencies), which gives the same bytes.What changes
package.json:"@noble/hashes": "2.4.0", exact. The lockfile gains that one package and nothing else.src/model/workspace.ts:sha256Jskeeps its name and its synchronous signature; its body becomestoHex(sha256(bytes)), withsha256imported from@noble/hashes/sha2.js.sha256Hexstill uses Web Crypto first and falls back to it.fullContentDigestis left unchanged.check:share-cryptokeeps "no cryptography library" with one narrow exception (below).docs/specs/SEMANTICS-W.mdandSEMANTICS-R.mdrequire a bundled pure-JS SHA-256 fallback;@noble/hashesis one, so they are unchanged.internal: the version stays 0.17.1 and there is no release note. Nothing a person sees or stores changes.The digests are byte-identical
src/model/sha256Baseline.fixture.tswas recorded with the replaced code onmainat44af9a4, before the change, andsrc/model/sha256Baseline.test.tschecks all of it against the new code:The same values are checked through Web Crypto, and with Web Crypto removed. A deliberately wrong hash fails 22 of these 25 tests.
The exception in
check:share-cryptoHeld in
scripts/share-crypto-noble.mjsand tested on 38 made-up cases inscripts/share-crypto-noble.test.mjs:package.jsonmay name exactly@noble/hashes2.4.0, independencies; any other version, range or field fails, and every other cryptography-looking package still fails.@noble/*package,@noble/hashesat 2.4.0, with no dependencies.src/model/workspace.ts, asimport { sha256 } from '@noble/hashes/sha2.js'. Another path, another or an additional name, a namespace or default import, a re-export or a dynamic import fails, and so does an import from any other product file, unit test, end-to-end spec or script.src/model/shareProtected.tsmay not reach@noble/hashes,src/model/workspace.tsorsrc/model/revision.ts, directly or through another module, and may not name their hash functions. The existing Web-Crypto-only checks on protected links are unchanged.Run against a deliberate violation (
shareProtected.tsimporting the workspace wrapper), the real check fails on all three counts.Measured
sha2.js,_md.js,_u64.jsandutils.js.http://192.0.2.10/, where the browser exposes nocrypto.subtle), with the dev build in Chromium: a revision file imported through the toolbar opens with its stored digest verified, a proposal applies, and both graph digests equal the committed verification oracle; in the page, 20 hash vectors and the 12 example diagrams match the baseline.Verification (local)
npx tsc -b, oxlint (39 warnings, the existing baseline), 3,028 unit tests and all check scripts pass; the web, PWA and portable builds succeed.Not in this pull request
fullContentDigesthas no product caller; removing it is a separate candidate.