Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: DID signature generation for DIP #14

Merged
merged 3 commits into from
May 12, 2023
Merged

Conversation

ntn-x2
Copy link
Member

@ntn-x2 ntn-x2 commented May 12, 2023

@ntn-x2 ntn-x2 self-assigned this May 12, 2023
@ntn-x2 ntn-x2 merged commit 54c7d43 into aa/dip May 12, 2023
@ntn-x2 ntn-x2 deleted the aa/dip-did-signatures branch May 12, 2023 12:07
ntn-x2 added a commit to KILTprotocol/kilt-node that referenced this pull request May 22, 2023
Fixes KILTprotocol/ticket#2553.

The main changes are:
* Removed half-baked versioning support, to re-introduce a proper one
once versioning and version negotiation will be tackeld
* Moved most of the logic from the `runtime-common` crate to a new
`kilt-dip-support` crate, after making all the types generic over all
the runtime configurations
* Updated the `pallet-dip-consumer` pallet to have a bunch more details,
more info below
* Updated the XCM-simulator based tests

## Updates to the `dip-support` crate

The `dip-support` does not contain any versioned types anymore. Support
for versioning was half-baked and has been removed. Proper thought
around versioning and version negotiation will happen in the (short)
future.

## New `kilt-dip-support` crate

The new `kilt-dip-support` crate contains types and traits that are not
generic over ANY DIP deployment, but that can be used by every consumer
that relies on the KILT chain as their provider. Hence, types are
opinionated towards the way KILT implements the DIP protocol, but
generic over the runtime configuration.
The most relevant types are `MerkleProofAndDidSignatureVerifier`,
exported from the root, `DidMerkleProofVerifier`, exported from the
`merkle` module, and `DidSignatureAndCallVerifier`, exported from the
`did` module. When they are chained together, they allow a user to
submit a Merkle proof revealing parts of their DID Document, and to use
one of the revealed keys to sign a specifically-crafted payload which
provides authenticity guarantees of the DID subject.

The default verification logic for the DID signature is the following:
1. Verify that the block number specified in the signature is no older
than `SIGNATURE_VALIDITY` blocks, as specified by the runtime
2. Verify that the signature can be verified over the encoded tuple
formed by `(call, identity_details, submitter_address, block_number,
genesis_hash, signed_extra)`, where `signed_extra` can be anything more
that the runtime might require be included in the signature.
3. Verify that one of the keys revealed in the Merkle proof can be used
to verify the provided signature
4. [OPTIONAL] If the type variant which also performs authorization
checks on the call itself is used, i.e., the
`DidSignatureAndCallVerifier` type, then the verification will also
include checking whether the used verification relationship can be used
to dispatch the specified call or not, as we do ourselves in our did
pallet within the `submit_did_call`, but in a more generic way.

The verification logic for Merkle proofs has remained unchanged, and it
can now be chained with the DID verification logic.

## Refreshed `pallet-dip-consumer`

The pallet has been updated so that now the `dispatch_as` extrinsic
takes a generic `Proof` instead of an `IdentityProof`, and internally
performs the following checks:

1. Verify the origin is a signed origin (as before)
2. Verify that the call passes a preliminary filter, before any heavy
computation is executed on the provided proof, via the
`DipCallOriginFilter` type. This step will typically immediately filter
out any calls that cannot be called with a Dip origin regardless of the
content of the proof.
3. Retrieves the identity details from storage, if they exist
4. Delegate everything to the `ProofVerifier`, which has a mutable
reference to the details fetched at step 3, in case they need to update
some values that will be written to storage (e.g., the nonce)
5. The maybe mutated details are written back into storage
6. The call is dispatched with the new `DipOrigin`, which carries the
additional information as returned by the `ProofVerifier`. In the demo
runtime, this will be the set of keys revealed as part of the Merkle
proof, that have been verified, parsed, and used for verifying the DID
signature provided as part of the proof.

The pallet logic is very simple, and most of the (complex) logic lies in
the types that have been exposed as part of the `kilt-dip-support`
crate. This makes the pallet easier to understand, and more generic to
be used in different contexts potentially for different identity
providers as well, where each provider might require users to provide a
different identity proof.

## Minor changes

Other things have been updated to reflect the relocation of some files
into the new `kilt-dip-support` crate.

## How to test

1. Build [this version](KILTprotocol/sdk-js#751)
of the SDK
2. Clone and `yarn install && yarn build` [this
version](https://github.com/KILTprotocol/polkadot-apps/pull/8) of the
PolkadotJS apps
3. Copy-paste the `@kiltprotocol/type-definitions` output into the root
`node_modules` folder of the PolkadotJS apps
4. Follow the steps to set up the HRMP channels, create the DIDs, and
push the identity commitment from provider to consumer
5. Use [this
version](KILTprotocol/kilt-did-utilities#14) of
the kilt-did-utilities CLI tool to generate a valid DIP DID signature.
6. Enjoy ☀️☀️☀️
ntn-x2 added a commit to KILTprotocol/kilt-node that referenced this pull request May 22, 2023
Fixes KILTprotocol/ticket#2553.

The main changes are:
* Removed half-baked versioning support, to re-introduce a proper one
once versioning and version negotiation will be tackeld
* Moved most of the logic from the `runtime-common` crate to a new
`kilt-dip-support` crate, after making all the types generic over all
the runtime configurations
* Updated the `pallet-dip-consumer` pallet to have a bunch more details,
more info below
* Updated the XCM-simulator based tests

## Updates to the `dip-support` crate

The `dip-support` does not contain any versioned types anymore. Support
for versioning was half-baked and has been removed. Proper thought
around versioning and version negotiation will happen in the (short)
future.

## New `kilt-dip-support` crate

The new `kilt-dip-support` crate contains types and traits that are not
generic over ANY DIP deployment, but that can be used by every consumer
that relies on the KILT chain as their provider. Hence, types are
opinionated towards the way KILT implements the DIP protocol, but
generic over the runtime configuration.
The most relevant types are `MerkleProofAndDidSignatureVerifier`,
exported from the root, `DidMerkleProofVerifier`, exported from the
`merkle` module, and `DidSignatureAndCallVerifier`, exported from the
`did` module. When they are chained together, they allow a user to
submit a Merkle proof revealing parts of their DID Document, and to use
one of the revealed keys to sign a specifically-crafted payload which
provides authenticity guarantees of the DID subject.

The default verification logic for the DID signature is the following:
1. Verify that the block number specified in the signature is no older
than `SIGNATURE_VALIDITY` blocks, as specified by the runtime
2. Verify that the signature can be verified over the encoded tuple
formed by `(call, identity_details, submitter_address, block_number,
genesis_hash, signed_extra)`, where `signed_extra` can be anything more
that the runtime might require be included in the signature.
3. Verify that one of the keys revealed in the Merkle proof can be used
to verify the provided signature
4. [OPTIONAL] If the type variant which also performs authorization
checks on the call itself is used, i.e., the
`DidSignatureAndCallVerifier` type, then the verification will also
include checking whether the used verification relationship can be used
to dispatch the specified call or not, as we do ourselves in our did
pallet within the `submit_did_call`, but in a more generic way.

The verification logic for Merkle proofs has remained unchanged, and it
can now be chained with the DID verification logic.

## Refreshed `pallet-dip-consumer`

The pallet has been updated so that now the `dispatch_as` extrinsic
takes a generic `Proof` instead of an `IdentityProof`, and internally
performs the following checks:

1. Verify the origin is a signed origin (as before)
2. Verify that the call passes a preliminary filter, before any heavy
computation is executed on the provided proof, via the
`DipCallOriginFilter` type. This step will typically immediately filter
out any calls that cannot be called with a Dip origin regardless of the
content of the proof.
3. Retrieves the identity details from storage, if they exist
4. Delegate everything to the `ProofVerifier`, which has a mutable
reference to the details fetched at step 3, in case they need to update
some values that will be written to storage (e.g., the nonce)
5. The maybe mutated details are written back into storage
6. The call is dispatched with the new `DipOrigin`, which carries the
additional information as returned by the `ProofVerifier`. In the demo
runtime, this will be the set of keys revealed as part of the Merkle
proof, that have been verified, parsed, and used for verifying the DID
signature provided as part of the proof.

The pallet logic is very simple, and most of the (complex) logic lies in
the types that have been exposed as part of the `kilt-dip-support`
crate. This makes the pallet easier to understand, and more generic to
be used in different contexts potentially for different identity
providers as well, where each provider might require users to provide a
different identity proof.

## Minor changes

Other things have been updated to reflect the relocation of some files
into the new `kilt-dip-support` crate.

## How to test

1. Build [this version](KILTprotocol/sdk-js#751)
of the SDK
2. Clone and `yarn install && yarn build` [this
version](https://github.com/KILTprotocol/polkadot-apps/pull/8) of the
PolkadotJS apps
3. Copy-paste the `@kiltprotocol/type-definitions` output into the root
`node_modules` folder of the PolkadotJS apps
4. Follow the steps to set up the HRMP channels, create the DIDs, and
push the identity commitment from provider to consumer
5. Use [this
version](KILTprotocol/kilt-did-utilities#14) of
the kilt-did-utilities CLI tool to generate a valid DIP DID signature.
6. Enjoy ☀️☀️☀️
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant