From f0c865593158c9b87578ef0f5520059afd627ccb Mon Sep 17 00:00:00 2001 From: ivan770 Date: Tue, 20 Feb 2024 17:02:30 -0500 Subject: [PATCH 1/2] docs: init JS wrapper docs --- crates/teddybear-js/src/lib.rs | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/crates/teddybear-js/src/lib.rs b/crates/teddybear-js/src/lib.rs index 5e85a6f..0fe61ee 100644 --- a/crates/teddybear-js/src/lib.rs +++ b/crates/teddybear-js/src/lib.rs @@ -1,3 +1,85 @@ +//! # Teddybear JS/WASM wrapper. +//! +//! `teddybear-js` is a JavaScript/TypeScript library designed to make working with W3C verifiable credentials easier and more accessible. +//! It provides a collection of tools and utilities to issue, validate and query verifiable credentials, and to execute common cryptographic operations. +//! +//! ## Key management +//! +//! Teddybear's [`PrivateEd25519`] structure provides a central access point for Ed25519 key management and cryptographic operations. +//! +//! It allows you to: +//! * Generate new key pairs +//! * Import existing keys from JSON Web Key (JWK) or Decentralized Identifier (DID) formats +//! * Extract DID values for both Ed25519 and X25519 public keys +//! * Generate JWKs for Ed25519 and X25519 public and private keys +//! * Sign JSON Web Signatures (JWS) +//! * Encrypt and decrypt JSON Web Encryption (JWE) values +//! +//! ```ignore +//! import { PrivateEd25519 } from "@vaultie/teddybear"; +//! +//! const key = await PrivateEd25519.generate(); +//! +//! // Extract document DID value +//! console.log(key.documentDID()); +//! +//! // Extract public key JWK value +//! console.log(JSON.stringify(key.toEd25519PublicJWK())); +//! // ^^^^^^^^^^^^^^ Important for correct serialization +//! +//! // Produce a JWS value +//! console.log(key.signJWS("Value to sign")); +//! +//! // Issue a verifiable credential +//! // https://www.w3.org/TR/vc-data-model-2.0/#example-usage-of-the-context-property +//! const credential = { +//! "@context": [ +//! "https://www.w3.org/ns/credentials/v2", +//! "https://www.w3.org/ns/credentials/examples/v2" +//! ], +//! "id": "http://university.example/credentials/58473", +//! "type": ["VerifiableCredential", "ExampleAlumniCredential"], +//! "issuer": "https://university.example/issuers/565049", +//! "issuanceDate": "2024-01-01T00:00:00Z", +//! "validFrom": "2024-01-01T00:00:00Z", +//! "credentialSubject": { +//! "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", +//! "alumniOf": { +//! "id": "did:example:c276e12ec21ebfeb1f712ebc6f1", +//! "name": "Example University" +//! } +//! } +//! }; +//! +//! console.log(await key.issueVC(credential)) +//! ``` +//! +//! ## JWE encryption and decryption +//! +//! Teddybear supports JWE encryption and decryption using X25519 keys. +//! +//! Additionally, you can convert Ed25519 keys to X25519 keys, allowing you to publish just a single DID value for both signing and encryption purposes. +//! +//! ```ignore +//! import { PrivateEd25519, PublicEd25519, encrypt } from "@vaultie/teddybear"; +//! +//! const firstKey = await PrivateEd25519.generate(); +//! const secondKey = await PublicEd25519.fromDID( +//! "did:key:z6MkmpNwNTy4ATx87tZWHqSwNf1ZdeQrBHFWyhtvUwqrt32R" +//! ); +//! +//! // Encrypt using recipient public keys. +//! const jwe = encrypt(new Uint8Array([0, 1, 2, 3], [ +//! firstKey.toX25519PublicJWK(), +//! secondKey.toX25519PublicJWK(), +//! ])); +//! +//! console.log(jwe); +//! +//! // Decrypt using any suitable recipient private key. +//! console.log(firstKey.decrypt(jwe)); +//! ``` + extern crate alloc; use js_sys::{Object, Uint8Array}; From c348d4e4824ccd09ccac3e0ba14c38193c126b94 Mon Sep 17 00:00:00 2001 From: ivan770 Date: Tue, 20 Feb 2024 17:34:50 -0500 Subject: [PATCH 2/2] docs: add status list documentation --- crates/teddybear-js/src/lib.rs | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/teddybear-js/src/lib.rs b/crates/teddybear-js/src/lib.rs index 0fe61ee..41dbd79 100644 --- a/crates/teddybear-js/src/lib.rs +++ b/crates/teddybear-js/src/lib.rs @@ -79,6 +79,46 @@ //! // Decrypt using any suitable recipient private key. //! console.log(firstKey.decrypt(jwe)); //! ``` +//! +//! ## Revocation/status list +//! +//! Teddybear also implements bitstring-encoded [W3C status lists](https://www.w3.org/TR/vc-bitstring-status-list/). +//! +//! Status lists can be used to track revoked credentials in a privacy-preserving manner, without disclosing any +//! details about the credential itself. +//! +//! To start, create a new status list (all bits set to 0) and [publish it as a verifiable credential](https://www.w3.org/TR/vc-bitstring-status-list/#example-example-bitstringstatuslistcredential): +//! +//! ```ignore +//! import { StatusListCredential } from "@vaultie/teddybear"; +//! +//! const statusList = new StatusListCredential(); +//! const partialCredentialSubject = statusList.toJSON(); +//! +//! // ... +//! ``` +//! +//! During credential issuance generate a random index number between 0 and 131072, unique to this new credential: +//! +//! ```ignore +//! const idx = /* credential index */; +//! ``` +//! +//! Set this index as a [statusListIndex value](https://www.w3.org/TR/vc-bitstring-status-list/#example-example-statuslistcredential). +//! +//! If a situation occurs where you have to revoke a previously issued verifiable credential, set the bit corresponding +//! to the credential index to 1 (thus revoking the corresponding verifiable credential) and re-publish the updated status list verifiable credential: +//! +//! ```ignore +//! statusList.revoke(idx); +//! const updatedPartialCredentialSubject = statusList.toJSON(); +//! ``` +//! +//! Status lists can be queried for the index revocation status: +//! +//! ```ignore +//! console.log(statusList.isRevoked(idx)); // true +//! ``` extern crate alloc; @@ -358,6 +398,7 @@ impl StatusListCredential { } /// Check if a given index is revoked (bit set to 1). + #[wasm_bindgen(js_name = "isRevoked")] pub fn is_revoked(&self, idx: usize) -> bool { self.0.is_set(idx) }