{"id":26005185,"url":"https://github.com/docknetwork/crypto-wasm","last_synced_at":"2025-11-16T19:03:43.574Z","repository":{"id":40541184,"uuid":"415002472","full_name":"docknetwork/crypto-wasm","owner":"docknetwork","description":"WASM wrapper over the crypto library","archived":false,"fork":false,"pushed_at":"2024-07-19T05:03:15.000Z","size":1679,"stargazers_count":17,"open_issues_count":1,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-02-12T11:53:21.634Z","etag":null,"topics":["accumulator","cryptography","rust","signature-scheme","wasm","wasm-bindgen","zero-knowledge-proofs"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docknetwork.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-08T13:42:56.000Z","updated_at":"2024-12-09T12:03:59.000Z","dependencies_parsed_at":"2024-05-10T16:52:42.746Z","dependency_job_id":"8183d163-bcfd-4ccf-a307-66cf6f7f4f68","html_url":"https://github.com/docknetwork/crypto-wasm","commit_stats":{"total_commits":153,"total_committers":12,"mean_commits":12.75,"dds":0.5882352941176471,"last_synced_commit":"cd02553308927646e4909b44fff9c60db1ad33e1"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docknetwork%2Fcrypto-wasm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docknetwork%2Fcrypto-wasm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docknetwork%2Fcrypto-wasm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docknetwork%2Fcrypto-wasm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docknetwork","download_url":"https://codeload.github.com/docknetwork/crypto-wasm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242100498,"owners_count":20071735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accumulator","cryptography","rust","signature-scheme","wasm","wasm-bindgen","zero-knowledge-proofs"],"created_at":"2025-03-05T20:41:24.998Z","updated_at":"2025-11-16T19:03:43.562Z","avatar_url":"https://github.com/docknetwork.png","language":"Rust","readme":"# crypto-wasm\n\nThis repository is a WASM wrapper over [Dock's Rust crypto library](https://github.com/docknetwork/crypto) and is home to \n- BBS+, a performant multi-message digital signature algorithm implementation which supports\nderiving zero knowledge proofs that enable selective disclosure from the originally signed message set.\n- bilinear map, positive and universal accumulators supporting single and batch updates to the accumulator and witness\n- composite proof system that lets you combine BBS+ signatures, accumulators and Schnorr protocols\n\nThis project started as fork of [@mattrglobal/bbs-signatures](https://github.com/mattrglobal/bbs-signatures) but now only borrows the \nWASM setup; the API is quite different.\n\nThis repo contains a thin wrapper over the Rust code and exposes free floating JS functions. For a Typescript wrapper with better \nabstractions, check [this](https://github.com/docknetwork/crypto-wasm-ts). \n\n## Overview\nFollowing is a conceptual explanation of the primitives. For the API, check the [tests](./tests/js).  \n\n### BBS+ Signatures\nBBS+ signature allow for signing an ordered list of messages, producing a signature of constant size independent of the number \nof messages. The signer needs to have a public-private keypair and signature parameters which are public values whose size \ndepends on the number of messages being signed. A verifier who needs to verify the signature needs to know the \nsignature parameters used to sign the messages and the public key of the signer.  \nBBS+ signature also allow a user to request a blind signature from a signer where the signer does not know 1 or more messages \nfrom the list. The user can then unblind the blind signature to get a regular signature which can be verified by a verifier in \nthe usual way. Such blind signatures can be used to hide a user specific secret like a private key or some unique identifier \nas a message in the message list and the signer does not become aware of the hidden message.     \nWith a BBS signature, a user in possession of the signature and messages and create a [zero-knowledge proof of knowledge](https://en.wikipedia.org/wiki/Proof_of_knowledge) \nof the signature and the corresponding signed messages such that he can prove to a verifier that he knows a signature and the \nmessages and optionally reveal one or more of the messages.  \nA typical use of BBS+ signatures looks like:\n  - Signature parameters of the required size are assumed to exist and published at a public location. The signer can create \n    his own or reuse parameters created by another party.\n  - Signer public-private keypair and publishes the public key. The keypair can be reused for signing other messages as well. \n  - User requests a signature from the signer.\n  - Signer signs the message list using the signature parameters and his private key.\n  - User verifies the signature on the  message list using the signature parameters and signer's public key\n  - User creates a proof of knowledge of the signature and message list and optionally reveals 1 or more messages to the verifier.\n  - The verifier uses the signature parameters and signer's public key to verify this proof. If successful, the verifier is \n    convinced that the user does have a signature from the signer and any messages revealed were part of the message list \n    signed by the signer.\n\n### Accumulator\nAn accumulator is a \"set like\" data-structure in which elements can be added or removed but the size of the accumulator remains \nconstant. But an accumulator cannot be directly checked for presence of an element, an element needs to have accompanying data called \nthe witness (its the manager's signature on the element), the element and the witness and these together can be used to check the presence \nor absence of the element. An accumulator can be considered similar to the root of the merkle tree where the inclusion proof is the witness \nof the element (non-membership proofs aren't possible with simple merkle trees). As with merkle trees, as elements are added or \nremoved from the accumulator, the witness (inclusion proof) needs to be updated for the current accumulated value (root).  \n2 kinds of accumulators are provided, **positive** and **universal**. Positive support only membership witnesses while universal support both \nmembership and non-membership witnesses. Creating non-membership witnesses is expensive however and the cost depends on the \nnumber of members present in the accumulator. Both accumulators are owned by an accumulator manager who has the private key to the accumulator \nand only the owner can add or remove elements or create witnesses using the accumulator.    \nAccumulator allows proving membership of the member (or non-member) and the corresponding witness in zero knowledge meaning \na user in possession of an accumulator member (or non-member) and the witness can convince a verifier that he knows of an \nelement present (or absent) in the accumulator without revealing the element or the witness. Note, the like merkle trees, \nwitnesses (inclusion proof) are tied to the accumulated value (root) and need to be updated as accumulator changes.  \nWitnesses can be updated either by the accumulator manager using his private key or the manager can publish witness update \ninformation and the updates (additions and removals) and users can update their witnesses. \nA typical use of accumulator looks like:\n  - Accumulator parameters are assumed to exist and published at a public location. The manager can create his own params or \n    reuse existing ones.\n  - Accumulator manager creates a keypair and publishes the public key.\n  - Accumulator manager initializes the accumulator and publishes the accumulator.\n  - User requests an element to be added to the accumulator and the membership witness from the manager. The user could have \n    also requested a non-membership witness for an absent element.\n  - Signer checks whether requested element is not already present (in his database) and adds the element to the \n    accumulator if not already present. He publishes the new accumulator and creates a (non)membership witness and sends to the user.\n  - User verifies the (non)membership using the element, the witness, the new accumulated value and the accumulator params and signer's public key.\n  - To prove knowledge of (non)membership in zero knowledge, user and verifier agree on a proving key. Anyone can generate this. \n  - User can create a proof of knowledge of the element and the witness corresponding to the accumulator.\n  - Verifier can verify above proof using the current accumulator, the parameters and signer's public key and is convinced \n    that the user knows of an element and its witness and the (non)-membership.\n\n### Verifiable encryption\nAllow a verifier to check that the plaintext satisfies some properties, and it correctly encrypted for a specified public key without \nlearning the plaintext itself. This is implemented using a protocol called [SAVER](https://eprint.iacr.org/2019/1270).  \n\n### Bound check\nAllow a verifier to check that some message satisfies given bounds `min` and `max`, i.e. `min \u003c= message \u003c= max` without \nlearning the message itself. This is implemented using a protocol called LegoGroth16, a protocol described in the SNARK framework [Legosnark](https://eprint.iacr.org/2019/142)\n\n### Composite proofs\nThe above primitives can be combined using the composite proof system. An example is (in zero knowledge) proving knowledge of 2 \ndifferent signatures and the message lists. Another example is proving knowledge of the signature and messages and certain message's presence (absence) \nin an accumulator. Or the knowledge of 5 signatures and proving certain message is the same in the 5 message lists. \n\n### DKG from FROST\n\n### Threshold BBS+ and BBS\n\n## Getting started\n\nTo use this package within your project simply run\n\n```\nnpm install @docknetwork/crypto-wasm\n```\n\nOr with [Yarn](https://yarnpkg.com/)\n\n```\nyarn add @docknetwork/crypto-wasm\n```\n\nSee the [sample](./sample) directory for a runnable demo's.\n\nThe following is a short sample on how to use the API\n\n## Element Size\n\nWithin a digital signature there are several elements for which it is useful to know the size, the following table\noutlines the general equation for calculating element sizes in relation to BBS+ signatures as it is dependent on the\npairing friendly curve used.\n\n| Element     | Size Equation                        |\n| ----------- | ------------------------------------ |\n| Private Key | F                                    |\n| Public Key  | G2                                   |\n| Signature   | G1 + 2\\*F                            |\n| Proof       | 5*G1 + (4 + no_of_hidden_messages)*F |\n\n- `F` A field element\n- `G1` A point in the field of G1\n- `G2` A point in the field of G2\n- `no_of_hidden_messages` The number of the hidden messages\n\nThis library includes specific support for BLS12-381 keys with BBS+ signatures and hence gives rise to the following\nconcrete sizes\n\n| Element     | Size with BLS12-381                     |\n| ----------- | --------------------------------------- |\n| Private Key | 32 Bytes                                |\n| Public Key  | 96 Bytes                                |\n| Signature   | 112 Bytes                               |\n| Proof       | 368 + (no_of_hidden_messages)\\*32 Bytes |\n\n## Getting started as a contributor\n\nThe following describes how to get started as a contributor to this project\n\n### Prerequisites\n\nThe following is a list of dependencies you must install to build and contribute to this project\n\n- [Yarn](https://yarnpkg.com/) - make sure you're not using the legacy version.\n- [Rust](https://www.rust-lang.org/)\n\nFor more details see our [contribution guidelines](./docs/CONTRIBUTING.md)\n\n#### Install\n\nTo install the package dependencies run:\n\n```\nyarn install --frozen-lockfile\n```\n\n#### Build\n\nTo build the project for debug, run:\n\n```\nyarn build\n```\n\nTo build the project for release, run:\n\n```\nyarn build:release\n```\n\nTo build the project for profiling (slower to build, faster to run), run:\n\n```\nyarn build:profiling\n```\n\n#### Test\n\nTo run the all test in the project run:\n\n```\nyarn test\n```\n\nTo run just the tests for a node environment using the wasm module run:\n\n```\nyarn test:wasm\n```\n\nBefore running the JS tests, build the project with `yarn build`.\n\nTo run just the tests for a browser environment run:\n\n```\nyarn test:browser\n```\n\nAbove runs the Rust tests [here](./tests/). To run specific modules, use following wasm-pack command and pass the test module \nname. Eg. for running accumulator tests, run:\n\n```\nwasm-pack test --headless --chrome -- --test accumulator\n```\n\nFor BBS+, run:\n```\nwasm-pack test --headless --chrome -- --test bbs_plus\n```\n\nFor accumulator, run:\n```\nwasm-pack test --headless --chrome -- --test accumulator\n```\n\nSome tests take long (few minutes) to run and to prevent timeout of such tests, set env variable `WASM_BINDGEN_TEST_TIMEOUT` \nto the number of seconds for the timeout. eg. the following sets the timeout to 360 seconds, i.e. 6 minutes\n\n```\nWASM_BINDGEN_TEST_TIMEOUT=360 wasm-pack test --headless --chrome\n```\n\nIt's better to run tests in release mode since debug mode takes a long time. Increasing the timeout helps as well as shown below.\n\n```\nWASM_BINDGEN_TEST_TIMEOUT=360 wasm-pack test --release --headless --chrome\n```\n\n#### Benchmark\n\nTo benchmark the implementation locally in a node environment using the wasm module run:\n\n```\nyarn benchmark:wasm\n```\n\n## Usage\n\nSince loading WASM is an async process, before any function can be used `initializeWasm` should be called and resolved which \nloads WASM.\n\nExample of using BBS+ signature\n\n```js\nimport {\n  bbsPlusGenerateSignatureParamsG1, bbsPlusGeneratePublicKeyG2, bbsPlusGenerateSigningKey, bbsPlusSignG1, bbsPlusVerifyG1, \n  bbsPlusInitializeProofOfKnowledgeOfSignature, bbsPlusGenProofOfKnowledgeOfSignature, bbsPlusVerifyProofOfKnowledgeOfSignature, \n  bbsPlusChallengeContributionFromProtocol, bbsPlusChallengeContributionFromProof, generateChallengeFromBytes, \n  initializeWasm\n} from \"../../../lib\";\n\nconst stringToBytes = (str: string) =\u003e Uint8Array.from(Buffer.from(str, \"utf-8\"));\n\nconst main = async () =\u003e {\n    // Load the WASM module\n    await initializeWasm();\n\n    // Generate some random messages\n    const messages = [\n        Uint8Array.from(Buffer.from(\"message1\", \"utf8\")),\n        Uint8Array.from(Buffer.from(\"message2\", \"utf8\")),\n        Uint8Array.from(Buffer.from(\"message3\", \"utf8\")),\n    ];\n\n  const label = stringToBytes(\"test-params\");\n  const messageCount = messages.length;\n\n  // Generate params deterministically using a label\n  const sigParams = bbsPlusGenerateSignatureParamsG1(messageCount, label);\n  console.log('params is', sigParams);\n\n  // Generate a new key pair\n  const sk = bbsPlusGenerateSigningKey();\n  const pk = bbsPlusGeneratePublicKeyG2(sk, sigParams);\n  console.log(\"Key pair generated\");\n  console.log(\n    `Public key base64 = ${Buffer.from(pk).toString(\"base64\")}`\n  );\n\n  console.log(\"Signing a message set of \" + messages);\n\n  // Create the signature\n  const signature = bbsPlusSignG1(messages, sk, sigParams, true);\n  console.log(\n    `Output signature base64 = ${Buffer.from(signature).toString(\"base64\")}`\n  );\n\n  // Verify the signature\n  const isVerified = bbsPlusVerifyG1(messages, signature, pk, sigParams, true);\n  const isVerifiedString = JSON.stringify(isVerified);\n  console.log(`Signature verified ? ${isVerifiedString}`);\n\n  // Derive a proof from the signature revealing the first message\n  const revealed = new Set\u003cnumber\u003e();\n  revealed.add(0);\n  const revealedMsgs = new Map();\n  revealedMsgs.set(0, messages[0]);\n  \n  const protocol = bbsPlusInitializeProofOfKnowledgeOfSignature(\n      signature,\n      sigParams,\n      messages,\n    new Map(),\n      revealed,\n      true\n  );\n\n  const challengeProver = generateChallengeFromBytes(bbsPlusChallengeContributionFromProtocol(protocol, revealedMsgs, sigParams, true));\n  const proof = bbsPlusGenProofOfKnowledgeOfSignature(protocol, challengeProver);\n\n  console.log(`Output proof base64 = ${Buffer.from(proof).toString(\"base64\")}`);\n\n  // Verify the created proof\n  const challengeVerifier = generateChallengeFromBytes(bbsPlusChallengeContributionFromProof(proof, revealedMsgs, sigParams, true));\n  const isProofVerified = bbsPlusVerifyProofOfKnowledgeOfSignature(\n    proof,\n      revealedMsgs,\n    challengeVerifier,\n    pk,\n    sigParams,\n    true,\n  );\n  const isProofVerifiedString = JSON.stringify(isProofVerified);\n  console.log(`Proof verified ? ${isProofVerifiedString}`);\n};\n\nmain();\n\n```\n\nSee the [tests](./tests/js) for more thorough examples.\n\n\n## Dependencies\n\nThis library uses the creates defined in [Dock's crypto library](https://github.com/docknetwork/crypto) which is then \nwrapped and exposed in javascript/typescript using [Web Assembly](https://webassembly.org/).\n\n## Security Policy\n\nPlease see our [security policy](./SECURITY.md) for additional details about responsible disclosure of security related issues.\n\n## Relevant References\n\nFor those interested in more details, you might find the following resources helpful\n\n- [BLS12-381 For The Rest Of Us](https://hackmd.io/@benjaminion/bls12-381)\n- [Pairing-based cryptography](https://en.wikipedia.org/wiki/Pairing-based_cryptography)\n- [Exploring Elliptic Curve Pairings](https://vitalik.ca/general/2017/01/14/exploring_ecp.html)\n- [Anonymous Attestation Using the Strong Diffie Hellman Assumption Revisited](https://www.researchgate.net/publication/306347781_Anonymous_Attestation_Using_the_Strong_Diffie_Hellman_Assumption_Revisited)\n- [Pairing Friendly Curves](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-01)\n- BBS+ signature defined in [Anonymous Attestation Using the Strong Diffie Hellman Assumption Revisited](https://eprint.iacr.org/2016/663)\n- Dynamic accumulator defined in [Dynamic Universal Accumulator with Batch Update over Bilinear Groups](https://eprint.iacr.org/2020/777)\n- Verifiable encryption using [SAVER](https://eprint.iacr.org/2019/1270)\n- LegoGroth16, described in the appending H.5 of the [Legosnark paper](https://eprint.iacr.org/2019/142)\n\nTo build, use\n```\nBUILD_MODE=DEBUG ./scripts/build-package.sh \n```\n\nor\n\n```\nBUILD_MODE=RELEASE ./scripts/build-package.sh \n```\n\nor\n\n```\nBUILD_MODE=PROFILING ./scripts/build-package.sh \n```\n\nTo run jest tests, build with target nodejs as `wasm-pack build --out-dir lib --target nodejs` \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocknetwork%2Fcrypto-wasm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocknetwork%2Fcrypto-wasm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocknetwork%2Fcrypto-wasm/lists"}