Concordium DID Method Version 1.0

About

The Concordium DID method specification conforms to the requirements specified in Decentralized Identifiers (DIDs) v1.0 published by the W3C Credentials Community Group. For more information about DIDs and DID method specifications, please see the DID Primer and DID Spec.

Abstract

Concordium is a layer-1 blockchain with identity built into the core protocol. We distinguish the following types of DIDs:

  • Account DID refers to accounts on the Concordium blockchain.

  • Concordium Credential DID refers to a Concordium credential object.

  • Smart Contract DID refers to smart contract instances on the Concordium blockchain.

  • Public Key DID refers to a subject that knows the corresponding secret key.

  • Identity Provider DID refers to an Identity Provider - an organization, approved by Concordium, that performs off-chain identification of users.

Status of This Document

This is a draft document and may be updated.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Concordium DID Identifier

Method Name

The Concordium DID method name is ccd. A DID identifier that uses this method must begin with the following prefix: did:ccd. Per DID specification [DID] this string must be in lowercase.

Identifier Syntax

Concordium DID identifiers are defined by the following ABNF:

ccd-did = prefix ":" *1(network ":") (acctype / pkctype / scitype / idptype / credtype)
prefix  = %s"did:ccd"
network = "testnet" / "mainnet"
acctype = "acc:" 50(base58char)
pkctype = "pkc:" 64(base16char)
scitype = "sci:" index *1(“:” subindex)
idptype = "idp:" index
credtype = "cred:" 96(base16char)
index = 1*DIGIT
subindex = 1*DIGIT
base16char = HEXDIG
base58char = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
             "A" / "B" / "C" / "D" / "E" / "F" / "G" / "H" / "J" /
             "K" / "L" / "M" / "N" / "P" / "Q" / "R" / "S" / "T" /
             "U" / "V" / "W" / "X" / "Y" / "Z"

Note

In the ABNF grammar, string literals are case-insensitive, unless explicitly specified using the %s prefix.

Note

The network part of a CCD DID is optional. If omitted the network is assumed to be “mainnet” by default.

Note

The subindex part of the smart contract instance sci is optional. If omitted the subindex is assumed to be `0` by default.

Smart Contract Instance Reference Syntax

A DID reference is a DID with additional data, such as a path and query parameters. Concordium smart contract entrypoints can be addressed using DID references.

ccd-sc-ref = "/" entrypoint *1("/" parameter)
parameter = base16char
entrypoint = 1*(ALPHA / DIGIT / punctuation)
punctuation = "!" / DQUOTE / "#" / "$" / "%" / "&" / "'" / "(" /
              ")" / "*" / "+" / "," / "-" / "." / "/" / ";" /
              "<" / "=" / ">" / "?" / "@" / "[" / "\" / "]" /
              "^" / "_" / "`" / "{" / "|" / "}" / "~"

See the details about dereferencing a smart contract instance reference in Smart Contract Instance Reference.

Examples

An account on testnet:

did:ccd:testnet:acc:3ZFGxLtnUUSJGW2WqjMh1DDjxyq5rnytCwkSqxFTpsWSFdQnNn

A Concordium credential on mainnet

did:ccd:mainnet:cred:9aa3641a212da36a9ffae6e6085b9cf486ca9b44fa059aa74565b0a1c0f7052d8e71168beccf299d767f3961b33aaae2

A smart contract instance on the default network (mainnet):

did:ccd:sci:12:0

A public key:

did:ccd:pkc:0c7f4421e44a4385850b883e3bbf098f5a9853ef6f1a862c2ce2856381b5f5e3

A smart contract instance with the issuerKeys entrypoint that does not take any parameters

did:ccd:sci:321/issuerKeys

A smart contract instance with the credentialEntry entrypoint taking a parameter

did:ccd:sci:123/credentialEntry/ee763364dc1a47d6aa4cc6bdb005e2b2

Concordium DID Documents

Account DID

The goal of the Account DID Document is to provide information about the account authentication data, including a possibility to reference particular pieces of data, such as public keys. In order to do that, it specifies a DID verification method that reflects the account authentication data: public keys grouped into credentials.

The Account DID Document MUST contain the following data:

  • id - the DID of the account.

  • verificationMethod - the account’s verification method. It is a nested threshold scheme requiring T out of M credentials to sign; each credential uses its own threshold scheme requiring R_i out of N_i keys to sign, where i = 1..M.and j = 1..N_i. The credentials are identified by a DID fragment #credential-i, and the keys in each credentials by #key-j-i where i = 1..M and j = 1..N_i.

  • authentication - authentication method for the account.

The document MAY include any other public data of a Concordium account.

Note

A DID fragment allows for referencing a particular credential, or a key in the Account DID Document. The fragment is used to locate the (unique) JSON object by matching the DID URL with the object’s id property.

See also

Dereferencing a DID URL in the W3C Credentials Community Group draft report.

{
  "id": "did:ccd:NET:acc:ADDR",
  "verificationMethod": [
    {
      "id": "did:ccd:NET:acc:ADDR#acc-vm",
      "controller": "did:ccd:NET:acc:ADDR",
      "type": "VerifiableCondition2021",
      "blockchainAccountId": "ADDR",
      "threshold": "T",
      "conditionThreshold": [
        {
          "verificationMethod": [
            {
              "id": "did:ccd:NET:acc:ADDR#credential-1",
              "controller": "did:ccd:NET:acc:ADDR",
              "type": "VerifiableCondition2021",
              "threshold": "R_1",
              "conditionThreshold": [
                {
                  "id": "did:ccd:NET:acc:ADDR#key-1-1",
                  "type": "Ed25519VerificationKey2020",
                  "controller": "did:ccd:NET:acc:ADDR",
                  "publicKeyMultibase": "fXX"
                },
                "...",
                {
                  "id": "did:ccd:NET:acc:ADDR#key-N_1-1",
                  "type": "Ed25519VerificationKey2020",
                  "controller": "did:ccd:NET:acc:ADDR",
                  "publicKeyMultibase": "fYY"
                }
              ]
            }
          ]
        },
        "...",
        {
          "verificationMethod": [
            {
              "id": "did:ccd:NET:acc:ADDR#credential-M",
              "controller": "did:ccd:NET:acc:ADDR",
              "type": "VerifiableCondition2021",
              "threshold": "N",
              "conditionThreshold": [
                {
                  "id": "did:ccd:NET:acc:ADDR#key-1-M",
                  "type": "Ed25519VerificationKey2020",
                  "controller": "did:ccd:NET:acc:ADDR",
                  "publicKeyMultibase": "fVV"
                },
                "...",
                {
                  "id": "did:ccd:NET:acc:ADDR#key-N_M-M",
                  "type": "Ed25519VerificationKey2020",
                  "controller": "did:ccd:NET:acc:ADDR",
                  "publicKeyMultibase": "fZZ"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "authentication": [
    "#acc-vm"
  ]
}

Note

The publicKeyMultibase field contains a public key prefixed with f that denotes the base16 encoding. See The Multibase Encoding Scheme.

Concordium Credential DID

The goal of the Concordium Credential DID Document is to provide information about Concordium credentials, including a possibility to reference particular pieces of data, such as public keys. In order to do that, it specifies a DID verification method that reflects the credential authentication data.

The Concordium Credential DID Document MUST contain the following data:

  • id - the DID of the credential.

  • verificationMethod - the credential’s verification method.

  • authentication - authentication method for the credential.

The document MAY include any other public data of a Concordium credential.

The following document defines a Concordium credential with ID CRED. The credential has N keys and uses a threshold signature scheme requiring T signatures.

{
  "id": "did:ccd:NET:cred:CRED",
  "verificationMethod": [
    {
      "did:ccd:NET:cred:CRED#credential-vm"
      "type": "VerifiableCondition2021",
      "threshold": "T",
      "conditionThreshold": [
        {
          "id": "did:ccd:NET:cred:CRED#key-1",
          "type": "Ed25519VerificationKey2020",
          "controller": "did:ccd:NET:cred:CRED",
          "publicKeyMultibase": "fXX"
        },
        "...",
        {
          "id": "did:ccd:NET:cred:CRED#key-N",
          "type": "Ed25519VerificationKey2020",
          "controller": "did:ccd:NET:cred:CRED",
          "publicKeyMultibase": "fYY"
        }
      ]
    }
  ],
  "authentication": [
    "#credential-vm"
  ]
}

Smart Contract Instance DID

The goal of the Smart Contract Instance DID is to provide metadata about the contract instance. At the moment, it contains an account address of the initialization transaction sender, and the list of the contract’s entrypoints.

The Smart Contract Instance DID Document MUST contain the following data:

  • id - the DID of the smart contract instance.

  • creator - a DID of an account that initialized the contract instance represented as a JSON object containing fields id and account.

  • entrypoints - a list on the contract’s entrypoints. Each entrypoint is an object containing fields id and name.

The document MAY include any other public data of a smart contract instance.

{
  "id": "did:ccd:sci:IND:SUBIND",
  "owner": {
    "id": "did:ccd:sci:IND:SUBIND#creator",
    "account": "did:ccd:NET:acc:ADDR"
  }
  "entrypoints": [
    { "id": "did:ccd:sci:IND:SUBIND#entrypoint-issuerKeys",
      "name": "issuerKeys"
    },
    { "id": "did:ccd:sci:IND:SUBIND#entrypoint-revocationKey",
      "name": "revocationKey"
    }
  ]
}

Where IND and SUBIND are the contract index and subindex. NET and ADDR correspond to the network and to the owner’s account address respectively.

Public Key Cryptography DID

The goal of the Public Key Cryptography DID is to represent a public key and the corresponding signature verification method.

The Public Key Cryptography DID Document MUST contain the following data:

  • id - the DID of the public key.

  • verificationMethod - specifies a DID verification method for verifying a signature corresponding to the public key.

  • authentication - authentication method for the key.

{
  "id": "did:ccd:pkc:XX",
  "verificationMethod": [
    {
      "id": "did:ccd:pkc:XX#key-0",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:ccd:NET:pkc:PK",
      "publicKeyMultibase": "fXX"
    }
  ],
  "authentication": [
    {
      "did:ccd:pkc:XX#key-0"
    }
  ]
}

Identity Provider DID

The goal of the Identity Provider DID is identify a Concordium identity provider. An identity provider (IDP) is an organization, approved by Concordium, that performs off-chain identification of users. Identity providers are used in the account creation process to issue an identity. Identity provider DIDs can represent an issuer of a verifiable credential.

The Identity Provider DID Document MUST contain the following data:

  • id - the DID of the IDP.

  • name - the IDP name.

  • url - A link to more information about the IDP.

  • description - A free form description the IDP.

  • verificationMethod - specifies a DID verification method for verifying a signature corresponding to the public key.

{
  "id": "did:ccd:testnet:idp:0",
  "name": "Concordium testnet IP",
  "url": "",
  "description": "Concordium testnet identity provider",
  "verificationMethod": [
    {
      "id": "did:ccd:testnet:idp:0#cdi-key",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:ccd:testnet:idp:0",
      "publicKeyMultibase": "fXX"
    }
  ]
}

Concordium DID Operations

Concordium DIDs are managed on the Concordium blockchain.

Create

Account DID

An account DID can be created by opening an account on the NET blockchain. The resulting DID is did:ccd:NET:acc:ADDR where ADDR is the base58 encoded account address.

Concordium Credential DID

A Concordium Credential DID is created as part of the account opening process, or by adding a Concordium credential to an existing account.

Smart Contract Instance DID

A smart contract instance DID can be created by deploying a smart contract module and initializing a smart contract instance on the NET blockchain. The resulting DID is did:ccd:NET:sci:IND:SUBIND where IND, SUBIND are the index and the subindex of the instance.

Public Key Cryptography DID

A public key cryptography DID can be created by generating a fresh Ed25519 key pair. The resulting DID is did:ccd:NET:pkc:PK where PK is the base16 encoded public key. These DIDs are not registered on the blockchain.

Identity Provider DID

Identity providers can be added as a chain update transaction of type UpdateAddIdentityProvider.

Read

Account DID

The DID document information for a DID of the form

did:ccd:NET:acc:ADDR

can be resolved by looking up an account with address ADDR on blockchain NET.

Data required to construct the DID document can be acquired by using the gRPC interface command GetAccountInfo.

See the details in the gRPC v2 documentation.

From the command line, concordium-client allows retrieving the data in the following way:

$concordium-client raw GetAccountInfo ADDR

Concordium Credential DID

The DID document information for a DID of the form

did:ccd:NET:cred:CRED

can be resolved by looking up a credential with ID CRED on blockchain NET.

Data required to construct the DID document can be acquired by using the same gRPC interface command GetAccountInfo as for Concordium account DIDs.

Smart Contract Instance DID

The DID document information for a DID of the form

did:ccd:NET:sci:IND:SUBIND

can be resolved by looking up a smart contract instance with indices IND, SUBIND on blockchain NET. This includes a lookup of the owner’s account.

Data required to construct the DID document can be acquired by using the gRPC interface command GetInstanceInfo.

See the details in the gRPC v2 documentation.

From the command line, concordium-client allows retrieving the data in the following way:

$concordium-client contract show IND

Smart Contract Instance Reference

Dereferencing the smart contract DID reference invokes the specified entrypoint.

Dereferencing a DID reference of the form

did:ccd:NET:sci:IND:SUBIND/EP[/PAR]

can be done by using the gRPC interface command InvokeInstance. The entrypoint is considered a view: no state changes are persisted, only the result of the invocation is returned to the caller. The parameter PAR is passed to the entrypoint.

The result of the invocation is the return value produced by the contract or an error if the invocation fails.

If the contract contains an embedded schema, then the response is the following:

{
  "type" : "json",
  "data": "JSON"
}

Where JSON is the JSON rendering of the response.

If the contract does not contain an embedded schema, then the response is the following:

{
  "type" : "raw",
  "data": "BASE16DATA"
}

Where BASE16DATA is a base16-encoded return value.

From the command line, concordium-client allows invoking a smart contract instance in the following way:

$concordium-client contract invoke IND --entrypoint EP --parameter-binary param.bin

The base16 encoding of the param.bin file corresponds to PAR.

See the details in the gRPC v2 documentation.

See also

Dereferencing a DID URL in the W3C Credentials Community Group draft report.

Public Key Cryptography DID

The DID document corresponding to a DID of the form

did:ccd:NET:pkc:PK

can be constructed directly from the DID without any lookup necessary.

Note

The NET part is optional and currently there is no difference how the documents are generated for different networks. In the future, however, the vefiricationMethod as it specified in Public Key Cryptography DID might depend on the network.

Identity Provider DID

The DID document information for a DID of the form

did:ccd:NET:idp:INDEX

can be resolved by looking up an identity provider INDEX on blockchain NET.

Data required to construct the DID document can be acquired by using the gRPC interface command GetIdentityProviders.

See the details in the gRPC v2 documentation.

From the command line, concordium-client allows retrieving the data in the following way:

$concordium-client raw GetIdentityProviders

Update

Account DID

It is possible to update Account DID documents by sending an update credentials transaction. This type of transaction allows for adding/removing credentials and changing the signature threshold.

Concordium Credential DID

It is possible to update Concordium Credential DID documents by sending an update credentials keys transaction. This type of transaction allows for updating the keys associated with a Concordium credential and the corresponding signature threshold.

Deactivate

Concordium Credential DID

A Concordium Credential DID can be deactivated by removing the corresponding credential with an update credentials transaction.

Security Considerations

The did:ccd method is built on top the Concordium blockchain, a public permissionless distributed ledger (DL). Security of the DID method reduces to the security of the underlying blockchain protocol. This concerns attacks such as eavesdropping, replay, message insertion, deletion, modification, denial of service, amplification, and man-in-the-middle.

Parties SHOULD run a full node of the underlying blockchain protocol to ensure that they can read and write securely to the DL.

Authorization is performed by means of digital signature keys. Leakage of private keys allows an attacker to take control. Therefore, parties MUST handle private keys with care.

Privacy Considerations

DIDs SHOULD be assumed to be pseudonyoums and public as they might be stored on the underlying DL. Correlation attacks MAY be possible if information assocciated to DIDs is published. It is therefore NOT RECOMMENDED to reuse PKC DIDs.

Appendices

Threshold Verification Method

The threshold verification method used in Concordium DID Documents is based on a ConditionalProof verification method. This is a new type of verification method under development. ConditionalProof features several extensions such as logical operations (and, or), threshold and weighted threshold. Note that the method is not yet a W3C standard and currently has a draft status.

The example below shows the 2-out-of-3 signature verification method. It uses the ConditionalProof2022 verification method. It specifies conditionThreshold with three keys key-1, key-2 and key-3; each signature can be verified using Ed25519VerificationKey2020. The document that uses the 2-out-of-3 method is valid if it has at least two valid signatures.

{
  "id": "did:example:123#2-out-of-3",
  "controller": "did:example:123",
  "type": "ConditionalProof2022",
  "threshold": 2,
  "conditionThreshold": [
    {
      "id": "did:example:123#key-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "...",
      "publicKeyMultibase": "..."
    },
    {
      "id": "did:example:123#key-2",
      "type": "Ed25519VerificationKey2020",
      "controller": "...",
      "publicKeyMultibase": "..."
    },
    {
      "id": "did:example:123#key-3",
      "type": "Ed25519VerificationKey2020",
      "controller": "...",
      "publicKeyMultibase": "..."
    }
  ]
}