-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Here are some of my lightly-organized thoughts that were discussed on the 2024-09-02 call. Posting here as promised for record and for further consideration. These musings mostly arise from the initial question of why Derive-Local and Derive-Remote need to be distinct.
Does HDK-Root really need to be distinct from HDK-Derive-Local?
Could HDK-Root(pk_device, seed) = HDK-Derive-Local((pk_device, sk_device, seed), 0) ?
[Discussed on 2024-09-02 call: The distinction may not be strictly necessary, but it's useful to only need to inject the root public key once.]
I still don't really get why HDK makes a difference between HDK-Root and HDK-Derive-Local,
Multi-party sequence diagrams could greatly help illustrate how the pieces fit together.
Oooh, the sk
output from HDK-Derive-Local isn't actually the private key corresponding to pk
, just a shard (blinding factor) of it?
In that case it's been very confusing to me to call it sk
instead of "blinding factor" or "key handle" or something like that.
Perhaps the hierarchy could be remodeled from a tree of (pk, sk) pairs to a tree of blinding factors?
HDK-Derive-Local (re-)blinds both pk and sk with the same factor simultaneously.
So maybe an appropriate abstraction for the blinding scheme could be something like:
BL-Generate-Keypair() -> (pk, sk)
BL-Derive-Blinding-Factor(seed, DST) -> tau
BL-Blind-Public-Key(pk, tau) -> pk'
BL-Blind-Private-Key(sk, tau) -> sk'
BL-Combine-Blinding-Factors(tau1, tau2) -> tau'
Computetau'
such that
BL-Blind-Public-Key(pk, tau') = BL-Blind-Public-Key(BL-Blind-Public-Key(pk, tau1), tau2)
and
BL-Blind-Private-Key(sk, tau') = BL-Blind-Private-Key(BL-Blind-Private-Key(sk, tau1), tau2)
Can't include the DST in Blind-Public-Key/Blind-Private-Key anymore, since that would break the algebra.
tau becomes a BL-specific type (scalars in the EC case) instead of arbitrary octet strings.
Anyway, with this abstraction, I think the HDK tree could be something like:
(tau0, salt0) = HDK-Root(pk_device, seed)
(tau1, salt1) = HDK-Derive((tau0, salt0), index)
HDK-Root(pk_device, seed):
salt = expand(serialize(pk_device), ID || seed, Ns)
tau = BL-Derive-Blinding-Factor(salt, DST)
return (tau, salt)
HDK-Derive((tau, salt), index):
salt' = expand(salt || I2OSP(index, 4), ID, Ns)
tau_tmp = BL-Derive-Blinding-Factor(salt', DST)
tau' = BL-Combine-Blinding-Factors(tau, tau_tmp)
return (tau', salt')
HDK-Derive-Public-Key((tau, salt), pk_device):
return BL-Blind-Public-Key(pk_device, tau)
HDK-Derive-Private-Key((tau, salt), sk_device):
return BL-Blind-Private-Key(sk_device, tau)
Maybe the distinction between Derive-Local and Derive-Remote disappears? I don't think the taus really need to be kept secret?
Not sure how this would interact with HDK-Authenticate, though. Maybe this makes it harder to implement the blinding using ECDH for multiplication, for example?
What is the advantage of the hierarchical tree structure?
What capabilities does this introduce that you don't get with just a single level of blinded keys?
[Discussed on 2024-09-02 call: Might enable some selective proofs of association that aren't as straightforward in a flat structure?]
Metadata
Metadata
Assignees
Labels
Projects
Status