Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
3 Skipped Deployments
|
0xParti
left a comment
There was a problem hiding this comment.
This is insanely good. Very well written, a lot of info.
I would strongly suggest adding numbers to the md files, it was a bit complex to follow without knowing the correct ordering.
Not approving yet because there are 3-4 important comments. The rest are just nitpicks. Great job.
| 1. **BIP-32 Derivation.** The firmware first uses its existing BIP-32 implementation to derive a child key. Think of a master seed and its derived keys as a family tree. "Normal" derivation is like having public records if you find a child key, you might be able to find information about its parent. **Hardened derivation**, which is mandatory in this protocol, is different. It's like a one way street using a mathematical process that makes it computationally impossible to go from the child key back to the parent. This is done along a specific, app registered derivation path (for example, `m/44'/8888'/0'`) creating a cryptographic firewall. Even if one application's secret is completely compromised, it reveals nothing about the master seed or any other application's secret. | ||
| 2. **HKDF finalization.** The resulting intermediate key is not the final secret. It is a raw private key and we don't want to return that. Instead, it is immediately fed into an `HKDF-Extract` function, this step is crucial because it acts as a **finalizer**. It takes the structured private key and transforms it into a blob of pure, unstructured entropy, like scrambling a message into random noise. This final `appSecret` has no mathematical properties of a signing key, so it cannot be accidentally imported into another wallet or used to sign a transaction. Using a protocol specific "salt" during this step also ensures that this particular "scrambling" is unique to our protocol, preventing any cross protocol misuse. | ||
|
|
||
| It's worth noting we deliberately split the standard `Extract-then-Expand` model of HKDF. The firmware performs only the simple `HKDF-Extract` step, which is a single, atomic function call. We leave the more complex `HKDF-Expand` step, which often involves loops and variable logic, to the application's SDK. This decision follows the principle of **minimal firmware complexity**, keeping the code on the most secure part of the system as simple and auditable as possible. |
|
|
||
| The next step is to prove control over the master seed by signing a message. Critically, we use the `Privileged-Access Address` from Step 1 to construct an unforgeable challenge. We do this by creating an EIP-712 payload that includes the hash of this address `keccak256(Privileged-Access Address)`. | ||
|
|
||
| EIP-712 is the ideal tool for this because it ensures signatures can be **deterministically replicated** (crucial for recovery), provides strong **cross context replay resistance** (prevents signatures from being used elsewhere) and enables **informed user consent** through a human readable format. |
There was a problem hiding this comment.
the replicability is not only a property from 712, but it has to do with how nonces are generated in the wallet. The most modern implementation depends on the message and I cant rembember what else. Some legacy wallets used an index, meaning a repeated message resulted in a different signature, which was non replicable. We are trusting on the wallet to use the good nonce pattern (it had a standard number, can´t recall now)
| - **`H_domain`** : This is the "lock" we mentioned before. It is a hash of the application's unique context, including its `name` ("Standardized Secret Derivation") and `version` (like "1"). This ensures a signature for our protocol cannot be maliciously replayed on another dApp's platform, because that platform would have a different domain name, and thus a different lock. | ||
| - **`H_struct`** : If `H_domain` is the lock, `H_struct` is the unique fingerprint of the document being signed. Any change to the message, even a single character, would result in a completely different `H_struct`, making the signature invalid. This guarantees the integrity of what the user is actually signing. | ||
|
|
||
| It's worth noting there's a design trade off here. Our protocol uses a single, protocol wide `H_domain` for all apps that use it. For example, a user performs one signature for the "Standardized Secret Derivation" domain. From the resulting signature, we can then derive secrets for both *Privacy Pools* and *Railgun*. This is great for UX, one signature unlocks privacy everywhere. An alternative design would be to create a unique domain for every app. This would require the user to sign a new message for every time, adding friction but creating even stronger isolation at the signature level. We opt for the former, prioritizing a seamless UX. |
There was a problem hiding this comment.
This is still open actually. We are 90% convinced that the correct way to handle this is by using a per application H_domain. That is what the UI guys implemented actually (correct me if I'm wrong here @akoidefi ). The common H_domain was originally though if we planned to cache some secrets and improve the UX, but we rather have full isolation now.
|
|
||
| ### **Key generation and management** | ||
|
|
||
| Everything starts here. The process must begin with cryptographically secure randomness to create a private key. Most modern wallets use **hierarchical deterministic (HD)** structures, which allow a single secret (the "seed phrase") to generate a nearly infinite tree of keys and addresses. This is a massive improvement over early wallets where every single key had to be backed up individually. |
There was a problem hiding this comment.
This made me remember a good analogy I once hear is: money in blockchain is on public transparent vaults. Anyone can grab the money, as long as they know the key. And most importantly, keys don't have owners, anyone can try.
| @@ -0,0 +1,62 @@ | |||
| # On words and keys, a guide to Mnemonic Phrases | |||
There was a problem hiding this comment.
I’d like to link each document back to why it matters. why I need to know this? where it’s being applied in Kohaku? and create cross-references between them to make those connections clear
ecca183 to
2bbe9c0
Compare
EF Handbook
https://linear.app/defi-wonderland/issue/EFI-490/ef-handbook-privacy