let message = `Login to Nostr as ${username}\n\nImportant: Please verify the integrity and authenticity of your Nostr client before signing this message.\n${info}`
HKDF-SHA-256 is used to derive 42 bytes long hash key.
`hkdf(sha256, inputKey, salt, info, dkLen = 42)`
-`Input key` is SHA-256 hash of signature bytes.
```js
let inputKey = await sha256(hexToBytes(signature.slice(2)));
```
-`Salt` is SHA-256 hash of following identifier string. `signature.slice(68)` is hex `s` value of signature, last 32 bytes.
```js
let salt = await sha256(`eip155:${chainId}:${username}:${password?password:""}:${signature.slice(68)}`);
```
-`Info` is string with following format.
```js
let info = `eip155:${chainId}:${username}:${address}`;
```
-`Derived Key Length` is set to 42. FIPS 186/4 B.4.1 require hash length to be >=n+8 where, n is length of final private key. (42 >= 32 + 8)
```js
let dkLen = 42;
```
-`hashToPrivateKey` function is FIPS 186-4 B.4.1 implementation to convert derived hash keys from `HKDF`to valid `secp256k1` private keys. This function is implemented in js `@noble/secp256k1` as `hashToPrivateKey`.
```js
let hashKey = hkdf(sha256, inputKey, salt, info, dkLen=42);
let privKey = secp256k1.utils.hashToPrivateKey(hashKey);
let pubKey = secp256k1.schnorr.getPublicKey(privKey);
```
## Implementation Requirements
- Connected Ethereum Wallet signer MUST be EIP191 and RFC6979 compatible.
- The message MUST be string formatted as `Login to Nostr as ${username}\n\nImportant: Please verify the integrity and authenticity of your Nostr client before signing this message.\n${info}`.
- HKDF input key MUST be generated as the SHA-256 hash of 65 bytes signature.
- HKDF salt MUST be generated as SHA-256 hash of string `eip155:${chainID}:${username}:${password?password:""}:${signature.slice(68)}`.
- HKDF derived key length MUST be 42.
- HKDF info MUST be string formatted as `eip155:${chainId}:${username}:${address}`
let message = `Login to Nostr as ${username}\n\nImportant: Please verify the integrity and authenticity of your Nostr client before signing this message.\n${info}`
let signature = wallet.signMessage(message); // request signature from wallet