Share Kit enables developers to request and validate any independently verified data from their users without relying on a centralized service provider.

Bloom released Share Kit this past October at the ETH San Francisco Hackathon. Since then, we’ve seen many great projects built on Share Kit, including BlocuSign, Lending Party and UpTown.

In this post, we'll dig into the sharing and data verification functionality of Share Kit. Learn how you can request BloomID-verified personal data directly from your customers, without any centralized middleman. We'll also cover our recent updates to make Share Kit compatible with the W3C Verifiable Credential specification, enabling interoperability with other decentralized identity services.

Share Kit enhances digital privacy.

Imagine you are applying for a personal loan from an online lender. The lender needs a verification of your income and expenses, but in the interest of privacy, you're hesitant to grant them full access to your financial statements. Bank statements can reveal information about investments, medical bills, subscription services and more.

Sample Bank Statement

Instead, you can grant Bloom temporary access to view your summarized financial data. Bloom calculates the income metrics the lenders need and gives it back to you as a digitally signed, reusable attestation. Here’s what that looks like in practice:

Asset Attestation on Bloom

Based on this snapshot of your financial data, Bloom can calculate metrics like income, volatility of income, net worth, ranges of income or net worth (e.g., > $10k, < $100k, etc.). With your copy of the data, authenticated by Bloom, you now have full control over which parts of it you wish to disclose. Thanks to the cryptographic techniques used in this data, the recipient is able to verify the source of the data and prove that it's never been tampered with.

We're able to achieve this using a Merkle Tree data structure:

Simplified Attestation Merkle Tree

The root hash of the tree is signed by both the subject of the attestation to prove consent and the attester to prove issuance. The resulting signatures are hashed and published on the Ethereum Blockchain.

Issuance Signatures

A user chooses to share they have a a verified net income over $100k while leaving the other claims concealed.

Simplified Merkle Proof

Each claim contains all relevant metadata and signatures to prove the authenticity of the claim independent of the rest of the attestation. The metadata enables a recipient of this claim to see the issuance and expiration dates, revocation tokens to check against a public on chain revocation registry and the identity of the claim issuer.

Claim Node Data Structure

A subject even has the option to leave the plaintext data of a claim obscured and just share the type of attestation performed.

Type only claim

Attestations are shared in the form of W3C Verifiable Presentations.

When a user authorizes a set of attestations to be shared via Share Kit, the claims are structured into compliant Verifiable Credentials and grouped into a Verifiable Presentation.

A verifiable credential is a tamper-evident credential that has authorship that can be cryptographically verified. - VC Data Model

The sample code in this section references a simple email ownership attestation. An email attestation can be used for a simple, secure signup and login tool. Bloom verifies the user controls the referenced email address by sending a verification code challenge to the user. Once the user has an email attestation, a Share Kit integrator can request the attestation and sign the user up for an account in one step without needing to send an email confirmation to the user.

The Verifiable Credential starts with the Credential Subject . The subject defines the claim and the user referenced by the claim. The subject is identified by an Ethereum address. The data is the stringified version of the verified data. There is also an optional authorization field which can contain an array of signatures authorizing another address to share the data on behalf of the original subject. In an upcoming update the subject address will comply with the Ethereum DID spec to further enable interoperability.

{ "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] } }

The type field of the Verifiable Credential is a string identifying a specific attestation type. These types are defined in the Share Kit repository.

{ "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] }, "type": "email" }

The issuer field references the attester's Ethereum address.

{ "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] }, "type": "email", "issuer": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", }

The issuanceDate field references the date in the issuance node of the claim tree. The date is formatted in compliance with RFC3339.

{ "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] }, "type": "email", "issuer": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", "issuanceDate": "2019-05-15T01:38:02.502Z" }

The proof field contains the Merkle Proof which proves inclusion of the referenced data in the larger Attestation Merkle Tree

{ "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] }, "proof": { "created": "2019-05-15T01:38:02.502Z", "data": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "version": "batch", "batchAttesterSig": "0xffcf3b824f4beffa50c250308f54f6367444d86af8196ca452c71a7eefceec473baf33b4d87279ea527222eb7b055fc7b9c93846d78593fbaa2852009e92e1351c", "rootHashNonce": "0xd19abeca6dd0e7daa486d9e596d9dca96728c568751918dc99e1aaca3ab445be", "layer2Hash": "0x36e952d746dbaa6c8b3e2451145198de8945094db39f52a4c9497d61241dea16", "rootHash": "0x2223208a5a1927fed62f95c1be879b1831b556300a87ba41fa931f0968ad7f23", "stage": "mainnet", "proof": [ { "position": "left", "data": "0x7079ce5b946f0fbc0b160c8aee7a7db02c92f5f6a9cb42408cd60adc72a17823" }, { "position": "left", "data": "0x8fc45a1e10df267e5e127286b9913fdb22fe27cd99196491f9aa9af80f5ca342" }, { "position": "right", "data": "0x3e2466500850683f4c32605fb9fca000e44c463fc4b9557cbfba0ce54589d8a7" }, { "position": "left", "data": "0xa2920d7b3306ae8397715ff574ce183a7678a5ffa58648ab088766a279c310d5" } ], "requestNonce": "0xc995c3badcbb87a59bade5559e43630a07fb793c2ae4808fbc81263360008607", "target": { "claimNode": { "data": { "nonce": "a92c0e08bd7ade12c92424c7d4861236c26b831c1423f3ab54e4bb5b51df6679", "data": "ipatka@gmail.com", "version": "2.0.0" }, "issuance": { "typeHash": "0x2b8f752a33ec25cd6aef2cb067477b64a4fe727238f4a31807ff4c2ec45c6a0b", "expirationDate": "2024-05-15T01:38:02.502Z", "dataHash": "0xecde0370b2a4cacefbbc13c0a63d451857be256ca69150bb960b48822522c8d6", "localRevocationToken": "0xe84ab3e2c99464702260749716d65b9b184c8ddf14d1db0f3a7a111164d1f2b2", "issuanceDate": "2019-05-15T01:38:02.502Z", "globalRevocationToken": "0xddd4dd3dd27861da7627fa4d48916fb4a681498ff6914ddfa815c5d6eba2fab1" }, "aux": "0x2d42ba0a6212914179d480f3b4c35238da98f9af75b117986d58252c21388fc8", "type": { "type": "email", "nonce": "ebb6668e467df4f591647dd5b5b7c7dc1b7ca06f6f52f705ea4e1fb5c784e00b", "provider": "Bloom" } }, "attesterSig": "0xad9ba60d018bbc1a9b2ad69f9f415779394b69e89284348f681a7d181ec95bd05230b793ca1286f6d960fec9a117d8d6860e87df8054c1baf4d76f589baf95661b", "attester": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb" }, "subjectSig": "0x3c142cf48a169616cc3c1665df1721f1fee3d4f96f9936e82ee39f01946b082461ccfe71e86912deb3c9343ae60ddda59b1b5f5a2a889109a507422ca036a3931b", "attester": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", "batchLayer2Hash": "0x01f575b3beb4ac1706494c756fb19632a2fa494bd6c171522132ba4f3b48770f" }, "type": "Bloom-Batch-Proof-1.0.0", "creator": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb" }, "type": "email", "issuer": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", "issuanceDate": "2019-05-15T01:38:02.502Z" }

After being structured into the Verifiable Credential, the credentials are structured into a Verifiable Presentation.

Data derived from one or more verifiable credentials, issued by one or more issuers, that is shared with a specific verifier. A verifiable presentation is a tamper-evident presentation encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification. - VC Data Model

In addition to the Verifiable Credential, the Verifiable Presentation contains additional fields defined below.

The context field contains an array of URIs, which resolve to machine readable documents. These documents instruct the recipient on how the presentation should be parsed and verified.

The signature is the signed hash of the presentation proof field. It should either be signed by the subject referenced in the Verifiable Credential credentialSubject , or by an address authorized in the credentialSubject.authorization field.

The proof field contains metadata describing the circumstances surrounding this specific presentation. This includes the hash of the credentials being shared, the timestamp of when the payload was signed, the domain where the user intends to share the data, and a random string presented by the recipient of the data intended to identify this unique share request.

Putting it all together, a Bloom Share Kit Verifiable Presentation payload looks like the following:

{ "signature": "0x1b6dfeb3608e5793bf7cfdbeedbb84bd06bc769f9c4450e1253e424b69bc451679007ddcab8a85bf6562c8551e99a3a07159c1dcbe1dd866e889e524846241e71c", "type": "VerifiablePresentation", "token": "78c7f905-6091-4c7f-a63f-f8590242502f", "verifiableCredential": [ { "credentialSubject": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "data": "ipatka@gmail.com", "authorization": [] }, "proof": { "created": "2019-05-15T01:38:02.502Z", "data": { "subject": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "version": "batch", "batchAttesterSig": "0xffcf3b824f4beffa50c250308f54f6367444d86af8196ca452c71a7eefceec473baf33b4d87279ea527222eb7b055fc7b9c93846d78593fbaa2852009e92e1351c", "rootHashNonce": "0xd19abeca6dd0e7daa486d9e596d9dca96728c568751918dc99e1aaca3ab445be", "layer2Hash": "0x36e952d746dbaa6c8b3e2451145198de8945094db39f52a4c9497d61241dea16", "rootHash": "0x2223208a5a1927fed62f95c1be879b1831b556300a87ba41fa931f0968ad7f23", "stage": "mainnet", "proof": [ { "position": "left", "data": "0x7079ce5b946f0fbc0b160c8aee7a7db02c92f5f6a9cb42408cd60adc72a17823" }, { "position": "left", "data": "0x8fc45a1e10df267e5e127286b9913fdb22fe27cd99196491f9aa9af80f5ca342" }, { "position": "right", "data": "0x3e2466500850683f4c32605fb9fca000e44c463fc4b9557cbfba0ce54589d8a7" }, { "position": "left", "data": "0xa2920d7b3306ae8397715ff574ce183a7678a5ffa58648ab088766a279c310d5" } ], "requestNonce": "0xc995c3badcbb87a59bade5559e43630a07fb793c2ae4808fbc81263360008607", "target": { "claimNode": { "data": { "nonce": "a92c0e08bd7ade12c92424c7d4861236c26b831c1423f3ab54e4bb5b51df6679", "data": "ipatka@gmail.com", "version": "2.0.0" }, "issuance": { "typeHash": "0x2b8f752a33ec25cd6aef2cb067477b64a4fe727238f4a31807ff4c2ec45c6a0b", "expirationDate": "2024-05-15T01:38:02.502Z", "dataHash": "0xecde0370b2a4cacefbbc13c0a63d451857be256ca69150bb960b48822522c8d6", "localRevocationToken": "0xe84ab3e2c99464702260749716d65b9b184c8ddf14d1db0f3a7a111164d1f2b2", "issuanceDate": "2019-05-15T01:38:02.502Z", "globalRevocationToken": "0xddd4dd3dd27861da7627fa4d48916fb4a681498ff6914ddfa815c5d6eba2fab1" }, "aux": "0x2d42ba0a6212914179d480f3b4c35238da98f9af75b117986d58252c21388fc8", "type": { "type": "email", "nonce": "ebb6668e467df4f591647dd5b5b7c7dc1b7ca06f6f52f705ea4e1fb5c784e00b", "provider": "Bloom" } }, "attesterSig": "0xad9ba60d018bbc1a9b2ad69f9f415779394b69e89284348f681a7d181ec95bd05230b793ca1286f6d960fec9a117d8d6860e87df8054c1baf4d76f589baf95661b", "attester": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb" }, "subjectSig": "0x3c142cf48a169616cc3c1665df1721f1fee3d4f96f9936e82ee39f01946b082461ccfe71e86912deb3c9343ae60ddda59b1b5f5a2a889109a507422ca036a3931b", "attester": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", "batchLayer2Hash": "0x01f575b3beb4ac1706494c756fb19632a2fa494bd6c171522132ba4f3b48770f" }, "type": "Bloom-Batch-Proof-1.0.0", "creator": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb" }, "type": "email", "issuer": "0x156ba3f2af07d24cfd5dd8ec0fe2b17c6131d7fb", "issuanceDate": "2019-05-15T01:38:02.502Z" } ], "packedData": "0xae69844748a07e06d259aa697a3e1867bd84749a53bded6d4a4cf9cc7b97bbab", "context": ["placeholder"], "proof": { "credentialHash": "0x0d0f48792f41e35fd83f70c2ac5694eaf08291cdd7530a331715db34a688409e", "created": "2019-05-15T23:53:36.808Z", "nonce": "78c7f905-6091-4c7f-a63f-f8590242502f", "type": "Bloom-Presentation-1.0.0", "creator": "0x1cc73a01dab0d88060d86033d21c9068e601b84c", "domain": "bloom.co/receiveData" } }

The recipient performs proofs on the Verifiable Presentation to verify the integrity of the data

The following proofs are implemented in Share-Kit.

The payload contains a context field

Checks if the context field is present and that it is an array of non-empty strings.

Note: The context field is not currently parsed beyond this check, but in the future it will be used to provide the recipient endpoint with machine readable instructions on interpreting the payload.

The payload contains a valid type field

Checks if the type field is present and that it matches the string 'VerifiablePresentation'

The payload contains an array of valid Verifiable Credentials

Each Verifiable Credential contains the fields defined in the above section on Verifiable Credentials. It also performs the Merkle Proof included in the credential to check if the referenced data was included in the attestation Merkle Tree. Depending on the type of the Verifiable Credential, Share Kit also checks the logs of on chain attestation transactions.

Note: Share-Kit does not yet check against the global revocation registry for attestations.

The payload contains a valid presentation proof.

Checks if the credentialHash and token in the proof matches the credentials included in the payload.

Recovers the address of the payload signer. Checks that it is the same subject referenced in the attestations.

Note: Share-Kit does not yet implement checking of the authorization field in the Verifiable Credentials because it has not yet been implemented in any clients.

Decentralized identity is the foundation on which Bloom is building a fair, inclusive, and secure credit scoring system.

We’re thrilled by the explosion in identity technology over the past year, as well as the collaborative efforts of many organizations to build interoperable identity solutions. In the modern environment of data breaches, privacy issues, and surveillance concerns, it’s essential to have a decentralized alternative to centralized login and authentication services provided by companies like Facebook, Google, and Apple.

Bloom: Take Control of Your Credit & Identity

Bloom is a blockchain solution for identity security and cross-border credit scoring, restoring ownership and control of identity information and financial data back to consumers. By decentralizing the way that information is shared between untrusted parties, the system reduces the risk of identity theft and minimizes costs associated with customer on-boarding, compliance and fraud prevention.

Together, we are paving a path for a fairer and more secure credit system, redefining the way that credit and finance are conducted.

To learn more about the latest with Bloom: