Júlio Santos


Decentralized identity: W3C standards and the ixo KeySafe

And how to provably associate a DID with a person

ixo is the blockchain for sustainable development impacts, aiming to help standardize the measurement and rewarding of impact. Through their protocol and native IXO tokens, ixo plans to incentivize the funding and tracking on impact projects through unlocking a new economy for collecting and verifying impact data.

It’s crucial for ixo to encourage data integrity. As such they’re highly involved in the decentralized identity space, because it’s important that the several network stakeholders are properly identified. ixo uses the W3C DID and Verifiable Claims standard drafts to facilitate this process.

(See also: on decentralized identity, I previously wrote about ERC 725 and ERC 735 in the context of implementing a simple KYC claim verification for a crowdsale, check it out below.)

The W3C standards

The W3C, always the trailblazer, has been hard at work on standards for Decentralized Identifiers and Verifiable Claims.

(Note that the examples provided below are vastly simplified for clarity, and kind of butcher the well-crafted standards.)

DIDs — Decentralized identifiers

DID stands for Decentralized Identifier, and represents a new identifier for an identity that is detached from central control. From the horse’s mouth:

Decentralized Identifiers (DIDs) are a new type of identifier for verifiable, “self-sovereign” digital identity. DIDs are fully under the control of the DID subject, independent from any centralized registry, identity provider, or certificate authority.

They had me at self-sovereign. Onwards:

DIDs are URLs that relate a DID subject to means for trustable interactions with that subject. DIDs resolve to DID Documents — simple documents that describe how to use that specific DID.

Here’s an example of what a DID Document could look like:

"did": "did:example:person-123456789",
"pubKey": "DDoFgPQ4JyjrsBwqGg2yCoZdGk5x11k7nGXXeg3wokFy"

This simple document declares a DID and its corresponding public key (more complex documents can include other info, such as the location of associated personal data, or the DID owner’s agent). There isn’t much one can do with this in isolation. However, combining a DID with verifiable claims is quite powerful. Proving ownership of a DID on which a trusted claim has been made would grant you access to whatever the claim grants you access to. Let’s explore.

Verifiable Claims

Verifiable Claims are a method for trusted parties to provably issue a credential on a DID (claim and credential are used interchangeably in this post). Again, the W3C:

Driver’s licenses are used to claim that we are capable of operating a motor vehicle, university degrees can be used to claim our education status, and government-issued passports enable holders to travel between countries. This specification provides a standard way to express these sorts of claims on the Web in a way that is cryptographically secure, privacy respecting, and automatically verifiable.

Think of a traditional driver’s license. It’s usually issued by a trusted party (your local motor vehicle authority) on a person identified by a government ID. They evaluate your driving skills and, if you pass muster, they’ll associate a claim with your government ID saying you’re fit to drive.

Verifiable claims are a more secure way to achieve the same result on DIDs. If my identifier with the motor vehicle authority is not my government-issued ID, but a DID, how would this work?

First, they’ll need to verify that the applicant owns the DID they claim to. This is done through the use of public-key cryptography, as will be described later in this post.

Once that verification is completed, the authority can issue a claim confirming the applicant’s ability to drive. This is what it could look like.

"issuer": "did:example:trusted-authority-123",
"issued": "2010-01-01",
"claim": {
"id": "did:example:person-123456789",
"canDrive": true
"signature": "g4j9UrpHM4..."

This represents a claim by did:example:trusted-authority-123 that the DID did:example:person-123456789 can drive. Anyone could produce a similar document. What makes this claim verifiable is that it’s signed. That is, we know that the signature value could only be correctly produced by the owner of did:example:trusted-authority-123 (because cryptography). This means that, if we know that did:example:trusted-authority-123 indeed represents the authority it claims to be, we can trust this claim to be legitimate, and ascribe did:example:person-123456789 the ability to drive.

Here’s a use case. Suppose you’re stopped by your local transit authority for a random document check. All they really need to know is that you’re authorized to drive. However, a traditional driver’s license contains a lot of other unrelated data (such as your name and address), and all that data leaks in the document check process. Proving ownership of your DID and showing the associated claim will yield only the information required and no more.

Identities and claims on the IXO blockchain

In order to make it easier for people to register with ixo’s network, the ixo Foundation forked MetaMask and built KeySafe, a browser extension that simplifies the process for someone to create a decentralized identity. KeySafe generates a decentralized identifier (DID) on behalf of the user. From the draft whitepaper:

Each participant in an Impact Exchange project […] is identified as an entity, using a Digital Identifier [DID]. Entities can refer to natural persons, organizations, software agents or devices. For instance, an Evaluation Agent could be an identified software agent that functions as a Smart Oracle, checking submitted claims data against external data references and performing algorithmic calculations, to arrive at a conclusion that verifies
the claim. These identifiers resolve back to verifiable identity credentials, such as a proof of skills qualification, that can be used to determine the eligibility of the entity to exchange their claim for funding.

In order for someone to register with ixo, this DID needs to be ledgered on ixo’s blockchain.

Setting up KeySafe

Once installed, a user must set up KeySafe for the first time. This setup process will generate a DID for the user (more precisely, it generates a public/private key pair, and derives the DID from the public key), as seen below.

Generating a DID with KeySafe (simplified journey)

Once the user has followed the journey and a DID is generated, it’s time to register the DID on the ixo blockchain.

Ledgering the DID

In order to ledger the DID on the ixo chain, ixo requires a proof of ledgering intent. In other words, ixo must know that the owner of the DID must have wanted this ledgering to occur. As such, whomever issues the request for ledgering (be it the DID owner or a third party) must prove this intent.

A way to verify that this is true is by requiring that the ledgering request payload contains a signature of said payload. This is what the payload looks like.

payload : [
didDoc: {
did: "did:sov:person-123",
pubKey: "DDoFgPQ4JyjrsBwqGg2yCoZdGk5x11k7nGXXeg3wokFy",
credentials: [],
signature: {
signatureValue: [
created: "2018-07-20T16:50:07.420Z",

That long hex inside signature is the result of signing the didDoc in the payload with the DID's private key. We first transform the didDoc into JSON:


And then have KeySafe prompt the user to sign it.

KeySafe prompting the user to sign the ledgering payload

When we submit this payload to the ixo Blockchain API, this signature will be verified before any ledgering occurs. Only a successful verification will result in ledgering. There are 2 steps to this verification.

The first step is to confirm that the supplied DID and public key match. Skipping this step would allow an attacker to supply a different public key, whose private key they control, and use it to generate a valid signature.

A DID can be matched to a public key because the DID itself is derived from the public key. We then simply have to check that the supplied DID is the same as the one derived from the supplied public key, as such.

base58.encode(base58.decode(publicKey).slice(0, 16))

The signature itself can be verified through an algorithm which takes the original message, the public key, and the signature as inputs. Only an agent in possession of the DID’s private key will be able to generate a signature that will pass this verification.

It’s important to note that this process doesn’t prove that the registrant is actually in possession of the DID’s private key. An attacker might have found this signed message elsewhere (in the ixo chain, for example). This isn’t much of a problem: the private key can not be calculated from a message+signature pair, so all the attacker can do is replay the ledgering, which is presumably an idempotent operation.

As such, this proof is enough for ixo. Since the only way for an attacker to successfully register this DID is having found this signature elsewhere already, we can assume ledgering has occurred already and that, when it did, it was done by the DID owner (since the correct signature could have only been produced by the owner of the private key).

Provably associating a person with a DID

ixo, however, cares about associating a DID with an actual person. As an identity provider, we at Fractal then need to conduct a KYC process on an individual to prove their identity. We must also prove their ownership of a DID.

Asking the user to sign a challenge nonce

As such, Fractal needs to subtly alter their KYC procedure for identity provisioning. Alongside the normal identity questions, we will ensure the user has KeySafe installed and configured.

Once this has been confirmed, Fractal can issue a cryptographic challenge: we ask the user to sign a message whose contents are plausibly unique (a nonce). This uniqueness guarantees that there’s little to no chance that such a message has been signed before, making it next to impossible for the attacker to supply a correct signature as a response to this challenge.

A way to make this message plausibly unique is to use a UUID. If the user is able to produce a valid signature (as defined above), it must mean they are in possession of the DID’s private key.

Now that we have confirmed the association between a person and a DID, we’re ready to sign and issue a claim on their KYC status. We can then broadcast the following into the ixo blockchain.

"issuer": "did:sov:fractal-123",
"issued": "2010-01-01",
"claim": {
"id": "did:sov:person-123",
"kycLevels": ["IdentityVerified", "AccreditedInvestor"]
"signature": "g4j9UrpHM4..."

And boom — ixo can now rest assured that this DID does indeed match to a person, whose identity has been validated by Fractal.

Planning an ICO? At Fractal, we offer a hassle-free, user-friendly launchpad solution combined with a comprehensive customer identification service (KYC/AML) to successfully deploy your token launch with ease.

More by Júlio Santos

Topics of interest

More Related Stories