aboutsummaryrefslogtreecommitdiffstats
path: root/src/wallet.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-17 11:16:25 -0700
committerAdam Soltys <[email protected]>2026-08-17 11:16:25 -0700
commit6a78f8fefe71e636c847e1402b08b1d60483565b (patch)
tree4e4684c6e395fe5f00d68a089b34749f09b2c3b5 /src/wallet.js
parentf9b0a054f822fc6a28fafd623ac2ebd2d274334d (diff)
downloadcoinosv3-6a78f8fefe71e636c847e1402b08b1d60483565b.tar.gz
coinosv3-6a78f8fefe71e636c847e1402b08b1d60483565b.zip
Own entropy means owned outcome: the typed text alone derives the seed, so re-typing it is an import on any device — the warn-box says what that guarantee costs, and Regenerate bows out of a deterministic job
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
Diffstat (limited to 'src/wallet.js')
-rw-r--r--src/wallet.js15
1 files changed, 7 insertions, 8 deletions
diff --git a/src/wallet.js b/src/wallet.js
index 2ede69d..cdae1ff 100644
--- a/src/wallet.js
+++ b/src/wallet.js
@@ -66,14 +66,13 @@ export const NETS = {
export function newMnemonic(strengthBits = 128, extraEntropy = '') {
if (!extraEntropy) return generateMnemonic(wordlist, strengthBits);
- // User entropy is MIXED with the CSPRNG, never used alone: hashing the two
- // together can only add randomness — weak dice can't weaken the seed, and
- // a distrusted device RNG can't fully determine it either.
- const txt = new TextEncoder().encode(extraEntropy);
- const rnd = crypto.getRandomValues(new Uint8Array(strengthBits / 8));
- const mix = new Uint8Array(txt.length + rnd.length);
- mix.set(txt); mix.set(rnd, txt.length);
- return entropyToMnemonic(sha256(mix).slice(0, strengthBits / 8), wordlist);
+ // User entropy is used ALONE, deterministically: seed = BIP-39 from
+ // SHA-256 of exactly the typed text. The same text recreates the same
+ // wallet on any device (that's the point — it doubles as an import), and
+ // the derivation is simple enough to verify elsewhere. The flip side —
+ // guessable text is stealable money — is the UI's warning to give.
+ const digest = sha256(new TextEncoder().encode(extraEntropy));
+ return entropyToMnemonic(digest.slice(0, strengthBits / 8), wordlist);
}
// The base localStorage cache key for a wallet identity (xpub, xprv, or