{"id":18601588,"url":"https://github.com/peculiarventures/2key-ratchet","last_synced_at":"2025-04-08T04:17:21.644Z","repository":{"id":18819476,"uuid":"80312226","full_name":"PeculiarVentures/2key-ratchet","owner":"PeculiarVentures","description":"2key-ratchet is an implementation of a Double Ratchet protocol and X3DH in TypeScript utilizing WebCrypto.","archived":false,"fork":false,"pushed_at":"2023-01-06T02:40:12.000Z","size":464,"stargazers_count":109,"open_issues_count":30,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-14T23:15:40.726Z","etag":null,"topics":["cryptography","diffie-hellman","ecc","encryption","integrity","javascript","privacy","secp256r1","secrecy","session","typescript","webcrypto"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PeculiarVentures.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-28T21:33:21.000Z","updated_at":"2024-04-02T01:11:19.000Z","dependencies_parsed_at":"2023-01-13T20:01:40.787Z","dependency_job_id":null,"html_url":"https://github.com/PeculiarVentures/2key-ratchet","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2F2key-ratchet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2F2key-ratchet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2F2key-ratchet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeculiarVentures%2F2key-ratchet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeculiarVentures","download_url":"https://codeload.github.com/PeculiarVentures/2key-ratchet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773721,"owners_count":20993639,"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":["cryptography","diffie-hellman","ecc","encryption","integrity","javascript","privacy","secp256r1","secrecy","session","typescript","webcrypto"],"created_at":"2024-11-07T02:08:48.584Z","updated_at":"2025-04-08T04:17:21.621Z","avatar_url":"https://github.com/PeculiarVentures.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 2key-ratchet\n\n[![CircleCI](https://circleci.com/gh/PeculiarVentures/2key-ratchet.svg?style=svg\u0026circle-token=29f5d4fefececbe5668f0c0858cc583e4e130765)](https://circleci.com/gh/PeculiarVentures/2key-ratchet)\n[![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/PeculiarVentures/2key-ratchet/master/LICENSE.md)\n[![Coverage Status](https://coveralls.io/repos/github/PeculiarVentures/2key-ratchet/badge.svg?branch=master)](https://coveralls.io/github/PeculiarVentures/2key-ratchet?branch=master)\n[![npm version](https://badge.fury.io/js/2key-ratchet.svg)](https://badge.fury.io/js/2key-ratchet)\n\n[![NPM](https://nodei.co/npm/2key-ratchet.png)](https://nodei.co/npm/2key-ratchet/)\n\n\n`2key-ratchet` is an implementation of a [Double Ratchet](https://whispersystems.org/docs/specifications/doubleratchet/) protocol and [X3DH](https://whispersystems.org/docs/specifications/x3dh) in TypeScript utilizing WebCrypto. \n\nThe Double Ratchet protocol and X3DH were designed with goals of providing both forward secrecy and cryptographic deniability. Importantly there have been several independent [security reviews](https://eprint.iacr.org/2016/1013.pdf) that concluded they deliver on those goals.\n\nThe term “Double Ratchet” comes from how the protocol makes sure each message gets a new key: their [Diffie-Hellman keys are “ratcheted”](https://github.com/PeculiarVentures/2key-ratchet/blob/master/src/classes/asym_ratchet.ts) by each new message exchange; and so are the send/receive chains (the [“symmetric-key ratchet”](https://github.com/PeculiarVentures/2key-ratchet/blob/master/src/classes/sym_ratchet.ts)).\n\nThere are a few [differences](https://github.com/PeculiarVentures/2key-ratchet/blob/master/DIFFERENCES.md) between the original specifications and `2key-ratchet`, the most significant being, as it’s name suggests, it uses [two keys](https://github.com/PeculiarVentures/2key-ratchet/blob/3538a1481b4249830549e1c1d251fb6a7a7512ec/src/classes/data/identity.ts#L18-L19), one for authentication and another for key exchange. The other big one is that secp256r1 is used instead of curve25519 because browsers do not yet support this curve natively.\n\nSee the [ARCHITECTURE](https://github.com/PeculiarVentures/2key-ratchet/blob/master/ARCHITECTURE.md) document to better understand the library structure.\n\nFor ideas on where you might use `2key-ratchet` see the [SCENARIOS](https://github.com/PeculiarVentures/2key-ratchet/blob/master/SCENARIOS.md) document.\n\nFor licensing information, see the [LICENSE](https://github.com/PeculiarVentures/2key-ratchet/blob/master/LICENSE.md) file.\n\n## Overview\n\n### IdentityKeys\n\nEach peer in the protocol has an `IdentityKey`, these are secp256r1 keys. These keys are used to authenticate both `PreKeys` and `ExchangeKeys`. `IdentityKeys` are used similarly to the public key in an X.509 certificate.\n\n\n### ExchangeKeys\n\nExchangeKeys are introduced by `2key-ratchet`, they are used to derive `PreKeys`. The `ExchangeKey` is signed by a peers `IdentityKey`.\n\n### PreKeys\n\nIn `2key-ratchet` a PreKey is a secp256r1 public key with an associated unique id. These `PreKeys` are signed by the `IdentityKey`.\n\nOn first use, clients generate a single signed PreKey, as well as a large list of unsigned PreKeys, and transmit all of them to a server.\n\n### Server\n\nThe server in the protocol is an untrusted entity, it simply stores preKeys for retrieval when the peer may be offline and unreachable.\n\n### Sessions\n\nThe Double Ratchet protocol is session-oriented. Peers establish a `session` with each other, this is then used for all subsequent exchanges. These sessions can remain open and be re-used since each message is encrypted with a new and unique cryptographic key.\n\n## Size and Dependencies\n\n| Name            | Size   | Description                                    |\n|-----------------|--------|------------------------------------------------|\n| 2key-ratchet.js |  66 Kb | UMD module without external modules            | \n\n__NOTE:__ You will also have to import [tslib](https://github.com/Microsoft/tslib) and [protobufjs](https://github.com/dcodeIO/ProtoBuf.js/#browsers) for use in the browser.\n\n\n## Instructions\n\n### Installation\n\n```\nnpm install 2key-ratchet\n```\n\n\n### Usage\n\nInclude `2key-ratchet` and its dependencies in your application.\n\nNODEJS:\n\n```javascript\nlet DKeyRatchet = require(\"2key-ratchet\");\n```\n\nBROWSER:\n\n```html\n\u003cscript src=\"2key-ratchet.js\"\u003e\u003c/script\u003e\n```\n\n\nThe `DKeyRatchet` namespace will always be available globally and also supports AMD loaders.\n\n#### Generate an IdentityKey\n\nThe first step is to create an IdentityKey.\n\n```javascript\nlet AliceID;\nDKeyRatchet.Identity.create(16453, 1, 1)\n    .then((id) =\u003e {\n        AliceID = id;\n    });\n```\n\nThen create your PreKey message bundle:\n\n```javascript\nlet bundle = new DKeyRatchet.PreKeyBundleProtocol();\n\nbundle.identity.fill(AliceID)\n    .then(() =\u003e {\n        bundle.registrationId = AliceID.id;\n        const preKey = AliceID.signedPreKeys[0];\n        bundle.preKeySigned.id = 1;\n        bundle.preKeySigned.key = preKey.publicKey;\n        return bundle.preKeySigned.sign(AliceID.signingKey.privateKey);\n    })\n    .then(() =\u003e {\n        return bundle.exportProto();\n    })\n    .then((ab) =\u003e {\n        console.log(ab); // ArrayBuffer { byteLength: 374 }\n    });\n``` \n\nAnd then import the generated PreKey message bundle:\n\n```javascript\nDKeyRatchet.PreKeyBundleProtocol.importProto(ab)\n    .then((bundle) =\u003e {\n        // check signed prekey\n        return bundle.preKeySigned.verify(AliceID.signingKey.publicKey);\n    })\n    .then((trusted) =\u003e {\n        if (!trusted)\n            throw new Error(\"Error: The PreKey is not trusted\");\n    })\n```\n\n#### Create a session\nWith the previous steps complete you can now create a session:\n\n\u003e NOTE: For data conversion was used module `pvtsutils`. \n\n```javascript\nDKeyRatchet.AsymmetricRatchet.create(BobID, bundle)\n    .then((cipher) =\u003e {\n        return cipher.encrypt(Convert.FromUtf8String(\"Hello world!\"));\n    })\n    .then((preKeyMessage) =\u003e {\n        return preKeyMessage.exportProto();\n    })\n    .then((BobMessage) =\u003e {\n        console.log(BobMessage); // ArrayBuffer {byteLength: 408}\n    });\n```\n\nOn the other side you would do the same:\n\n```javascript\n// Parse received bytes to proto\nreturn DKeyRatchet.PreKeyMessageProtocol.importProto(BobMessage)\n    .then((proto) =\u003e {\n        return DKeyRatchet.AsymmetricRatchet.create(AliceID, proto)\n            .then((cipher) =\u003e {\n                return cipher.decrypt(proto.signedMessage);\n            })\n            .then((message) =\u003e {\n                console.log(Convert.ToUtf8String(message)); // Hello world!\n            });\n    });\n```\n\nWe have a [complete example you can look at here](https://github.com/PeculiarVentures/2key-ratchet/tree/master/src/examples).\n\n## Contributing\n\nIf you've found an problem with 2key-ratchet, please open a new issue. Feature requests are welcome, too.\n\nPull requests – patches, improvements, new features – are a fantastic help. Please ask first before embarking on any significant pull request (e.g., implementing new features).\n\n## Note\n\nBruce Schneier famously said \"If you think cryptography can solve your problem, then you don't understand your problem and you don't understand cryptography\". The point being, using 2key-ratchet, or any other \"cryptography related\" library, will not necessarily make your product secure. \n\nIn short, there is a lot more to making a secure product than adding cryptography, [this is a great book to get you familiar with thinking defensively](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998).\n\n### WARNING\nThough this library is based on [the Double Ratchet Algorithm](https://whispersystems.org/docs/specifications/doubleratchet/) and [the X3DH Key Agreement Protocol](https://whispersystems.org/docs/specifications/x3dh/) several [changes](https://github.com/PeculiarVentures/2key-ratchet/blob/master/DIFFERENCES.md) have been made that could change the security properties they offer. At this time you should consider this implementation appropriate for experimentation until further security reviews are completed.\n\n## Acknowledgements\nBoth Double Ratchet and X3DH were designed by Trevor Perrin and Moxie Marlinspike, we thank them for their work.\n\n## Related\n- [A Formal Security Analysis of the Signal Messaging Protocol](https://eprint.iacr.org/2016/1013.pdf)\n- [WhatsApp Security Paper Analysis](https://courses.csail.mit.edu/6.857/2016/files/36.pdf)\n- [Web Cryptography API](https://www.w3.org/TR/2016/PR-WebCryptoAPI-20161215/)\n- [The X3DH Key Agreement Protocol](https://whispersystems.org/docs/specifications/x3dh/)\n- [The Double Ratchet Algorithm](https://whispersystems.org/docs/specifications/doubleratchet/)\n- [Google Key Transparency](https://github.com/google/keytransparency)\n- [OMEMO Multi-End Message and Object Encryption](https://xmpp.org/extensions/xep-0384.html)\n- [Matrix OLM](https://matrix.org/docs/guides/e2e_implementation.html)\n- [Double Ratchet \u0026 the Quantum Computers](https://www.fredericjacobs.com/blog/2016/04/07/qc-axolotl/)\n- [CryptoCat Encryption Overview](https://crypto.cat/security.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeculiarventures%2F2key-ratchet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeculiarventures%2F2key-ratchet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeculiarventures%2F2key-ratchet/lists"}