fix: nip6

closes #729
This commit is contained in:
2024-09-09 15:03:18 +01:00
parent 7822f6a62b
commit 40ffebb0c2
8 changed files with 83 additions and 26 deletions

View File

@ -7,8 +7,8 @@
"@noble/curves": "^1.4.0",
"@noble/hashes": "^1.4.0",
"@scure/base": "^1.1.6",
"@scure/bip32": "^1.4.0",
"@scure/bip39": "^1.3.0",
"@scure/bip32": "^1.5.0",
"@scure/bip39": "^1.4.0",
"@snort/shared": "workspace:*",
"@snort/system": "workspace:*",
"@snort/system-react": "workspace:*",

View File

@ -4,6 +4,7 @@
width: 210px;
background-color: var(--gray);
z-index: 2;
background-size: cover;
}
.avatar[data-domain="iris.to"],

View File

@ -33,9 +33,9 @@ export default function useLoginHandler() {
if (!hasSubtleCrypto) {
throw new Error(insecureMsg);
}
const ent = generateBip39Entropy(key);
const hexKey = entropyToPrivateKey(ent);
LoginStore.loginWithPrivateKey(await pin(hexKey));
const entropy = generateBip39Entropy(key);
const privKey = await entropyToPrivateKey(entropy);
LoginStore.loginWithPrivateKey(await pin(privKey));
return;
} else if (key.length === 64) {
if (!hasSubtleCrypto) {

View File

@ -6,7 +6,7 @@ import { FormattedMessage } from "react-intl";
import Copy from "@/Components/Copy/Copy";
import useLogin from "@/Hooks/useLogin";
import { hexToBech32 } from "@/Utils";
import { hexToMnemonic } from "@/Utils/nip6";
import { seedToMnemonic } from "@/Utils/nip6";
export default function ExportKeys() {
const { publicKey, privateKeyData, generatedEntropy } = useLogin();
@ -44,7 +44,7 @@ export default function ExportKeys() {
<FormattedMessage defaultMessage="Mnemonic" />
</div>
<div className="mnemonic-grid">
{hexToMnemonic(generatedEntropy ?? "")
{seedToMnemonic(generatedEntropy ?? "")
.split(" ")
.map((a, i) => (
<div key={a} className="flex items-center word">

View File

@ -49,11 +49,6 @@ export const DefaultImgProxy = {
salt: "a897770d9abf163de055e9617891214e75a9016d748f8ef865e6ffbcb9ed932295659549773a22a019a5f06d0b440c320be411e3fddfe784e199e4f03d74bd9b",
};
/**
* NIP06-defined derivation path for private keys
*/
export const DerivationPath = "m/44'/1237'/0'/0/0";
/**
* Blaster relays
*/

View File

@ -1,5 +1,6 @@
import * as utils from "@noble/curves/abstract/utils";
import * as secp from "@noble/curves/secp256k1";
import { bytesToHex } from "@noble/hashes/utils";
import { unixNowMs } from "@snort/shared";
import {
EventPublisher,
@ -47,9 +48,8 @@ export async function generateNewLogin(
pin: (key: string) => Promise<KeyStorage>,
profile: UserMetadata,
) {
const ent = generateBip39Entropy();
const entropy = utils.bytesToHex(ent);
const privateKey = entropyToPrivateKey(ent);
const entropy = generateBip39Entropy();
const privateKey = await entropyToPrivateKey(entropy);
const newRelays = {} as Record<string, RelaySettings>;
// Use current timezone info to determine approx location
@ -95,7 +95,7 @@ export async function generateNewLogin(
system.BroadcastEvent(ev3);
Promise.all(Blasters.map(a => system.WriteOnceToRelay(a, ev3)));
LoginStore.loginWithPrivateKey(await pin(privateKey), entropy, newRelays);
LoginStore.loginWithPrivateKey(await pin(privateKey), bytesToHex(entropy), newRelays);
}
export function generateRandomKey() {

View File

@ -1,11 +1,15 @@
import * as utils from "@noble/curves/abstract/utils";
import { bytesToHex } from "@noble/hashes/utils";
import { HDKey } from "@scure/bip32";
import * as bip39 from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
import { DerivationPath } from "@/Utils/Const";
/**
* NIP06-defined derivation path for private keys
*/
export const DerivationPath = "m/44'/1237'/0'/0/0";
export function generateBip39Entropy(mnemonic?: string): Uint8Array {
export function generateBip39Entropy(mnemonic?: string) {
try {
const mn = mnemonic ?? bip39.generateMnemonic(wordlist, 256);
return bip39.mnemonicToEntropy(mn, wordlist);
@ -15,9 +19,9 @@ export function generateBip39Entropy(mnemonic?: string): Uint8Array {
}
/**
* Convert hex-encoded entropy into mnemonic phrase
* Convert hex-encoded seed into mnemonic phrase
*/
export function hexToMnemonic(hex: string): string {
export function seedToMnemonic(hex: string) {
const bytes = utils.hexToBytes(hex);
return bip39.entropyToMnemonic(bytes, wordlist);
}
@ -25,8 +29,8 @@ export function hexToMnemonic(hex: string): string {
/**
* Derrive NIP-06 private key from master key
*/
export function entropyToPrivateKey(entropy: Uint8Array): string {
const masterKey = HDKey.fromMasterSeed(entropy);
export function seedToPrivateKey(seed: Uint8Array) {
const masterKey = HDKey.fromMasterSeed(seed);
const newKey = masterKey.derive(DerivationPath);
if (!newKey.privateKey) {
@ -35,3 +39,16 @@ export function entropyToPrivateKey(entropy: Uint8Array): string {
return utils.bytesToHex(newKey.privateKey);
}
export async function entropyToPrivateKey(entropy: Uint8Array) {
const mm = bip39.entropyToMnemonic(entropy, wordlist);
const seed = await bip39.mnemonicToSeed(mm);
const masterKey = HDKey.fromMasterSeed(seed);
const newKey = masterKey.derive(DerivationPath);
if (!newKey.privateKey) {
throw new Error("INVALID KEY DERIVATION");
}
return bytesToHex(newKey.privateKey);
}