|  |  |  |  | # fast-jwt
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | [](https://npm.im/fast-jwt) | 
					
						
							|  |  |  |  | [](https://github.com/nearform/fast-jwt/actions/workflows/ci.yml) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <!-- [](https://codecov.io/gh/nearform/fast-jwt) --> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Fast JSON Web Token implementation. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Installation
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Just run: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | npm install fast-jwt | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Usage
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### createSigner
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Create a signer function by calling `createSigner` and providing one or more of the following options: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `key`: A string or a buffer containing the secret for `HS*` algorithms or the PEM encoded private key for `RS*`, `PS*`, `ES*` and `EdDSA` algorithms. If the `key` is a passphrase protected private key it must be an object (more details below). The key can also be a function accepting a Node style callback or a function returning a promise. This is the only mandatory option, which MUST NOT be provided if the token algorithm is `none`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `algorithm`: The algorithm to use to sign the token. The default value is autodetected from the key, using `RS256` for RSA private keys, `HS256` for plain secrets and the corresponding `ES` or `EdDSA` algorithms for EC or Ed\* private keys. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `mutatePayload`: If set to `true`, the original payload will be modified in place (via `Object.assign`) by the signing function. This is useful if you need a raw reference to the payload after claims have been applied to it but before it has been encoded into a token. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `expiresIn`: Time span (in milliseconds) after which the token expires, added as the `exp` claim in the payload as defined by the [section 4.1.4 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4). This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `notBefore`: Time span (in milliseconds) before the token is active, added as the `nbf` claim in the payload as defined by the [section 4.1.5 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5). This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `jti`: The token unique identifier, added as the `jti` claim in the payload as defined by the [section 4.1.7 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7). This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `aud`: The token audience, added as the `aud` claim in the payload as defined by the [section 4.1.3 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). This claim identifies the recipients that the token is intended for. It must be a string or an array of strings. This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `iss`: The token issuer, added as the `iss` claim in the payload as defined by the [section 4.1.1 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1). It must be a string. This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `sub`: The token subject, added as the `sub` claim in the payload as defined by the [section 4.1.2 of RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2). It must be a string. This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `nonce`: The token nonce, added as the `nonce` claim in the payload. The `nonce` value is used to associate a Client session with an ID Token. Note that this is a [IANA JSON Web Token Claims Registry](https://www.iana.org/assignments/jwt/jwt.xhtml#claims) public claim registered by OpenID Connect (OIDC). It must be a string. This will override any existing value in the claim. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `kid`: The token key id, added as the `kid` claim in the header section (see [section 4.1.4 of RFC 7515](https://www.rfc-editor.org/rfc/rfc7515#section-4.1.4) and [section 4.5 of RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517#section-4.5)). It must be a string. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `header`: Additional claims to add to the header section. This will override the `typ` and `kid` claims. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `noTimestamp`: If set to `true`, the `iat` claim should not be added to the token. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `clockTimestamp`: The timestamp in milliseconds (like the output of `Date.now()`) that should be used as the current time for all necessary time comparisons. Default is the system time. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The signer is a function which accepts a payload and returns the token. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The payload must be an object. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If the `key` option is a function, the signer will also accept a Node style callback and will return a promise, supporting therefore both callback and async/await styles. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If the `key` is a passphrase protected private key, the `algorithm` option must be provided and must be either a `RS*` or `ES*` encoded key and the `key` option must be an object with the following structure: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```js | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   key: '<YOUR_RSA_ENCRYPTED_PRIVATE_KEY>', | 
					
						
							|  |  |  |  |   passphrase: '<PASSPHRASE_THAT_WAS_USED_TO_ENCRYPT_THE_PRIVATE_KEY>' | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### Example
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```javascript | 
					
						
							|  |  |  |  | const { createSigner } = require('fast-jwt') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Sync style | 
					
						
							|  |  |  |  | const signSync = createSigner({ key: 'secret' }) | 
					
						
							|  |  |  |  | const token = signSync({ a: 1, b: 2, c: 3 }) | 
					
						
							|  |  |  |  | // => eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Callback style | 
					
						
							|  |  |  |  | const signWithCallback = createSigner({ key: (callback) => callback(null, 'secret') }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | signWithCallback({ a: 1, b: 2, c: 3 }, (err, token) => { | 
					
						
							|  |  |  |  |   // token === eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Promise style - Note that the key function style and the signer function style are unrelated | 
					
						
							|  |  |  |  | async function test() { | 
					
						
							|  |  |  |  |   const signWithPromise = createSigner({ key: async () => 'secret' }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   const token = await signWithPromise({ a: 1, b: 2, c: 3 }) | 
					
						
							|  |  |  |  |   // => eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Using password protected private key - in this case you MUST provide the algorithm as well | 
					
						
							|  |  |  |  | const signSync = createSigner({ | 
					
						
							|  |  |  |  |   algorithm: '<ANY_RS*_OR_ES*_ALGORITHM>', | 
					
						
							|  |  |  |  |   key: { | 
					
						
							|  |  |  |  |     key: '<YOUR_RSA_ENCRYPTED_PRIVATE_KEY>', | 
					
						
							|  |  |  |  |     passphrase: '<PASSPHRASE_THAT_WAS_USED_TO_ENCRYPT_THE_PRIVATE_KEY>' | 
					
						
							|  |  |  |  |   }) | 
					
						
							|  |  |  |  | const token = signSync({ a: 1, b: 2, c: 3 }) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### createDecoder
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Create a decoder function by calling `createDecoder` and providing one or more of the following options: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `complete`: Return an object with the decoded header, payload, signature and input (the token part before the signature), instead of just the content of the payload. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `checkTyp`: When validating the decoded header, setting this option forces the check of the `typ` property against this value. Example: `checkTyp: 'JWT'`. Default is `undefined`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The decoder is a function which accepts a token (as Buffer or string) and returns the payload or the sections of the token. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### Examples
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```javascript | 
					
						
							|  |  |  |  | const { createDecoder } = require('fast-jwt') | 
					
						
							|  |  |  |  | const token = | 
					
						
							|  |  |  |  |   'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Standard decoder | 
					
						
							|  |  |  |  | const decode = createDecoder() | 
					
						
							|  |  |  |  | const payload = decode(token) | 
					
						
							|  |  |  |  | // => { a: 1, b: 2, c: 3, iat: 1579521212 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Complete decoder | 
					
						
							|  |  |  |  | const decodeComplete = createDecoder({ complete: true }) | 
					
						
							|  |  |  |  | const sections = decodeComplete(token) | 
					
						
							|  |  |  |  | /* =>  | 
					
						
							|  |  |  |  |   {  | 
					
						
							|  |  |  |  |     header: { alg: 'HS512', typ: 'JWT' },  | 
					
						
							|  |  |  |  |     payload: { a: 1, b: 2, c: 3, iat: 1579521212 }, | 
					
						
							|  |  |  |  |     signature: 'mIcxteEVjbh2MnKQ3EQlojZojGSyA/guqRBYHQURcfnCSSBTT2OShF8lo9/ogjAv+5oECgmCur/cDWB7x3X53g==', | 
					
						
							|  |  |  |  |     input: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9'  | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | */ | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### createVerifier
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Create a verifier function by calling `createVerifier` and providing one or more of the following options: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `key`: A string or a buffer containing the secret for `HS*` algorithms or the PEM encoded public key for `RS*`, `PS*`, `ES*` and `EdDSA` algorithms. The key can also be a function accepting a Node style callback or a function returning a promise. This is the only mandatory option, which MUST NOT be provided if the token algorithm is `none`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `algorithms`: List of strings with the names of the allowed algorithms. By default, all algorithms are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `complete`: Return an object with the decoded header, payload, signature and input (the token part before the signature), instead of just the content of the payload. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `cache`: A positive number specifying the size of the verified tokens cache (using LRU strategy). Setting to `true` is equivalent to provide the size `1000`. When enabled, as you can see in the benchmarks section below, performances dramatically improve. By default the cache is disabled. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `cacheTTL`: The maximum time to live of a cache entry (in milliseconds). If the token has a earlier expiration or the verifier has a shorter `maxAge`, the earlier takes precedence. The default is `600000`, which is 10 minutes. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `errorCacheTTL`: A number or function `function (tokenError) => number` that represents the maximum time to live of a cache error entry (in milliseconds). Example: the `key` function fails or does not return a secret or public key. By default **errors are not cached**, the `errorCacheTTL` default value is `-1`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `allowedJti`: A string, a regular expression, an array of strings or an array of regular expressions containing allowed values for the id claim (`jti`). By default, all values are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `allowedAud`: A string, a regular expression, an array of strings or an array of regular expressions containing allowed values for the audience claim (`aud`). By default, all values are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `allowedIss`: A string, a regular expression, an array of strings or an array of regular expressions containing allowed values for the issuer claim (`iss`). By default, all values are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `allowedSub`: A string, a regular expression, an array of strings or an array of regular expressions containing allowed values for the subject claim (`sub`). By default, all values are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `allowedNonce`: A string, a regular expression, an array of strings or an array of regular expressions containing allowed values for the nonce claim (`nonce`). By default, all values are accepted. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `requiredClaims`: An array of strings containing which claims should exist in the token. By default, no claim is marked as required. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `ignoreExpiration`: Do not validate the expiration of the token. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `ignoreNotBefore`: Do not validate the activation of the token. Default is `false`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `maxAge`: The maximum allowed age (in milliseconds) for tokens to still be valid. By default this is not checked. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `clockTimestamp`: The timestamp in milliseconds (like the output of `Date.now()`) that should be used as the current time for all necessary time comparisons. Default is the system time. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | - `clockTolerance`: Timespan in milliseconds is the tolerance to apply to the current timestamp when performing time comparisons. Default is `0`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The verifier is a function which accepts a token (as Buffer or string) and returns the payload or the sections of the token. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If the `key` option is a function, the signer will also accept a Node style callback and will return a promise, supporting therefore both callback and async/await styles. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### Examples
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```javascript | 
					
						
							|  |  |  |  | const { createVerifier, TOKEN_ERROR_CODES } = require('fast-jwt') | 
					
						
							|  |  |  |  | const token = | 
					
						
							|  |  |  |  |   'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Sync style | 
					
						
							|  |  |  |  | const verifySync = createVerifier({ key: 'secret' }) | 
					
						
							|  |  |  |  | const payload = verifySync(token) | 
					
						
							|  |  |  |  | // => { a: 1, b: 2, c: 3, iat: 1579521212 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Callback style with complete return | 
					
						
							|  |  |  |  | const verifyWithCallback = createVerifier({ key: callback => callback(null, 'secret'), complete: true }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | verifyWithCallback(token, (err, sections) => { | 
					
						
							|  |  |  |  |   /* | 
					
						
							|  |  |  |  |   sections === { | 
					
						
							|  |  |  |  |     header: { alg: 'HS512', typ: 'JWT' }, | 
					
						
							|  |  |  |  |     payload: { a: 1, b: 2, c: 3, iat: 1579521212 }, | 
					
						
							|  |  |  |  |     signature: 'mIcxteEVjbh2MnKQ3EQlojZojGSyA/guqRBYHQURcfnCSSBTT2OShF8lo9/ogjAv+5oECgmCur/cDWB7x3X53g==', | 
					
						
							|  |  |  |  |     input: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9' | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | */ | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Promise style - Note that the key function style and the verifier function style are unrelated | 
					
						
							|  |  |  |  | async function test() { | 
					
						
							|  |  |  |  |   const verifyWithPromise = createVerifier({ key: async () => 'secret' }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   const payload = await verifyWithPromise(token) | 
					
						
							|  |  |  |  |   // => { a: 1, b: 2, c: 3, iat: 1579521212 } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // custom errorCacheTTL verifier | 
					
						
							|  |  |  |  | const verifier = createVerifier({ | 
					
						
							|  |  |  |  |   key: 'secret', | 
					
						
							|  |  |  |  |   cache: true, | 
					
						
							|  |  |  |  |   errorCacheTTL: tokenError => { | 
					
						
							|  |  |  |  |     // customize the ttl based on the error code | 
					
						
							|  |  |  |  |     if (tokenError.code === TOKEN_ERROR_CODES.invalidKey) { | 
					
						
							|  |  |  |  |       return 1000 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return 2000 | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Algorithms supported
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | This is the lisf of currently supported algorithms: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | | Name    | Description                                                             | | 
					
						
							|  |  |  |  | | ------- | ----------------------------------------------------------------------- | | 
					
						
							|  |  |  |  | | `none`  | Empty algorithm - The token signature section will be empty             | | 
					
						
							|  |  |  |  | | `HS256` | HMAC using SHA-256 hash algorithm                                       | | 
					
						
							|  |  |  |  | | `HS384` | HMAC using SHA-384 hash algorithm                                       | | 
					
						
							|  |  |  |  | | `HS512` | HMAC using SHA-512 hash algorithm                                       | | 
					
						
							|  |  |  |  | | `ES256` | ECDSA using P-256 curve and SHA-256 hash algorithm                      | | 
					
						
							|  |  |  |  | | `ES384` | ECDSA using P-384 curve and SHA-384 hash algorithm                      | | 
					
						
							|  |  |  |  | | `ES512` | ECDSA using P-521 curve and SHA-512 hash algorithm                      | | 
					
						
							|  |  |  |  | | `RS256` | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm                          | | 
					
						
							|  |  |  |  | | `RS384` | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm                          | | 
					
						
							|  |  |  |  | | `RS512` | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm                          | | 
					
						
							|  |  |  |  | | `PS256` | RSASSA-PSS using SHA-256 hash algorithm                                 | | 
					
						
							|  |  |  |  | | `PS384` | RSASSA-PSS using SHA-384 hash algorithm                                 | | 
					
						
							|  |  |  |  | | `PS512` | RSASSA-PSS using SHA-512 hash algorithm                                 | | 
					
						
							|  |  |  |  | | `EdDSA` | EdDSA tokens using Ed25519 or Ed448 keys, only supported on Node.js 12+ | | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Caching
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | fast-jwt supports caching of verified tokens. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The cache layer, powered by [mnemonist](https://www.npmjs.com/package/mnemonist), is a LRU cache which dimension is controlled by the user, as described in the options list. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | When caching is enabled, verified tokens are always stored in cache. If the verification fails once, the error is cached as well for the time set by `errorCacheTTL` and the operation is not retried. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | For verified tokens, caching considers the time sensitive claims of the token (`iat`, `nbf` and `exp`) and make sure the verification is retried after a token becomes valid or after a token becomes expired. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Performances improvements varies by uses cases and by the type of the operation performed and the algorithm used. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | > **_Note:_** Errors are not cached by default, to change this behaviour use the `errorCacheTTL` option.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Token Error Codes
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | [Error codes](https://github.com/nearform/fast-jwt/blob/master/src/error.js) exported by `TOKEN_ERROR_CODES`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## JWKS
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | JWKS is supported via [get-jwks](https://github.com/nearform/get-jwks). Check out the documentation for integration examples. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Benchmarks
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### Signing
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | ╔══════════════════════════════╤═════════╤═════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                 │ Samples │          Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (async)     │   10000 │ 55766.29 op/sec │  ± 2.85 % │                         ║ | 
					
						
							|  |  |  |  | ║ HS512 - jsonwebtoken (async) │   10000 │ 68764.89 op/sec │  ± 1.25 % │ + 23.31 %               ║ | 
					
						
							|  |  |  |  | ║ HS512 - jsonwebtoken (sync)  │   10000 │ 70191.14 op/sec │  ± 1.84 % │ + 25.87 %               ║ | 
					
						
							|  |  |  |  | ║ HS512 - jose (sync)          │   10000 │ 72844.84 op/sec │  ± 1.72 % │ + 30.63 %               ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                 │ Samples │          Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (sync)      │   10000 │ 97602.16 op/sec │  ± 1.83 % │ + 75.02 %               ║ | 
					
						
							|  |  |  |  | ╚══════════════════════════════╧═════════╧═════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔══════════════════════════════╤═════════╤═══════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (async)     │    1000 │ 419.29 op/sec │  ± 0.34 % │                         ║ | 
					
						
							|  |  |  |  | ║ ES512 - jsonwebtoken (async) │    1000 │ 440.53 op/sec │  ± 0.26 % │ + 5.07 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - jsonwebtoken (sync)  │    1000 │ 445.91 op/sec │  ± 0.16 % │ + 6.35 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - jose (sync)          │    1000 │ 452.01 op/sec │  ± 0.20 % │ + 7.80 %                ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (sync)      │    1000 │ 467.54 op/sec │  ± 0.15 % │ + 11.51 %               ║ | 
					
						
							|  |  |  |  | ╚══════════════════════════════╧═════════╧═══════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔══════════════════════════════╤═════════╤═══════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (async)     │    1000 │ 196.13 op/sec │  ± 0.28 % │                         ║ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken (async) │    1000 │ 200.15 op/sec │  ± 0.23 % │ + 2.05 %                ║ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken (sync)  │    1000 │ 203.72 op/sec │  ± 0.18 % │ + 3.87 %                ║ | 
					
						
							|  |  |  |  | ║ RS512 - jose (sync)          │    1000 │ 245.89 op/sec │  ± 0.39 % │ + 25.37 %               ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (sync)      │    1000 │ 273.31 op/sec │  ± 0.27 % │ + 39.36 %               ║ | 
					
						
							|  |  |  |  | ╚══════════════════════════════╧═════════╧═══════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔══════════════════════════════╤═════════╤═══════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ PS512 - jsonwebtoken (sync)  │    1000 │ 194.00 op/sec │  ± 0.27 % │                         ║ | 
					
						
							|  |  |  |  | ║ PS512 - jsonwebtoken (async) │    1000 │ 202.08 op/sec │  ± 0.21 % │ + 4.17 %                ║ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (async)     │    1000 │ 203.36 op/sec │  ± 0.19 % │ + 4.82 %                ║ | 
					
						
							|  |  |  |  | ║ PS512 - jose (sync)          │    1000 │ 266.54 op/sec │  ± 0.29 % │ + 37.39 %               ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                 │ Samples │        Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────────┼─────────┼───────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (sync)      │    1000 │ 272.11 op/sec │  ± 0.24 % │ + 40.26 %               ║ | 
					
						
							|  |  |  |  | ╚══════════════════════════════╧═════════╧═══════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔══════════════════════════╤═════════╤═════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests             │ Samples │          Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (async) │    1000 │  8301.50 op/sec │  ± 0.70 % │                         ║ | 
					
						
							|  |  |  |  | ║ EdDSA - jose (sync)      │    1500 │ 16561.83 op/sec │  ± 0.88 % │ + 99.50 %               ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test             │ Samples │          Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟──────────────────────────┼─────────┼─────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (sync)  │    3000 │ 17514.99 op/sec │  ± 0.94 % │ + 110.99 %              ║ | 
					
						
							|  |  |  |  | ╚══════════════════════════╧═════════╧═════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### Decoding
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | ╔═════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                    │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken - complete │   10000 │ 126201.23 op/sec │  ± 2.84 % │                         ║ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken            │   10000 │ 143571.03 op/sec │  ± 1.82 % │ + 13.76 %               ║ | 
					
						
							|  |  |  |  | ║ RS512 - jose - complete         │   10000 │ 252738.76 op/sec │  ± 5.62 % │ + 100.27 %              ║ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt                │   10000 │ 254921.59 op/sec │  ± 3.39 % │ + 102.00 %              ║ | 
					
						
							|  |  |  |  | ║ RS512 - jose                    │   10000 │ 266197.51 op/sec │  ± 4.02 % │ + 110.93 %              ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                    │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt - complete     │   10000 │ 284719.82 op/sec │  ± 3.39 % │ + 125.61 %              ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Note that for decoding the algorithm is irrelevant, so only one was measured. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### Verifying
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | ╔═════════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ HS512 - jsonwebtoken (sync)         │   10000 │  49275.12 op/sec │  ± 1.41 % │                         ║ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (async)            │   10000 │  51353.81 op/sec │  ± 2.98 % │ + 4.22 %                ║ | 
					
						
							|  |  |  |  | ║ HS512 - jsonwebtoken (async)        │   10000 │  51610.98 op/sec │  ± 1.51 % │ + 4.74 %                ║ | 
					
						
							|  |  |  |  | ║ HS512 - jose (sync)                 │   10000 │  64280.92 op/sec │  ± 1.73 % │ + 30.45 %               ║ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (sync)             │   10000 │  75067.57 op/sec │  ± 2.40 % │ + 52.34 %               ║ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (async with cache) │   10000 │ 175013.21 op/sec │  ± 4.42 % │ + 255.18 %              ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ HS512 - fast-jwt (sync with cache)  │   10000 │ 207199.64 op/sec │  ± 3.15 % │ + 320.50 %              ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔═════════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (async)            │    1000 │    561.01 op/sec │  ± 0.44 % │                         ║ | 
					
						
							|  |  |  |  | ║ ES512 - jsonwebtoken (sync)         │    1000 │    573.52 op/sec │  ± 0.27 % │ + 2.23 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - jsonwebtoken (async)        │    1000 │    573.74 op/sec │  ± 0.26 % │ + 2.27 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (sync)             │    1000 │    597.68 op/sec │  ± 0.30 % │ + 6.54 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - jose (sync)                 │    1000 │    604.42 op/sec │  ± 0.27 % │ + 7.74 %                ║ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (async with cache) │   10000 │ 189999.48 op/sec │  ± 4.49 % │ + 33767.60 %            ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ ES512 - fast-jwt (sync with cache)  │   10000 │ 192353.61 op/sec │  ± 4.79 % │ + 34187.22 %            ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔═════════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken (async)        │    1500 │   7551.10 op/sec │  ± 0.92 % │                         ║ | 
					
						
							|  |  |  |  | ║ RS512 - jsonwebtoken (sync)         │    4500 │   7750.46 op/sec │  ± 0.96 % │ + 2.64 %                ║ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (async)            │    1000 │   8413.41 op/sec │  ± 0.99 % │ + 11.42 %               ║ | 
					
						
							|  |  |  |  | ║ RS512 - jose (sync)                 │    4500 │  12382.58 op/sec │  ± 0.94 % │ + 63.98 %               ║ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (sync)             │    4500 │  12665.45 op/sec │  ± 0.90 % │ + 67.73 %               ║ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (sync with cache)  │   10000 │ 145107.65 op/sec │  ± 7.54 % │ + 1821.68 %             ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ RS512 - fast-jwt (async with cache) │   10000 │ 158780.83 op/sec │  ± 3.90 % │ + 2002.75 %             ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔═════════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ PS512 - jsonwebtoken (async)        │    2500 │   7240.21 op/sec │  ± 0.89 % │                         ║ | 
					
						
							|  |  |  |  | ║ PS512 - jsonwebtoken (sync)         │    2000 │   7449.38 op/sec │  ± 0.91 % │ + 2.89 %                ║ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (async)            │    1500 │   8301.99 op/sec │  ± 0.81 % │ + 14.67 %               ║ | 
					
						
							|  |  |  |  | ║ PS512 - jose (sync)                 │    4000 │  11944.57 op/sec │  ± 0.99 % │ + 64.98 %               ║ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (sync)             │    1000 │  12881.96 op/sec │  ± 0.76 % │ + 77.92 %               ║ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (async with cache) │   10000 │ 155603.59 op/sec │  ± 4.27 % │ + 2049.16 %             ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ PS512 - fast-jwt (sync with cache)  │   10000 │ 172097.91 op/sec │  ± 4.58 % │ + 2276.97 %             ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ╔═════════════════════════════════════╤═════════╤══════════════════╤═══════════╤═════════════════════════╗ | 
					
						
							|  |  |  |  | ║ Slower tests                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (async)            │    1000 │   6370.58 op/sec │  ± 0.59 % │                         ║ | 
					
						
							|  |  |  |  | ║ EdDSA - jose (sync)                 │    1000 │   6538.90 op/sec │  ± 0.83 % │ + 2.64 %                ║ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (sync)             │    1000 │   7078.93 op/sec │  ± 0.87 % │ + 11.12 %               ║ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (async with cache) │   10000 │ 177457.09 op/sec │  ± 5.36 % │ + 2685.57 %             ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ Fastest test                        │ Samples │           Result │ Tolerance │ Difference with slowest ║ | 
					
						
							|  |  |  |  | ╟─────────────────────────────────────┼─────────┼──────────────────┼───────────┼─────────────────────────╢ | 
					
						
							|  |  |  |  | ║ EdDSA - fast-jwt (sync with cache)  │   10000 │ 202628.41 op/sec │  ± 3.12 % │ + 3080.69 %             ║ | 
					
						
							|  |  |  |  | ╚═════════════════════════════════════╧═════════╧══════════════════╧═══════════╧═════════════════════════╝ | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Contributing
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | See [CONTRIBUTING.md](./CONTRIBUTING.md) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## License
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Copyright NearForm Ltd 2020-2021. Licensed under the [Apache-2.0 license](http://www.apache.org/licenses/LICENSE-2.0). |