Lit JS SDK V3: Introducing ID Encrypt

Lit JS SDK V3: Introducing ID Encrypt

Major SDK Version Bump V2 (2.x.x) → V3 (3.x.x)

Lit Protocol is a decentralized key management network powered by threshold cryptography. A blockchain-agnostic identity layer, Lit can be used to power encryption, signing, and compute for web applications.

TLDR:

This is a major version update to how encryption works with the Lit JS SDK V3, which is only compatible with the new testnet cayenne.

The Lit JS SDK V3 replaces the V2 encryption and JWT signing processes with new cryptographic primitives to offer a more secure and seamless user experience. Encrypting private data with identity (ID) based encryption is now entirely a client-side operation, and only one round of network interactivity with the nodes is required upon decryption. Previously, encrypting and decrypting would be two network requests each.

Previously, encryption with the two network requests took 100 ms - 300 ms, now with ID-based encryption it only takes 2 ms.

To use cayenne and ID-based encryption, use the Lit JS SDK V3 and above. Please note when using V3, it is not backward compatible with the testnet networks, serrano and jalapeno.

ID-based encryption with the Lit JS SDK V3 is available now in beta.

Encryption Use Cases

  1. Social & Identity
    a. Encrypted wallet-based messaging: Secure wallet-to-wallet communication without relying on a centralized key custodian.
    b. User-owned social and identity graphs: Empower users to take full control over how their personal data and identity is managed on the web through generalizable access control and selective disclosure.
  2. Data Marketplaces
    a. Encrypted data storage: Use Lit to encrypt files, images, videos, archives, and other data for private storage on the dWeb.
    b. Open data marketplaces: Open data marketplaces facilitate the exchange of data between individuals and organizations, allowing users to buy, sell, or share information in a secure and transparent manner.
  3. Mempool encryption
    a. Conceal transaction data from searchers and block builders to mitigate the negative externalities of MEV.

Improvements to Encrypting with Lit

The cayenne Lit network uses a version of identity-based encryption scheme to encrypt data. This is made possible because the BLS network signature is the decryption key for a particular combination of access control conditions and private data, and the BLS network will only produce signature shares to the client if the user can prove that they satisfy the corresponding access control conditions.

This removes the need for Lit to store a global on-chain mapping of resource to access control conditions. Instead, the access control condition is part of the identity parameter that is used to generate a ciphertext, and the resource owner is only to be responsible for storing the ciphertext and the metadata that’s used for decryption. As a result, it’s quicker for encrypting lots of content since there is no need to talk to a server or chain to encrypt.

This scheme is also highly efficient, as encrypting private data is a entirely a client-side operation, and only 1 round of network interactivity with the nodes is required upon decryption. Previously, the nodes were generating symmetric encryption keys, which required additional resources and interactivity with the nodes.

Encryption with the two network requests took 100 ms - 300 ms, now with ID-based encryption it only takes 2 ms.

Feature matrix - Networks & Access Control

Shown below is a matrix illustrating which features are available with each SDK version.

V1 refers to the deprecated lit-js-sdk

V2 refers to 2.x.x versions of js-sdk

V3 refers to 3.x.x versions of js-sdk

Feature V1 V2 V3
jalapeno network
serrano network
cayenne network
ACC-based Encryption
ACC-based JWT signing
Updateable ACC

How to use the new ID-based encryption

Importing Lit JS SDK V3

Make sure you’re on the latest package - version 3.0.3 or higher.

npm install @lit-protocol/lit-node-client@^3.0.3

Importing the SDK has not changed significantly, make sure to set cayenne as the litNetwork.

import * as LitJsSDK from '@lit-protocol/lit-node-client';

const litNodeClient = new LitNodeClient({
  litNetwork: "cayenne",
});
await litNodeClient.connect();

Encryption

Previously in V2, you would have to:

  • Generate a symmetric key
  • Encrypt private data using this symmetric key
  • Encrypt this symmetric key using the BLS network key
  • Save this encrypted symmetric key with some access control conditions* in the BLS network

*This post does not go over access control conditions, read more here.

Let’s go through a scenario with ID-based encryption:

  1. Alice chooses some access control condition and private data and constructs the identity parameter
  2. Alice encrypts the private data using the BLS network public key and the identity parameter to get a ciphertext
  3. Alice stores the encryption metadata - set of access control conditions, hash of the private data etc. - and the ciphertext wherever she wants

Now in V3, all you would have to do is to call an encrypt function, like encryptString , to perform client-side encryption.

const { ciphertext, dataToEncryptHash } = await 		 
	litNodeClient.encryptString({
		accessControlConditions,
		authSig,
		dataToEncrypt: encryptionMaterial.data,
		chain,
	});

The full encryption method should look like

async encrypt(message: string) {
  if (!this.litNodeClient) {
    await this.connect()
  }

  const authSig = await LitJsSdk.checkAndSignAuthMessage({ chain })
  const { ciphertext, dataToEncryptHash } = await LitJsSdk.encryptString(
    {
      accessControlConditions,
      authSig,
      chain,
      dataToEncrypt: 'this is a secret message',
    },
    litNodeClient,
  );

  return {
    ciphertext,
    dataToEncryptHash,
  };
}

Check out the list of available encryption functions in the Lit SDK V3 API documentation.

Decryption

  1. Bob fetches the ciphertext and corresponding encryption metadata from the public data store
  2. Bob presents the encryption metadata to the BLS network and requests for signature shares over the identity parameter
  3. The BLS network nodes checks whether the user satisfies the access control conditions before signing the constructed identity parameter
  4. Bob assembles the signature shares into a decryption key and successfully decrypts the ciphertext

In order to decrypt, you can call the decriptToString() function like so:

const decryptedString = await LitJsSdk.decrypt(
  {
    accessControlConditions,
    ciphertext,
    dataToEncryptHash,
    authSig,
    chain: 'ethereum',
  },
  litNodeClient,
);

The full decrypt method should look like:

async decrypt(ciphertext: string, dataToEncryptHash: string, accessControlConditions: any) {
  if (!this.litNodeClient) {
    await this.connect()
  }

  const authSig = await LitJsSdk.checkAndSignAuthMessage({ chain })
  const decryptedString = LitJsSdk.decryptToString(
    {
      accessControlConditions,
      ciphertext,
      dataToEncryptHash,
      authSig,
      chain,
    },
    litNodeClient,
  );
  return { decryptedString }
}

Check out this sample project's lit-sdk-v3 branch for a full working code example.

Conclusion

We're excited to see builders use ID-based encryption on the Lit JS SDK V3! The new ID-based encryption scheme aims to advance the Lit network's security and ease developer experience by simplifying access control client-side operations.

Explore and get your hands on the Lit JS SDK V3... now in beta.

As always, we encourage our developer community to provide us with feedback on Discord - your input is instrumental to growing the ecosystem together.