Threshold Key Derivation - Privacy on the IC

Thanks! A clarificatory question:

When you refer to a Node in the Syntax section of Internet Computer Loading , i believe you are referring to SmartCanisters and not Nodes (as in Nodes on Internet Computer). Did i get it right?

No, these are actually nodes making up a subnet (similar to tECDSA).

If it was canisters holding shares of the master key, it would be trivial to collect all these shares (by looking at the state of a single replica; or at least one replica per subnet, if said canisters were spread across multiple subnets) and reconstruct the master key. With nodes holding the shares, you’d need simultaneous control of a majority of the subnet’s nodes (similar to what you’d need to do to extract a subnet’s secret key).



Trying to understand this statement : “Nodes can also combine encrypted shares to produce the full encrypted derived key ek using a Combine algorithm”.

Because each Node participating in this protocol has it’s own master-secret-key-share (msks-i) and is passed in the full public transport key (tpk) along with the id ( from bob, it can produce a derived encrypted key share (eki) representing a “shared” bob.

A threshold set of ekis are required to produce a “complete” bob; provided that these ekis can be decrypted. Since only bob holds the private transport key (tsk) with which these ekis are encrypted, a node can gossip with other nodes and produce that combined threshold share (aka full derived keys) which are encrypted.

This Combine function is therefore convenient because an actor (Bob) needs to interact with only one node; as opposed to threshold set of nodes.

Did I get the above right?

What happens if that node is a rogue node?

The talk was great!!!

I’m making an assumption that it would be nice to have verified. The Dapp controls these access to the keys correctly? So if the smart contract says that Bob can decrypt Alice’s encryption then he gives Bob the key he needs. Is that correct? It seems like this adds another level of trust to this scheme and the canister code is going to have to get pretty serious about immutability or DAO horizoning. In other words, could an upgraded canister arbitrarily decide to start issuing decryption keys to everyone?

I believe that next to ETH integration(to capture the known degens), this is likely the most important feature for the IC. Encryption in a secure way needs to be solved to bring enterprise onto the IC. As mentioned in the talk this would open up numerous use cases for businesses in the “Shared Data Spaces” realm.

At Origyn we need to encrypt certain product and user details that should only be accessible to authenticators, customers, or service providers who have been granted access. So certificates end up with a mix of open, transparent data and permissions, encrypted data.

Keep up the good work and I can’t wait to see what you all come up with!


I just thought of a potential use case while on an airplane today.

I was thinking about how a DAO or group could control an npm account and push new package versions to npm. The token could be verifiably encrypted, and a canister could decrypt the token just when necessary to do an http outcall to deploy a new version of a package.

Though, the decrypted token would be available temporarily in the memory of the nodes right? Hopefully AMD-SEV or something similar gets deployed soon to help on that front.



I don’t know much about the specifics of vetKD, but given that this is a subnet, the result would be the same as talking to a random malicious node on a random subnet: it could take arbitrarily long to respond, it could respond with garbage, but it wouldn’t be able to produce an invalid response with a valid subnet signature. So after either a timeout or an invalid response, you would query again for the status of your request and will likely hit an honest node.

1 Like

Assuming that Bob’s authentication to idbob passes through a dapp, the dapp could update itself to pass “true” to every authentication request. See below.

So yes your assertion is correct. Immutability / some kind of sensible implementation would be required.

@free @ais

Given that there’s one masterkey and assuming various different dapps that piggyback on the same arbitrary string (ie “”), what is the mechanism of distinguishing different idbobs (one idbob per dapp)?

1 Like


More generally, this would solve “how to store a api-key securely to call private apis which require api-keys” on IC ; baring a small window of time where the dapp smart canister (hosted on nodes) would have the decrypted api-key (aka token) in RAM.


Disclaimer: I’m not a cryptographer, I’m a systems software engineer. My first run-in with cryptography beyond the basics of public key cryptography (I just had to look up the proper term for it) was when I joined DFINITY a few years back. I’m also not directly involved with vetKD. So take my answers with a grain of salt.

I imagine one simple solution would be for the vetKD implementation to e.g. always prepend the canister ID (of the canister making the request) to the provided ID. That way, when Alice asks canister C to derive a public key for ID ""; or Bob asks canister C to derive the secret key for the same; they will actually be getting the public/secret key derived from "<C>|". So asking canister C for the public/secret key for "" would result in a different key pair than asking the same from a canister D.

And the only way to get the former key pair would be to go through canister C. And canister C may enforce whatever rules it chooses to decide whether to allow or not a given principal to retrieve the secret key derived from "".


What is the difference between vetKD and drand?
Both use t-BLS signatures and IBE cryptography for encryption and decryption. Please tell us what exactly are the differences.

1 Like

I need this functionality because this is the whole point of my application! I am working on encrypted file storage and I abandoned the idea of storing keys on the user side as soon as I learned about the possibility of using end-to-end encryption in the canister in the near future. At the moment, I just have a file storage until I again implement encryption support already on the side of the canister. I’m also inspired by the ability to decrypt data based on time, sharing files with someone in case of an accident. I would like to be able to work with this functionality in the near future, so please add +1 to the number of applications that really need it :slightly_smiling_face:


So maybe Q4 full implementation?

1 Like

I’ve thought of another use case, this time for the Internet Computer itself. I’ve written a tweet thread and I’ll open a forum post if initial feedback is good:

The idea is to use ZK proofs to vet node operators, and then use VetKD to encrypt their KYC/B information, store it in the NNS subnet, and allow decrypting it only with an NNS proposal.

This would allow almost anonymous node operators while allowing deterministic decentralization, legal compliance, and legal or reputational courses of action if node operators misbehave.

I truly believe, if I haven’t made some grave mistake in understanding, that this is a solution to one of the biggest attack vectors of the IC, that being collusion between node operators in static subnets.


I really think this is a win-win situation for both the internet computer and node operators.

1 Like

Who determines the authenticity of the initial KYC data that the node provider registers, Dfinity?
If the prover is the node provider himself, I don’t think we would know if the KYC is true or not.

I understand the goal of allowing node operators to stay anonymous as much as possible, as a goal in itself. But it does not change anything regarding their ability to collude. Those who want to collude will find each other no matter what. Or do you mean they would be harder to attack by an attacker whose goal is to hack multiple and then „make“ them collude?

1 Like

This would make it much harder for node providers to collude wouldn’t it? Right now they have free and open access to each other’s contact information more or less. With this solution I’m hoping it would be much harder for them to find each other, especially once we have node rotation/shuffling.

What do you mean by that, how would anonymous node operators find each other secretly?

Maybe by being the same node operator with multiple identities