From 6bb1273c234ed925e569a421388d814baff70001 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Wed, 15 Oct 2025 14:00:44 +0200 Subject: [PATCH 1/4] New RFC: BLS12-381 signatures --- text/0000-bls-signatures.md | 225 ++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 text/0000-bls-signatures.md diff --git a/text/0000-bls-signatures.md b/text/0000-bls-signatures.md new file mode 100644 index 000000000..435c1909e --- /dev/null +++ b/text/0000-bls-signatures.md @@ -0,0 +1,225 @@ +# RFC-0000: Add host functions to produce and verify BLS signatures + +| | | +| --------------- | ------------------------------------------------------------------------------------------- | +| **Start Date** | 2025-10-14 | +| **Description** | Introduce BLS12-381 host function | +| **Author** | Someone Unknown | + +## Summary + +Introduce new host functions allowing runtimes to generate BLS12-381 keys, signatures, and proofs of possession. + +## Credits + +BLS implementation and initial host functions implementation are authored by Seyed Hosseini and co-authored by Davide Galassi. + +## Interaction with other RFCs + +This RFC respects the runtime-side memory allocation strategy that will be introduced by [RFC-145](https://github.com/polkadot-fellows/RFCs/pull/145). + +## Motivation + +New functions are required to equip BEEFY with BLS signatures, which are essential for the accountable light client protocol. + +## Stakeholders + +Runtime developers who will be able to use the new signature types. + +## Explanation + +This RFC proposes introducing new host functions as follows. + +### ext_crypto_bls381_generate + +Generates a BLS12-381 key for the given key type using an optional `seed`, stores it in the keystore, and returns a corresponding public key. + +#### Prototype + +```wat +(func $ext_crypto_bls381_generate_version_1 + (param $id i32) (param $seed i64) (param $out i32)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `seed` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a SCALE-encoded Option value ([Definition 200](https://spec.polkadot.network/id-cryptography-encoding#defn-option-type)) containing a BIP-39 seed which must be valid UTF-8. The function will panic if the seed is not a valid UTF-8; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 144 bytes long, where the public key will be written. + +### ext_crypto_bls381_generate_proof_of_possession + +Generates a BLS12-381 Proof Of Possession for a given public key and owner identifier. + +#### Prototype + +```wat +(func $ext_crypto_bls381_generate_proof_of_possession_version_1 + (param $id i32) (param $pub_key i32) (param $owner i64) (param $out i32) (result i64)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `pub_key` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a public key, 144 bytes long; +* `owner` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to an opaque owner identifier; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 224 bytes long, where the proof of possession will be written. + +#### Result + +The function returns `0` on success. On error, `-1` is returned, and the output buffer should be considered uninitialized. + +### ext_crypto_bls381_num_public_keys + +Retrieves the number of BLS12-381 keys of the given type available in the keystore. + +#### Prototype + +```wat +(func $ext_crypto_bls381_num_public_keys_version_1 + (param $id i32) (result i32)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid. + +#### Result + +The result represents a (possibly zero) number of keys of the given type known to the keystore. + +### ext_crypto_bls381_public_key + +Retrieves a BLS12-381 public key of a given type at a given index from the keystore. + +#### Prototype + +```wat +(func $ext_crypto_bls381_public_key_version_1 + (param $id i32) (param $index i32) (param $out)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `index` is an index of the key in the keystore. If the index is out of bounds (determined by the value returned by the `ext_crypto_bls381_num_public_keys` function), the function will panic; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 144 bytes long, where the key will be written. + +### ext_crypto_bls381_sign + +Signs an input message using a given BLS12-381 key. + +#### Prototype + +```wat +(func $ext_crypto_bls381_sign_version_1 + (param $id i32) (param $pub_key i32) (param $msg i64) (param $out i64) (result i64)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `pub_key` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to public key bytes (as returned by `ext_crypto_bls381_public_key` function); +* `msg` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a message that is to be signed; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 112 bytes long, where the signature will be written. + +#### Result + +The function returns `0` on success. On error, `-1` is returned, and the output buffer should be considered uninitialized. + +### ext_crypto_ecdsa_bls381_generate + +Generates a combination ECDSA & BLS12-381 key for a given key type using an optional `seed`, stores it in the keystore, and returns the corresponding public key. + +#### Prototype + +```wat +(func $ext_crypto_ecdsa_bls381_generate_version_1 + (param $id i32) (param $seed i64) (param $out i32)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `seed` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a SCALE-encoded Option value ([Definition 200](https://spec.polkadot.network/id-cryptography-encoding#defn-option-type)) containing a BIP-39 seed which must be valid UTF-8. The function will panic if the seed is not a valid UTF-8; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 177 bytes long, where the public key will be written. + +### ext_crypto_ecdsa_bls381_num_public_keys + +Retrieves the number of ECDSA & BLS12-381 keys of a given type available in the keystore. + +#### Prototype + +```wat +(func $ext_crypto_ecdsa_bls381_num_public_keys_version_1 + (param $id i32) (result i32)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid. + +#### Result + +The result represents a (possibly zero) number of keys of the given type known to the keystore. + +### ext_crypto_ecdsa_bls381_public_key + +Retrieves an ECDSA & BLS12-381 public key of a given type at a given index from the keystore. + +#### Prototype + +```wat +(func $ext_crypto_ecdsa_bls381_public_key_version_1 + (param $id i32) (param $index i32) (param $out)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `index` is an index of the key in the keystore. If the index is out of bounds (determined by the value returned by the `ext_crypto_ecdsa_bls381_num_public_keys` function), the function will panic; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 177 bytes long, where the key will be written. + +### ext_crypto_ecdsa_bls381_sign + +Signs an input message using a given ECDSA & BLS12-381 key. + +#### Prototype + +```wat +(func $ext_crypto_ecdsa_bls381_sign_version_1 + (param $id i32) (param $pub_key i32) (param $msg i64) (param $out i64) (result i64)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `pub_key` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to public key bytes (as returned by `ext_crypto_ecdsa_bls381_public_key` function); +* `msg` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a message that is to be signed; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 177 bytes long, where the signature will be written. + +#### Result + +The function returns `0` on success. On error, `-1` is returned, and the output buffer should be considered uninitialized. + +### ext_crypto_ecdsa_bls381_sign_with_keccak256 + +Hashes a message using Keccak256 and then signs it using the ECDSA algorithm. It does not affect the behavior of the BLS12-381 component. Generates a BLS12-381 signature according to the IETF standard. + +#### Prototype + +```wat +(func $ext_crypto_ecdsa_bls381_sign_with_keccak256_version_1 + (param $id i32) (param $pub_key i32) (param $msg i64) (param $out i64) (result i64)) +``` + +#### Arguments + +* `id` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to a key type identifier ([Definition 220](https://spec.polkadot.network/chap-host-api#defn-key-type-id)). The function will panic if the identifier is invalid; +* `pub_key` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to public key bytes (as returned by `ext_crypto_ecdsa_bls381_public_key` function); +* `msg` is a pointer-size ([Definition 216](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer-size)) to a message that is to be signed; +* `out` is a pointer ([Definition 215](https://spec.polkadot.network/chap-host-api#defn-runtime-pointer)) to an output buffer, 177 bytes long, where the signature will be written. + +#### Result + +The function returns `0` on success. On error, `-1` is returned, and the output buffer should be considered uninitialized. From 8b35748ff59aba0e62e54a65d9ccfdc3acf71e49 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Wed, 15 Oct 2025 14:06:00 +0200 Subject: [PATCH 2/4] Assign RFC number --- text/{0000-bls-signatures.md => 0156-bls-signatures.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename text/{0000-bls-signatures.md => 0156-bls-signatures.md} (98%) diff --git a/text/0000-bls-signatures.md b/text/0156-bls-signatures.md similarity index 98% rename from text/0000-bls-signatures.md rename to text/0156-bls-signatures.md index 435c1909e..465ae144d 100644 --- a/text/0000-bls-signatures.md +++ b/text/0156-bls-signatures.md @@ -1,8 +1,8 @@ -# RFC-0000: Add host functions to produce and verify BLS signatures +# RFC-0156: Add host functions to produce and verify BLS signatures | | | | --------------- | ------------------------------------------------------------------------------------------- | -| **Start Date** | 2025-10-14 | +| **Start Date** | 2025-10-15 | | **Description** | Introduce BLS12-381 host function | | **Author** | Someone Unknown | From 55fb059aee1471e5735e42caae262afaac7c2133 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Wed, 15 Oct 2025 14:08:06 +0200 Subject: [PATCH 3/4] Fix header --- text/0156-bls-signatures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0156-bls-signatures.md b/text/0156-bls-signatures.md index 465ae144d..52d141314 100644 --- a/text/0156-bls-signatures.md +++ b/text/0156-bls-signatures.md @@ -1,4 +1,4 @@ -# RFC-0156: Add host functions to produce and verify BLS signatures +# RFC-0156: Add BLS12-381 Host Functions | | | | --------------- | ------------------------------------------------------------------------------------------- | From d35397c3479c3054c8a4ca317f172623f25134c1 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Wed, 15 Oct 2025 14:08:52 +0200 Subject: [PATCH 4/4] Minor typo --- text/0156-bls-signatures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0156-bls-signatures.md b/text/0156-bls-signatures.md index 52d141314..1e597c716 100644 --- a/text/0156-bls-signatures.md +++ b/text/0156-bls-signatures.md @@ -3,7 +3,7 @@ | | | | --------------- | ------------------------------------------------------------------------------------------- | | **Start Date** | 2025-10-15 | -| **Description** | Introduce BLS12-381 host function | +| **Description** | Introduce BLS12-381 host functions | | **Author** | Someone Unknown | ## Summary