Add notes on implementation, etc

This commit is contained in:
Adam B 2023-04-15 16:30:35 +02:00
parent 2e99c2d8d7
commit 6c57b4cf34
No known key found for this signature in database
GPG Key ID: 9ED7B5FB86547DAD

49
41.md
View File

@ -132,21 +132,12 @@ The verification process for the validity of an invalidation (`kind: 13`) event
## Additional comments
### This is not a general "rotation" scheme for keys
This scheme is intended to make it less catastrophic when a key is compromised because it was input into a computer, phone or Nostr client softwre that turns out later to have been compromised. It isn't intended to allow people to rotate their keys every month as a routine practice, nor is it supposed to let users be reckless and give their private keys to any malware or trusted third parties. A compromised key is still a bad event, just not one of awful and unrepairable consequences if this NIP is followed and relied upon.
### Notes on Implementation
32 vs 33-byte public keys. In Nostr usually the 32-byte 'X-only' format public key is used. However, in the BIP32 scheme employed here the 33-byte 'compressed' format public key is used. The 32-byte format misses the parity. In practice this means that at verification both parity alternatives have to be checked.
For derivation an 'off-the-shelve' BIP32-capable library implementation can be used directly, or an own implementation. The own implementation is recommended, for the reasons:
- Due to a limitation that stems from serialization format that is not relevant here, implementations typically limit the maximum depth of a derivation path to 256, meaning that at most 253 keys could be generated in this scheme (though in practice that's probably sufficient).
- Constructing an extended public key from its parts is needed at verification, but this is not a typical operation in the BIP32 use cases, and it cannot be easily accessed, only through some workarounds.
### Fallback mechanism possibilities
What happens if Bob is following Carol and Carol publishes an invalidation event for her key, but Bob's client doesn't see it for any reason or doesn't support the automatic refollow mechanism for the new key? Well, in this case we are at least not worse than the current state of things, but Bob has other possibilities:
@ -156,3 +147,41 @@ What happens if Bob is following Carol and Carol publishes an invalidation event
- anyone with a supporting client can be 100% sure the key was really invalidated, so they can alert others about that fact without any fear of spreading wrong information;
- and last but not least Bob may want to verify things manually if he sees suspicious activity from Carol's key. At least he doesn't have to ask her (and then get a response from the attacker stating that "no, it's just me, Carol!").
### Why not use a fix length derivation path?
Would it be possible to use a derivation path of fixed length, with consecutive indices to generate the keys?
It would be possible, but rotation requires publishing the chaincode, which would allow the reconstruction of other sibling keys. Only through using an ever-growing-length derivation path it is possible to use an iterative derivation employing a hash of previous keys.
### Notes on Implementation
32 vs 33-byte public keys. In Nostr usually the 32-byte 'X-only' format public key is used. However, in the BIP32 scheme employed here the 33-byte 'compressed' format public key is used. The 32-byte format misses the parity. In practice this means that at verification both parity alternatives have to be checked.
Library vs. own implemetation. For derivation an 'off-the-shelve' BIP32-capable library implementation can be used directly, or an own implementation. The own implementation is recommended, for the following reasons:
- Due to a limitation that stems from serialization format that is not relevant here, implementations typically limit the maximum depth of a derivation path to 256, meaning that at most 253 keys could be generated in this scheme (though in practice that's probably sufficient).
- Constructing an extended public key from its parts is needed at verification, but this is not a typical operation in the BIP32 use cases, and it cannot be easily accessed, only through some workarounds.
By referencing BIP32, it is not the task of this spec to defined the details of the derivation. For convenience we shortly reproduce it here.
The non-hardened ESK derivation pseudo-code is:
```
hash64 = HMAC_SHA512(CC || PK33 || N4)
SK = SK + hash64[0..31]
CC = hash64[32..63]
```
where HMAC_SHA512 is the corresponding hash function, `PK33` is the 33 byte public key `||` is byte concatenation, `N4` is the 4-byte (BE) serialization of the child number `[]` denotes byte sub-array, `+` is scalar addition (using BE 32 byte numbers).
The hardened version is similar, but the hash argument is `('0' || SK32)`.
The EPK derivation is also similarm with `+` here being point addition:
```
hash64 = HMAC_SHA512(CC || PK33 || N4)
PK = PK + hash64[0..31]
CC = hash64[32..63]
```