Decentralized identifiers (DID)

Decentralized identifiers (DIDs) are a new type of identifier that enables verifiable, decentralized digital identity.

DIDs are unique universally resolvable identifiers. A DID represents a subject, which can be a person, but also an organization, object, document, etc. There is no central register that registers all DIDs. Instead, there a DID has a method that indicates how it can be resolved.

Decentralized identifiers are a W3C standard. LTO Network implements v1.0.

Resolving a DID results in a DID document. This document contains cryptographic material that allows the DID controller to prove control of the DID.

What proofing control of a DID means depends on the subject. If the DID represents a person, it allows that person to identify themselves. In case the DID represents an object, it allows a person to prove he owns that object.

DID documents do not contain other (identifying) information, like a name, address, etc.

DID vs account

A decentralized identifier (DID) isn't the same as an account. Both correspond with a blockchain address. However, an account is based on a single public/private key pair. A DID can have multiple verification methods, managed through associations.

LTO DID method

DID with the method "lto" can be resolved by the LTO Network identity node.

The method-specific string is an address on the public chain. In the case of derived DIDs, it's followed by a path.

lto-did = "did:lto:" lto-address
lto-address = 35\*( ALPHA / DIGIT )

The address is case-sensitive.

Implicit DID

Any address on the LTO public chain can be represented by a DID. The DID document always contains a single verification method containing the public key of the account. This method is applicable for both authentication and assertion.

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH",
  "verificationMethod": [
    {
      "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH",
      "publicKeyMultibase": "zmMyJxTQuXW9bQVLmJeCrWNCSKzsEMkbZQ3xuNavj6Mk"
    },
  ],
  "authentication": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign"
  ],
  "assertionMethod": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign"
  ],
  "keyAgreement": [
    {
      "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#encrypt",
      "type": "X25519KeyAgreementKey2019",
      "controller": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH",
      "publicKeyMultibase": "zmMyJxTQuXW9bQVLmJeCrWNCSKzsEMkbZQ3xuNavj6Mk"
    },
  ],
  "capabilityInvocation": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign"
  ],
  "capabilityDelegation": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign"
  ]
}

It's only possible to resolve a DID for accounts for which the public key is known on-chain. This is the case for any account that has signed at least one on-chain transaction.

Verification methods

It's possible to explicitly specify verification methods for a DID document using associations. An association with the type 0x0100 specifies that the public key of the association recipient is a valid verification method for the association sender.

The subject field of the association transaction should not be set.

The public key of the recipient must be known. The register transaction allows the management account to register the public keys of all verification methods.

Revocation

The verification method can be revoked using a Revoke Association transaction with association type 0x100 and an empty subject.

Key type

LTO Network supports 3 cryptographic algorithms: ed25519, secp256k1, and secp256r1.

Expiration

Association transactions support expiration. Set the expires field to add a verification method that's automatically revoked at a specific date.

The expiration date can be changed by issuing a new association with an updated expires field.

Verification relationships

Different verification relationships enable the associated verification methods to be used for different purposes. It is up to a verifier to ascertain the validity of a verification attempt by checking that the verification method used is contained in the appropriate verification relationship.

By default, a verification method does not have any relationships. These can be specified in the data property of the association transaction, using the relationship as key and true as value.

To change the relationships of an existing verification method, issue a new Association transaction with updated data.

Encryption

For ed25519 accounts, the key relationship verification method must have type X25519KeyAgreementKey2019. The X25519 public key is generated from the ED25519 public key used to sign a transaction.

For secp256k1 and secp256r1 accounts, you can use EcdsaSecp256k1VerificationKey2019 for encryption. We support ECIES Hybrid Encryption. However, this may not be understood by verifiers.

Management key

The key pair of the main account of the DID is known as the management key. This is the only key that can sign for any on-chain transaction. That means it's the only key that can be used to modify the DID document.

Giving a verification method capability relationships does not allow it to do on-chain transactions. In case you want to allow other keys to modify the DID document and make changes in a trust network, you must use a smart account script.

You should not add verification methods with capability relationships without using a smart account.

By default, the management key has all verification relationships. To change the relationships, issue an association with type 0x100, setting the data to include specific relationships.

It's recommended to use the management key only for on-chain transactions and remove the authentication, assertion and key agreement relationships.

Deactivation

If the management key is compromised, the DID should no longer be used. Issuing a statement with type 0x120, will mark the DID as deactivated.

In addition, it will revoke all verification methods, including the management key. This ensures that the DID document can't be used, including implementations that don't check the metadata.

It's not possible to only revoke the management key, without also revoking all other verification methods.

The recipient of the statement transaction should be omitted. Optionally, a reason can be specified as data entry.

Deactivating the DID account does not prevent the associated account to do transactions on the public chain or private layer.

Trusted party deactivation

Creating an association with type 0x108 will add a key that can be used to deactivate the DID. This key will be listed in the capabilityInvocation relationship (and not as a generic verification method).

The main reason to use this is to allow a trusted authorized party to deactivate a DID document in case the management key is lost.

An authorized party can deactivate a DID using a statement transaction with type 0x121. The recipient of that statement should be the address of the management key of the DID. Optionally a reason can be specified as data entry.

Adding a verification method through an association with type 0x100 and with the capability invocation relationship, will not allow that key to deactivate the account. You must use association type 0x108.

The first thing the malicious holder of a compromised management key would do is revoke all deactivation capabilities. This would be a serious issue if the management key is both compromised and lost. To counter this, the holder can set a revocation delay by adding a revokeDelay data entry to the association tx. The value should be in microseconds. E.g. 86400000 is a delay of 24 hours.

Example

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1",
    "https://w3id.org/security/suites/secp256k1-2019/v1"
  ],
  "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH",
  "verificationMethod": [
    {
      "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH",
      "publicKeyMultibase": "zmMyJxTQuXW9bQVLmJeCrWNCSKzsEMkbZQ3xuNavj6Mk"
    },
    {
      "id": "did:lto:3MsE8Jfjkh2zaZ1LCGqaDzB5nAYw5FXhfCx#sign",
      "type": "EcdsaSecp256k1VerificationKey2019",
      "controller": "did:lto:3MsE8Jfjkh2zaZ1LCGqaDzB5nAYw5FXhfCx",
      "publicKeyMultibase": "zDeAxCdh1pYXpU7h41ieyqTDrTyQmhJWZarqxTtkmJv99"
    }
  ],
  "authentication": [
    "did:lto:3MsE8Jfjkh2zaZ1LCGqaDzB5nAYw5FXhfCx#sign"
  ],
  "assertionMethod": [
    "did:lto:3MsE8Jfjkh2zaZ1LCGqaDzB5nAYw5FXhfCx#sign"
  ],
  "keyAgreement": [
    "did:lto:3MsE8Jfjkh2zaZ1LCGqaDzB5nAYw5FXhfCx#sign"
  ],
  "capabilityInvocation": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign",
    {
      "id": "3Mv7ajrPLKewkBNqfxwRZoRwW6fziehp7dQ#sign",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:lto:3Mv7ajrPLKewkBNqfxwRZoRwW6fziehp7dQ"
      "publicKeyMultibase": "z6YQpeq9Yeh3VDAuVQvnUQLcUTnEq9hPUwCb9nX3yZHPC"
    }
  ],
  "capabilityDelegation": [
    "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#sign"
  ]
}

In this example, the verification relationships of the management key have been set to only capability invocation and capability delegation. A new verification method is added for authentication, assert method and key agreement. And deactivation capability is granted to one key.

Services

Services are used in DID documents to express ways of communicating with the DID subject or associated entities. A service can be any type of service the DID subject wants to advertise, including decentralized identity management services for further discovery, authentication, authorization, or interaction.

Defining services is done through data transactions. These transactions allow setting metadata of an account. This data is used by the indexer service when resolving a DID.

Services must be JSON encoded. Any data entry with a key starting with did:service: will be decoded and added as data entry. If the service id is omitted, it will be generated based on the service key.

A data instruction with the following data entries

[
  {
    key: 'did:service:lto-relay',
    type: 'string',  
    value: '{"type":"LTORelay","serviceEndpoint":"ampq://relay.lto.network"}'
  },
  {
    key: 'did:service:bar.example.com',
    type: 'string',
    value: '{"id":"https://bar.example.com","type":"LinkedDomains","serviceEndpoint":"https://bar.example.com"}'
  }
]

results in the following service property of the DID document

{
  "service": [
    {
      "id": "did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH#lto-relay",
      "type": "LTORelay",
      "serviceEndpoint": "ampq://relay.lto.network"
    },
    {
      "id": "https://bar.example.com",
      "type": "LinkedDomains", 
      "serviceEndpoint": "https://bar.example.com"
    }    
  ]
}

Versioning

LTO Did as versioned and support the versionTime DID parameter.

did:lto:3JugjxT51cTjWAsgnQK4SpmMqK6qua1VpXH?versionTime=2023-03-01T17:00:00Z

Using versionTime will return the DID document at the moment of the given time. If the DID document has changed since that time, the metadata will contain an updated and a nextUpdate property.

The DID will be marked as created at the moment when the public key is known on-chain. Requesting a DID with versionTime before the creation date will result in a not-found.

Last updated