|
| 1 | +--- |
| 2 | + |
| 3 | +keywords: [advanced, concept, vetkd, vetkeys, signature, BLS, threshold decryption, encrypted threshold key derivation] |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow"; |
| 8 | +import TabItem from "@theme/TabItem"; |
| 9 | +import { AdornedTabs } from "/src/components/Tabs/AdornedTabs"; |
| 10 | + |
| 11 | +# Threshold BLS signatures |
| 12 | + |
| 13 | +<MarkdownChipRow labels={["Advanced", "BLS signatures"]} /> |
| 14 | + |
| 15 | +The vetKeys feature supports threshold signing using the BLS signature scheme. BLS signatures are widely used across chains, including within ICP, due to its many useful properties, especially short deterministic signatures, excellent aggregation properties, and efficient verification. |
| 16 | + |
| 17 | +The specific variant of BLS that can be implemented using vetKeys is `BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_` as described in the BLS internet draft. |
| 18 | + |
| 19 | +Something to understand when using vetKeys to implement BLS signatures is that under the hood, all vetKeys are BLS signatures, where the message that is signed is the `input` field of `VetKDDeriveKeyArgs` and the private key that is used is derived from a master key using the `context` string. |
| 20 | + |
| 21 | +## Signing process |
| 22 | + |
| 23 | +### Step 1. Define Authentication Mechanism |
| 24 | + |
| 25 | +The backend generates signatures, and, like any other usage of vetKeys, must define some way of checking which clients are allowed to access which keys (or, here, signatures). |
| 26 | + |
| 27 | +In this example, the `context` string, which defines the BLS key that will be used, is derived using a combination of the caller's principal and an application specific identifier. This ensures that each BLS key that is used is unique to that particular user. In addition, the management canister implicitly includes the ID of the calling canister; this prevents any other canister from generating the same signatures, even if they provide the same context string during derivation. |
| 28 | + |
| 29 | +```rust reference |
| 30 | +https://github.com/dfinity/vetkeys/blob/b37e8288c50b6cb5110dfad8ffa026904cdcafdc/examples/basic_bls_signing/backend/src/lib.rs#L106-L115 |
| 31 | +``` |
| 32 | + |
| 33 | +### Step 2. Generate Signature in Backend |
| 34 | + |
| 35 | +The backend implements a method to create signatures, applying suitable access control. The signature that is returned will be a valid signature over the bytestring `input`, and the key that is used to generate the signature depends on both the canister's identifier and the `context` string. This example uses the caller's principal as part of the `context` input. This means that, while anyone can request that the canister generate a signature, only the specific caller will be able to generate signatures for their principal-specific public key. |
| 36 | + |
| 37 | +This example uses a helper function from the `ic_vetkeys` crate, `management_canister::sign_with_bls`. This function in turn calls the management canister interface. BLS signatures can be implemented using the direct management canister interface, but using `sign_with_bls` is a bit simpler and makes the intended usage of the derived vetKey clear. However, `sign_with_bls` assumes that it is acceptable for the generated BLS signature to be visible to the canister. If the signature itself needs to remain confidential, the application should follow the normal vetKey flow of generating a transport secret key on the client side and returning the encrypted signature to the caller. |
| 38 | + |
| 39 | +<AdornedTabs groupId="languages"> |
| 40 | +<TabItem value="rust" label="Rust" default> |
| 41 | + |
| 42 | +```rust reference |
| 43 | +https://github.com/dfinity/vetkeys/blob/b37e8288c50b6cb5110dfad8ffa026904cdcafdc/examples/basic_bls_signing/backend/src/lib.rs#L45-L53 |
| 44 | +``` |
| 45 | + |
| 46 | +</TabItem> |
| 47 | +</AdornedTabs> |
| 48 | + |
| 49 | +### Step 3. Request Signature In Frontend |
| 50 | + |
| 51 | +The application frontend can then invoke the canister method which returns a BLS signature for the provided message. |
| 52 | + |
| 53 | +<AdornedTabs groupId="languages"> |
| 54 | +<TabItem value="ts" label="TypeScript" default> |
| 55 | + |
| 56 | +```ts reference |
| 57 | +https://github.com/dfinity/vetkeys/blob/32215004e9204ba0caf8b4752ebd4a81a1be1b85/examples/basic_bls_signing/frontend/src/main.ts#L156-L168 |
| 58 | +``` |
| 59 | + |
| 60 | +</TabItem> |
| 61 | +</AdornedTabs> |
| 62 | + |
| 63 | +### Step 4. Determine The Public Key |
| 64 | + |
| 65 | +The canister can also implement a method which returns the public key that can be used to verify the generated signatures. This example returns the public key of the specific caller, but it could safely return the public key associated with any specified principal. |
| 66 | + |
| 67 | +<AdornedTabs groupId="languages"> |
| 68 | +<TabItem value="rust" label="Rust" default> |
| 69 | + |
| 70 | +```rust reference |
| 71 | +https://github.com/dfinity/vetkeys/blob/32215004e9204ba0caf8b4752ebd4a81a1be1b85/examples/basic_bls_signing/backend/src/lib.rs#L92-L105 |
| 72 | +``` |
| 73 | + |
| 74 | +</TabItem> |
| 75 | +</AdornedTabs> |
| 76 | + |
| 77 | +### Step 5. Verify The Signature |
| 78 | + |
| 79 | +In this example, the canister returns an unencrypted BLS signature. This signature should be verified before use, since a misbehaving canister might return an incorrect signature. The signature can be verified by any party using the `verifyBlsSignature` utility function provided in the `ic_vetkeys` TypeScript library, or alternately by using third party libraries such as TypeScript's `noble-curves` or Rust's `zkcrypto/bls12_381`. |
| 80 | + |
| 81 | +<AdornedTabs groupId="languages"> |
| 82 | +<TabItem value="ts" label="TypeScript" default> |
| 83 | + |
| 84 | +```ts reference |
| 85 | +https://github.com/dfinity/vetkeys/blob/32215004e9204ba0caf8b4752ebd4a81a1be1b85/examples/basic_bls_signing/frontend/src/main.ts#L196-L215 |
| 86 | +``` |
| 87 | + |
| 88 | +</TabItem> |
| 89 | +</AdornedTabs> |
| 90 | + |
| 91 | +## Resources |
| 92 | + |
| 93 | +- [Example BLS signing dapp](https://github.com/dfinity/vetkeys/tree/main/examples/basic_bls_signing). |
| 94 | + |
| 95 | +- [Internet Draft Specification for BLS signatures](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/) |
0 commit comments