NuID Web Client SDK


The nuid.zk package is the first in a suite of zero knowledge tools available for client interfaces. The package provides functions for generating credentials and proving credential challenges. We will be adding more tools to the Web Client SDK in the future.

The package is written in Clojure and is currently compatible with ClojureScript, JavaScript, and any JVM compatible language. To interact with the SDK on the web you'll want to use the @nuid/zk npm package in conjunction with a packaging solution like webpack, shadow-cljs, etc.

Please contact us if you have any questions regarding usage. We also encourage you to open an issue or pull request if you have any issues or suggestions.

Installation


$ npm install -s @nuid/zk
# or
$ yarn add @nuid/zk

tools.deps

;; deps.edn
{:deps
 {;; ...
  nuid/zk {:git/url "https://github.com/nuid/zk" :sha "..."}}}

For browser integration in ClojureScript we recommend using the excellent shadow-cljs.

Usage


const Zk = require('@nuid/zk')

// client context, registration
const secret = 'high entropy ✅'
const verifiable = Zk.verifiableFromSecret(secret)
const json = JSON.stringify(verifiable)

// server context, registration
const verifiable = JSON.parse(json)
Zk.isVerified(verifiable)
const credential = Zk.credentialFromVerifiable(verifiable) // persist credential (db, ledger, ...)

// server context, login step 1
const challenge = Zk.defaultChallengeFromCredential(credential) // retrieve credential (db, ledger, ...)
const json = JSON.stringify(challenge)

// client context, login
const challenge = JSON.parse(json)
const proof = Zk.proofFromSecretAndChallenge(secret, challenge)
const json = JSON.stringify(proof)

// server context, login step 2
const proof = JSON.parse(json)
const verifiable = Zk.verifiableFromProofAndChallenge(proof, challenge)
Zk.isVerified(verifiable) ? console.log('verified') : console.error('unverified')
(ns myapp.zk
 (require
  [clojure.spec.alpha :as s]
  [clojure.spec.gen.alpha :as gen]
  [clojure.test.check.generators]
  [nuid.cryptography :as crypt]
  [nuid.zk :as zk]))

(def parameters (gen/generate (s/gen ::zk/parameters)))
(def secret     "high entropy ✅")
(def pub        (zk/pub (assoc parameters :secret secret)))
(def nonce      (gen/generate (s/gen ::crypt/nonce)))
(def parameters (merge parameters {:pub pub :nonce nonce}))

(def good-proof (zk/proof (merge parameters {:secret secret})))
(def bad-proof  (zk/proof (merge parameters {:secret "garbage 🚮"})))

(zk/verified?   (merge parameters good-proof))
(zk/verified?   (merge parameters bad-proof))

You can see a complete code example using the Web Client SDK in our examples repo, or go read our Integrating with NuID guide for an in-depth walkthrough of your first integration.

JavaScript Docs


isVerified(verifiedCredential)

@param verifiedCredential [VerifiedCredential]

A VerifiedCredential produced by Zk.verifiableFromSecret(secret).

@return [boolean]

@example

if (Zk.isVerified(Zk.verifiableFromSecret(secret)) {
  console.log('verified')
} else {
  console.error('failed verification')
}

credentialFromVerifiable(verifiedCredential)

@param verifiedCredential [VerifiedCredential]

A VerifiedCredential produced by Zk.verifiableFromSecret(secret).

@return [Credential]

A Credential suitable for storage.

@example

const credential = Zk.credentialFromVerifiable(verifiedCredential)

defaultChallengeFromCredential(credential)

@param credential [Credential]

A credential derived from verifiableFromSecret -> credentialFromVerifiable.

@return [Challenge]

An object which can be used to generate a proof in concert with the user's secret.

@example

const challenge = Zk.defaultChallengeFromCredential(credential)

proofFromSecretAndChallenge(secret, challenge)

@param secret [String]

The protected secret, usually the user's password.

@param challenge [Challenge]

An object derived from verifiableFromSecret -> credentialFromVerifiable -> defaultChallengeFromCredential.

@return [Proof]

An object which can be used to verify secret knowledge without disclosing the secret.

@example

const proof = Zk.proofFromSecretAndChallenge(secret, challenge)

verifiableFromProofAndChallenge(proof, challenge)

@param proof [Proof]

An object which can be used to verify secret knowledge without disclosing the secret.

@param challenge [Challenge]

An object derived from verifiableFromSecret -> credentialFromVerifiable -> defaultChallengeFromCredential.

@return [VerifiedCredential]

The verified credential is simply a combination of the Proof and Challenge.

@example

const verifiedCredential = Zk.verifiableFromProofAndChallenge(proof, challenge)