# JavaScript JOSE Proposal ## Proposed Option Implement DID Comm in Rust, and use wasm for JS (both node.js and browsers) ## All Options 1. Implement DID Comm in Rust, and use wasm for JS (both node.js and browsers) * **Pros:** - Missing primitives for the browser and the NodeJs are supported; - Browser and NodeJs both are supported; - There is a shared implementation of crypto (ECDH-ES, ECDH-1PU, etc.) and probably some JOSE primitives written in, Rust; - Shared crypto lib uses popular low-level crypto libraries specific for the Rust; - Shared crypto lib has wrappers for all needed languages; - Other language-specific libraries use the shared common lib internally, but still have the API idiomatic for the language; - Language-specific libraries depend on neither JOSE nor low-level crypto libs. * **Cons:** - Needs a wrapper per each language; - It's more difficult for the community to maintain DIDComm library. 2. Fork jose, implement the lacked features in it and contribute to upstream. Discussion are created https://github.com/panva/jose/discussions/237. According this discussion draft spec are not welcome. 3. Copy jose code in DIDComm JS library, implement the lacked features for Browsers and NodeJs. We can take a look [elliptic](https://www.npmjs.com/package/elliptic) for native curvers implementation. They provide Ed25519. For asymmetric encription we can take a look OpenpgpJs * **Pros:** - no cross languages dependencies, easier to maintain; - browsers and NodeJs both are supported; - primitives and algorithms are implemented natively; * **Cons:** - DIDComm and JOSE parts are messed over libraries; - more development time. 4. Copy jose code in DIDComm JS library, implement the lacked features only for NodeJs * **Pros:** - The cheapest option; - Primitives are natively supported by the node; - Don't need WASM, don't depend on the shared library. Easily supported by the community; * **Cons:** - No web browser support, potentially losing the largest part of the community; - Support for primitives for the browser can drag on for years, because discussions of this specification have been going on since 2016 and there are no progress. # JavaScript JOSE libraries comparison This document describe result of OpenSource JavaScript's JOSE libraries comparison. * [jose](https://github.com/panva/jose) * [jsrsasign](https://github.com/kjur/jsrsasign) * [js-jose](https://github.com/square/js-jose) * [node-jose](https://github.com/cisco/node-jose) ## Supported JOSE specs * [RFC7515: JSON Web Signature](https://datatracker.ietf.org/doc/html/RFC7515) * [RFC7516: JSON Web Encryption](https://datatracker.ietf.org/doc/html/RFC7516) * [RFC7517: JSON Web Key](https://datatracker.ietf.org/doc/html/RFC7517) * [RFC7518: JSON Web Algorithms](https://datatracker.ietf.org/doc/html/RFC7518) * [RFC7519: JSON Web Token](https://datatracker.ietf.org/doc/html/RFC7519) * [RFC8037: ECDH in JWS and JWE](https://datatracker.ietf.org/doc/html/RFC8037) * [Public Key Authenticated Encryption for JOSE](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04) | Library | JWS | JWE | JWK | JWA | JWT | ECDH-ES | ECHD-1PU | | ----------- |:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:--------:| | jose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | jsrsasign| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | js-jose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | node-jose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | ## Supported curves ### Node.js | Library | X25519 | P-384 | P-256 | | --------- |:------------------:|:------------------:|:------------------:| | jose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | jsrsasign | :x: | :heavy_check_mark: | :heavy_check_mark: | | js-jose | :x: | :heavy_check_mark: | :heavy_check_mark: | | node-jose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ### Browsers | Library | X25519 | P-384 | P-256 | | --------- |:------------------:|:------------------:|:------------------:| | jose | :x: | :heavy_check_mark: | :heavy_check_mark: | | jsrsasign | :x: | :heavy_check_mark: | :heavy_check_mark: | | js-jose | :x: | :heavy_check_mark: | :heavy_check_mark: | | node-jose | :x: | :heavy_check_mark: | :heavy_check_mark: | ## Supported encryption protocols | Library | XC20P | A256GCM | A256CBC-HS512 | | ----------- |:-----:|:------------------:|:------------------:| | jose | :x: | :heavy_check_mark: | :heavy_check_mark: | | jsrsasign | :x: | :heavy_check_mark: | :heavy_check_mark: | | js-jose | :x: | :heavy_check_mark: | :heavy_check_mark: | | node-jose | :x: | :heavy_check_mark: | :heavy_check_mark: | ## Supported signature protocols ### Node.js | Library | EdDSA | ES256 | ES256K | | ----------- |:-----:|:------------------:|:------------------:| | jose | :heavy_check_mark: | :heavy_check_mark: | :x: | | jsrsasign | :x: | :heavy_check_mark: | :x: | | js-jose | :x: | :heavy_check_mark: | :x: | | node-jose | :heavy_check_mark: | :heavy_check_mark: | :x: | ### Browsers | Library | EdDSA | ES256 | ES256K | | ----------- |:-----:|:------------------:|:------------------:| | jose | :x: | :heavy_check_mark: | :x: | | jsrsasign | :x: | :heavy_check_mark: | :x: | | js-jose | :x: | :heavy_check_mark: | :x: | | node-jose | :x: | :heavy_check_mark: | :x: | ## Key Wrapping algorithms supported ### Node.js | Library | ECDH-ES+A256KW (with Ed25519) | | ----------- |:------------------:| | jose | :heavy_check_mark: | | jsrsasign | :x: | | js-jose | :x: | | node-jose | :heavy_check_mark: | ### Browsers | Library | ECDH-ES+A256KW (with Ed25519) | | ----------- |:------------------:| | jose | :x: | | jsrsasign | :x: | | js-jose | :x: | | node-jose | :x: | ## License | Library | License | | ----------- |:-------------------------------------- | | jose | MIT License | | jsrsasign | MIT License | | js-jose | Apache 2 License | | node-jose | Apache 2 License | ## External contributions All libraries are open to external contributions. ## How ECDH-1PU can be supported We need contribute for all libraries. ## Crypto lib - jose uses Web Crypto API for browser and `crypto` for Node - jsrsasign doesn't use external crypto library. - js-jose uses Web Crypto API - node-jose uses Web Crypto API, `node-forge`, `crypto` ## Supported Platform The main issue that `jose`, `js-jose` use Web Crypto API as Crypto Library for browsers, as Web Crypto still doesn't support Ed25519, X25519 curvers. It doesn't support EdDSA as well. `jose` has two runtime implementation for Node.js and for browsers. It uses `crypto` for Node.js, so we can contribute and add Ed25519, X25519 supporting in this case. `node-jose` uses `node-forge`. `node-forge` is a native implemetation `TLS` in JS. It supports Ed25519 for signtature but doesn't support X25519 for key wrapping. So in this case we need contribure X25519 into `node-forge` and after that contribute `ECDH-1PU` into `node-jose`. # Conclusion ## Result Existing libraries use Web Crypto API for browsers or implement it themselves (for example jsrsasign). Currently browsers do not support curves, so we need to search for third-party dependencies like [elliptic](https://www.npmjs.com/package/elliptic). We asked the [jose](https://github.com/panva/jose/discussions/237) if they were interested in contributing, they don't want draft specs. We can create a plugin, but it will need to be maintained in a fork. The likelihood that we will contribute to upstream by October is very small. There are two options left: - implement the library JOSE from scratch natively; - implement the DIDComm on Rust or Kotlin. In terms of time, it comes out the same way, but the common library of didcom can shorten the development time in other languages, for example, on ios. ## WBS ### jose #### For Node.js | Task | Realistic Estimate for Team (man hrs)| Comments | | :----------- |:-------------------------------------- |:-------------------------------------- | | Multi-recipient | 16 || | XC20P | 8 | jose provide plugin for [ChaCha](https://github.com/panva/jose-chacha) | | JSON serialization for JWE | 8 | | ECDH-1PU | 16 | | #### For browser Option 1. | Task | Realistic Estimate for Team (man hrs)| | :----------- |:-------------------| | Wasm lib for ECDH-1PU , EdDSA, XC20P | 40 | Option 2. We can research [elliptic](https://www.npmjs.com/package/elliptic) for native curvers implementation. They provide Ed25519. For asymmetric encription we can take a look [OpenpgpJs](https://openpgpjs.org) | Task | Realistic Estimate for Team (man hrs)| | :----------- |:-------------------| | Native lib for ECDH-1PU , EdDSA | 40 | | XC20P | 24 |