Skip to content

Instantly share code, notes, and snippets.

@jspilman
Last active December 16, 2015 15:09
Show Gist options
  • Save jspilman/5454201 to your computer and use it in GitHub Desktop.
Save jspilman/5454201 to your computer and use it in GitHub Desktop.
Payment Protocol uses X.509 certs to sign a Payment Request. This allows wallets to display meta-data from the cert
to the payer instead of the address, which should make it easier to verify where money is being sent, and prevent
an attacker from changing an address displayed to a user so that coins are sent to the wrong place.
The difficulty is that Payment Requests must be generated live, and therefore the cert used to sign those requests
must also be live, exposing the cert to theft similar to a hot wallet. The question... is there a way to sign something
once, offline, which verifies the address belongs to the payee?
1) Given a root or intermediate certificate 'parent' cert which is kept offline, and a child certificate of 'parent'
which is kept hot on the payment server.
2) Given a public key and chain code { pubKey, code } under BIP32 we generate child keys as I = HMAC(code, pubKey || i),
Ki = I[0:32] * Kpar.
3) If we sign Kpar with the parent cert offline, we can sign the remaining less critical data (address, I[0:32], amount,
description, etc.) with the child cert.
4) The payer verifies Kpar, and verifies the address by calculating Hash160(Kpar * I[0:32])
In fact, there's no requirement to use BIP32 to calculate I[0:32], it could also just be randomly generated.
Any I[0:32] included in the Payment Request, even if it is tampered with, will correspond to an address that the payee
can calculate from its extended private key. Anyone who has the Kpar private key, or the private key of any Ki from the
BIP32 chain can do the same.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment