The most recent release of the replica software, which is scheduled to be rolled out to the Internet Computer blockchain network in the coming days, enables the checking of subnet delegations as part of canister signatures on requests. But what is a canister signature and why should you care?
What is a canister signature?
Canisters are smart contracts that run on the IC. As the state of a canister is known to all replicas of the subnet that hosts that canister, and one or more replicas may behave maliciously, there is no way for a canister to securely store cryptographic keys in their memory. The IC provides certified data – which on a high level can be thought of as a cryptographic signature created by the subnet – as a mechanism for a canister to authenticate data toward the outside world. A canister signature uses the certified-data mechanism available to canisters to define something that syntactically resembles a digital signature scheme that enables the canister to sign messages.
The IC accepts canister signatures for requests or delegations contained therein. This functionality is heavily used by Internet Identity (II): When a user decides to authenticate toward a given dapp using II, the II canister signs a delegation to a short-term cryptographic key in the user’s browser. This mechanism is what enables II to let users authenticate as the same principal from different devices without requiring the user to synchronize cryptographic keys.
Why is this feature important?
Until now, the IC accepted canister signatures on requests only if the issuing canister was hosted on the root subnet (often referred to as NNS subnet) – which means that canisters on other subnets could not make use of the same functionality. With this week’s upgrade, that restriction vanishes: Any canister on any subnet will be able to use the same functionality that powers Internet Identity!
In particular, only now my Capture-the-ICP hacking challenge actually works, as in order to redeem the canister’s ICP, you have to construct such a canister signature.
I wonder how long until people build transferable neurons on top of this feature (or on top of ECDSA signatures, roughly the same thing)?
As @JaMarco pointed out, the canister signatures are specific to the IC and based on BLS – whereas ECDSA signatures are a common standard widely used outside of the IC. On the flip side, signature generation in canister signatures will (probably) be faster and cheaper in terms of cycles – there is simply less protocol overhead.
There is no specific tutorial, unfortunately, and I don’t think we’ll have the capacity to build one soon. But beyond the links that @nomeata provided above, the code of II and the IC are open source, so you could have a look at:
That’s great, thanks! If you hit any roadblocks, feel free to ask! Just tag me on the message to make sure I’ll get a notification – and I’m sure Joachim will be happy to help as well.
Whoa! So if I’m reading this right, there’s a way now to build an on-chain authenticator / validator for sessions, as long as you have a “secure device” with you.
I’m thinking something along the lines of:
a) Initiate a new session from an “unsupported” device, just like the flow for II does now
b) go to my authenticator canister, and request a delegation
c) sign in to the authenticator with a valid II via a supported device
d) see the request, validate it (say some characters, or a series of pictures, whatever)
e) my “unsupported” device now has a proper delegation chain, and can sign requests as if coming from whatever Principal comes out of my II authentication to my own canister.
That would be huge for general adoption! Almost everybody has at least one “secure” device, but most have “normal” pcs without secure enclaves / tpu / etc for webauthn.
You can access the signatures through the CertifiedData API in Motoko. @nomeata has a post describing this in more detail. (Note that while the example canister does certified assets, canister signatures use the same type of tree and just encode a different tree structure.) And @matthewhammer also provided an example implementation.
At least, we can build an enhanced or alternative version of II, integrated with other unsupported login methods, like Email, social login, other supporting ED25519/Secp256k1 curve/signature wallet providers maybe?
For my personal interest, I would prefer to build solution for individuals, like person-controlled canister for private usage. For example, I may have a canister under control and that canister will authorize my other device to control my IoT equipments of my house. . Or more generally, to build solution for small group or company that can authorize their employee or customers.
When using a dapp(auth-client-demo), the front end is http://localhost:8080, and I generated a session key pair on the front end. Then call prepare_delegation with the anchor number, frontend and sessionKey’s public key as parameters. ii After passing the detection of 10000 DeviceData and caller, update the sigs in State(in ii’s canister) and the certified data of the system.
A dapp wants to make a update call, the front-end uses the session key to sign msg, and then the front-end calls get_delegation? Calling get_delegation also requires caller detection, but it doesn’t seem to require the fingerprint to obtain the device’s signature when initiating an update call. Then the result of get_delegation has a more field: signature, which contains the system’s certified data and tree(delegation and asset’s info in ii canister). The certified data should be the node’s signature to the root hash of the system state tree. Does the ic have this signature code generation process?
When prepare_delegation, there is no information related to the update call msg, so there is no signature for the msg in the certified data.The front-end sends the signature of the session key and the result of get_delegation to https://ic0.app, and the IC checks the two signatures?
I am not entirely sure about your goals. If you just want to use II as a client (which is what auth-client-demo should be doing), then the functions prepare_delegation and get_delegation are only called from the II frontend. Are you trying to build an alternative frontend for the II canister?
If you want to understand the prepare_delegation and get_delegation flow in more detail, I suggest you have a look at the Internet Identity specification.
My goal is to understand how the process works. I can understand ecdsa/bls signature and threshold signature. But Canister Signature I don’t understand it or how to use it. Can official team provide some low-level interfaces with better encapsulation?
This function is very helpful for developing IC naive apps, but unfortunately, it requires a little high.
If you want to have your canister issue a signature that can be verified outside of the IC, I would suggest waiting for the ECDSA feature that will be available soon (when we roll out Bitcoin integration to the mainnet). The signatures generated by that functionality will be compliant with widely used standards (which canister signatures are not, they exist only on the IC), and they will be easier to use.
The main use of canister signatures is for identity solutions such as Internet Identity or the project that @neeboo is working on. If you plan to build on that, I’d suggest starting from the Internet Identity source code.
I don’t think we will provide improved library support for canister signatures (both on the canister and the verification side) soon – the main reason is that we want to focus our engineering efforts on features such as ECDSA.