From debc9566cce21f5cfb5c06df98aff63346135a5d Mon Sep 17 00:00:00 2001 From: w3irdrobot Date: Fri, 10 Mar 2023 14:02:43 -0500 Subject: [PATCH] Add nip06 private key generation --- packages/app/package.json | 2 ++ packages/app/src/Const.ts | 5 +++++ packages/app/src/Pages/Login.tsx | 19 +++++++++++++--- packages/app/src/Pages/new/NewUserFlow.tsx | 8 +++++-- packages/app/src/Pages/new/messages.ts | 1 + packages/app/src/State/Login.ts | 19 ++++++++++++---- packages/app/src/Util.ts | 10 +++++++++ packages/app/src/lang.json | 21 +++++++++++++++++ packages/app/src/translations/en.json | 7 ++++++ yarn.lock | 26 ++++++++++++++++++++-- 10 files changed, 107 insertions(+), 11 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 5c2f67bf..2606fa5f 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -12,6 +12,8 @@ "@noble/secp256k1": "^1.7.0", "@protobufjs/base64": "^1.1.2", "@reduxjs/toolkit": "^1.9.1", + "@scure/bip32": "^1.1.5", + "@scure/bip39": "^1.1.1", "@snort/nostr": "^1.0.0", "@szhsin/react-menu": "^3.3.1", "base32-decode": "^1.0.0", diff --git a/packages/app/src/Const.ts b/packages/app/src/Const.ts index 738f8fbd..9ac753e7 100644 --- a/packages/app/src/Const.ts +++ b/packages/app/src/Const.ts @@ -85,6 +85,11 @@ export const ZapperSpam = [ "e1ff3bfdd4e40315959b08b4fcc8245eaa514637e1d4ec2ae166b743341be1af", // benthecarman ]; +/** + * NIP06-defined derivation path for private keys + */ +export const DerivationPath = "m/44'/1237'/0'/0/0"; + /** * Regex to match email address */ diff --git a/packages/app/src/Pages/Login.tsx b/packages/app/src/Pages/Login.tsx index bc2548a4..8f303f7a 100644 --- a/packages/app/src/Pages/Login.tsx +++ b/packages/app/src/Pages/Login.tsx @@ -5,10 +5,13 @@ import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import * as secp from "@noble/secp256k1"; import { useIntl, FormattedMessage } from "react-intl"; +import { HDKey } from "@scure/bip32"; +import { wordlist } from "@scure/bip39/wordlists/english"; +import * as bip39 from "@scure/bip39"; import { RootState } from "State/Store"; import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login"; -import { DefaultRelays, EmailRegex } from "Const"; +import { DefaultRelays, EmailRegex, DerivationPath } from "Const"; import { bech32ToHex, unwrap } from "Util"; import { HexKey } from "@snort/nostr"; import ZapButton from "Element/ZapButton"; @@ -111,8 +114,18 @@ export default function LoginPage() { } async function makeRandomKey() { - const newKey = secp.utils.bytesToHex(secp.utils.randomPrivateKey()); - dispatch(setGeneratedPrivateKey(newKey)); + const mn = bip39.generateMnemonic(wordlist); + const ent = bip39.mnemonicToEntropy(mn, wordlist); + const entHex = secp.utils.bytesToHex(ent); + const masterKey = HDKey.fromMasterSeed(ent); + const newKey = masterKey.derive(DerivationPath); + + if (!newKey.privateKey) { + throw new Error("INVALID PRIVATE KEY DERIVATION"); + } + + const newKeyHex = secp.utils.bytesToHex(newKey.privateKey); + dispatch(setGeneratedPrivateKey({ key: newKeyHex, entropy: entHex })); navigate("/new"); } diff --git a/packages/app/src/Pages/new/NewUserFlow.tsx b/packages/app/src/Pages/new/NewUserFlow.tsx index 96f21eaf..6e5b3e80 100644 --- a/packages/app/src/Pages/new/NewUserFlow.tsx +++ b/packages/app/src/Pages/new/NewUserFlow.tsx @@ -6,7 +6,7 @@ import Logo from "Element/Logo"; import { CollapsedSection } from "Element/Collapsed"; import Copy from "Element/Copy"; import { RootState } from "State/Store"; -import { hexToBech32 } from "Util"; +import { hexToBech32, hexToMnemonic } from "Util"; import messages from "./messages"; @@ -68,7 +68,7 @@ const Extensions = () => { }; export default function NewUserFlow() { - const { publicKey, privateKey } = useSelector((s: RootState) => s.login); + const { publicKey, privateKey, generatedEntropy } = useSelector((s: RootState) => s.login); const navigate = useNavigate(); return ( @@ -91,6 +91,10 @@ export default function NewUserFlow() { +

+ +

+