> ## Documentation Index
> Fetch the complete documentation index at: https://lnurl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# LUD-05: BIP32-based seed generation for auth protocol.

> Display inline code and code blocks

`author: akumaigorodski`

***

### `linkingKey` derivation for BIP-32 based wallets:

1. There exists a private `hashingKey` which is derived by user `LN WALLET` using `m/138'/0` path.
2. `LN SERVICE` full domain name is extracted from login `LNURL` and then hashed using `hmacSha256(hashingKey, full service domain name)`. Full domain name here means FQDN with last full-stop (aka "point") omitted (Example: for `https://x.y.z.com/...` it would be `x.y.z.com`).
3. First 16 bytes are taken from resulting hash and then turned into a sequence of 4 `Long` values which are in turn used to derive a service-specific `linkingKey` using `m/138'/<long1>/<long2>/<long3>/<long4>` path, a Scala example:

```Scala theme={null}
import fr.acinq.bitcoin.crypto
import fr.acinq.bitcoin.Protocol
import java.io.ByteArrayInputStream
import fr.acinq.bitcoin.DeterministicWallet._
val domainName = "site.com"
val hashingPrivKey = derivePrivateKey(walletMasterKey, hardened(138L) :: 0L :: Nil)
val derivationMaterial = hmac256(key = hashingPrivKey.toBin, message = domainName)
val stream = new ByteArrayInputStream(derivationMaterial.slice(0, 16).toArray)
val pathSuffix = Vector.fill(4)(Protocol.uint32(stream, ByteOrder.BIG_ENDIAN)) // each uint32 call consumes next 4 bytes
val linkingPrivKey = derivePrivateKey(walletMasterKey, hardened(138L) +: pathSuffix)
val linkingPubKey = linkingPrivKey.publicKey
```

### Test Vector

```
domain name: site.com
hashingPrivKey: 0x7d417a6a5e9a6a4a879aeaba11a11838764c8fa2b959c242d43dea682b3e409b
pathSuffix: Vector(1588488367, 2659270754, 38110259, 4136336762)
```
