The ECDSA signatures generated by the IC itself through the threshold ECDSA mechanism? What would be the application?
So canister A would hold a virtual private ECDSA key, that is distributed among the hosting subnet, then would get a message signed and another canister, B, would verify the signature on that message. Why doesn’t A just send an inter-canister message to B and B looks at msg.caller to verify it comes from A?
There are async-temporal applications(general) and cross-chain applications(specifically) where we just need some solid crypto libraries in motoko. ICDevs will have some bounties around this in the next couple of weeks, but if you all have them sitting around on hard drives it would be nice to apply the funds elsewhere.
I would be interested to see how performant they are. But since you’re likely only going to verify a single signature per message the performance is probably irrelevant in practice.
RSA would be very to implement, anything EC related a lot more work. At least Motoko already has arbitrary precision integers so you don’t need a gmp library. That helps a bit. Just need to find someone to implement it.
All of the applications I can think of are orchestrating communication in swarms of canisters spawned from a trusted source. Given Source, Ca, Cb - how can Ca and Cb interact with one another while verifying they both belong to Source. The “best” solution here would be if we could derive the pubkey of a principalId - but I don’t think that is a feature on the roadmap (or even possible). The naive solutions are either too difficult implement (PubSub events on Canister Creation), or are subject to physical attacks HMACy -> Hash(Common Secret + Claim).
If I had this today, I would implement something like the following - Given Source, Ca, Cb. When creating a canister Source would pass its public key and a claim to Ca, Cb. When Ca sends an inter-canister call to Cb, it can tack on its claim and Cb can verify.
So, I pretty much just want to use this for glorified JWTs.
Can you have a registry in Source so that Cb can ask Source (once) if Ca belongs to Source or not?
Maybe not because you have so many Cx that you think this is going to be a bottleneck?
Or maybe not because you want to allow for recursion, i.e. chains of certificates?
Otherwise the registry would be easiest.
Yeah with the certificate scheme one could completely avoid the issues of storing a large number of Cx. Also, with the registry each Cx needs to maintain a record of canisters it has verified. One other thought, consider message queuing problems; If you have a lot of new interactions all the time, now you have to figure out how to distribute the load on the registry. Distributed systems are hard.
If you could determine the origin of a principal and you know you can trust the origin you’ve solved this interaction problem - just in this case the derived principals are the “special” secure thing. After thinking about it I think the additional flexibility you get from passing certificates around is superior.
Just want to share with everybody here that an important internal milestone has been reached earlier this week: we were able to successfully complete the end-to-end workflow of canister signature signing using threshold ECDSA. A user can submit a message to a canister, which then calls the system API to sign on the message. Subnet nodes then work together to produce this signature and the canister gets it back in a few seconds. The signature can be verified by the user inside a browser using a standard secp256k1 Javascript library against the canister’s public key (which was BIP32 derived from its canister id).
Before anyone gets too excited and demand this to be ready tomorrow, there is still much work ahead of us: support facilities, testing, integration, disaster recovery, more testing and security reviews. Nevertheless it is still a validation of the design, protocol and implementation behind this work. Thanks to the hard work put in by everybody on the team and also all community members who supported this project with warmth and valuable discussions, we are one step closer to the goal!
Good question. What you are asking here is: can we do threshold decryption on the IC? While threshold signing and decryption have some things in common, they are not exactly the same thing. So ECDSA threshold signing will not directly enable threshold decryption. That said, threshold decryption is something dfinity is definitely exploring. It certainly could be done, so it is just a matter of prioritizing engineering resources.
Only canisters themselves will be able to query their canister “root” public key from the system API. The canister’s “root” public key is derived by the system from the ECDSA master key. The canister can make the public key, further public keys derived from this public key, or Bitcoin addresses computed from those public keys available to any parties they wish using an application-specific interface. For example, a DEX canister would give each of its customers their own Bitcoin address computed from a public key that has been BIP-32 derived from the canister’s “root” key it has queried from the system. Then, the customer can transfer Bitcoin to this customer-specific address.
Apologies for my late response, the upcoming Bitcoin release and other things have been taking up all my time.
Let me provide some background on ECDSA keys:
We will have one master ECDSA key in the beginning, the architecture being extensible to multiple keys and also multiple curves, e.g., we see secp256r1 as one that might come next to enable decentralized CA use cases.
There will be one active signing subnet and one key backup subnet in the beginning.
The signing subnet will not run user-space canisters for reducing the attack surface on the key. (no user-space canister is even better than sandboxed ones)
We will have a system API for allowing canisters to retrieve its own or other canisters’ public keys and also derive public keys when specifying a derivation path.
The master public key is not published as it is derived with a non-standard extension of BIP-32: It uses a canister id as input instead of a 32-bit integer to derive the canister master key from the master key.
Returned public keys are always accompanied with a chain code for allowing further BIP-32 unhardened key derivation.
When requesting a signature, the canister provides the message hash and derivation path as input to the method.
The key management and deployment are part of the feature IC-733 that is about threshold ECDSA system integration and handles the required aspects besides the core protocol IC-316.
Does this answer your question above? – I tried go give some more context about related things to provide the larger picture.
This is a regular ECDSA library if I am not mistaken. Thanks for the pointer to this! It may contain some building blocks, e.g., EC scalar multiplication on the secp256k1 curve, which we will need as building blocks for Motoko-based canisters, e.g., for deriving Bitcoin addresses.
Doing ECDSA signing directly in a canister is not the best idea: It requires that the private key be stored in every replica and if one replica is breached, the private key is breached as well. So using an ECDSA library directly in the canister is not aligned with the trust model of the IC which stipulates that less than 1/3 of the replicas can be compromised and it is still secure. Anyone who needs ECDSA signing functionality in a canister is advised to use threshold ECDSA once available. However, it’s nice to have this library for verifying ECDSA signatures, so we appreciate this work!
Also, for the Bitcoin Developer Preview threshold ECDSA will not yet be available and such an ECDSA library is nice to have to compute ECDSA signatures in a non-secure way during development and then switching over to threshold ECDSA once it’s available and before going live with the canister using this functionality.
Thanks! So the public key stays private in the same sense as the Internet Identity seed salt is private: the nodes participating in that subnet know it, but won’t tell anyone.
You always emphasize “unhardened”. How hard is it to find the original public key?
Also, what is the rationale for not simply publishing the key and the derivation mechanism? This would unlock use cases where the receiver of a signed message wants to know if it was signed by a specific canister (rather than just by some public key claimed to be a canister) - or is that exactly something you don’t want?
To provide some background on the library at GitHub - herumi/ecdsa-motoko
This work was started in response to requests made here on this thread, in which people said being able to verify ECDSA signatures in Motoko would be useful in situations involving swarms of canisters or cross-chain applications.
The signing functionality is there for completeness. After all, Motoko is a general purpose language not limited to canisters, isn’t it? The implementation is not optimized, but that’s fine because it seems that the desired applications tend to require only one verification per message execution. The idea is to have this library available right away, from day 1, when the threshold ECDSA signatures go live.
It shouldn’t be hard. I think you need to observe the master public key of two canisters for which you know the canister id and then you can solve a linear equation. Or something like that.
There were some reasons but I don’t remember them. Maybe it has to do with not wanting people to start relying on something that is an implementation detail and that can’t be guaranteed in the future. The derivation mechanism is public of course because it is in the code.
Ok, so in all practical senses, people will (should they find a need) figure this out.
Which leads to the next question: Is the plan to eventually have more than one ESDSA master key signing subnet, and have some canisters get their key from one and others from another?