0.0.3 • Published 9 months ago

@nichoth/ratchet v0.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

ratchet

tests types module semantic versioning Common Changelog install size license

Key ratcheting in typescript, implemented with noble crypto.

Read some API docs

install

npm i -S @nichoth/ratchet

Example

See the tests for more examples.

Create a new keypair

import { create } from '@nichoth/ratchet'
const alice = create()

// => {
//    ed25519: {
//        privateKey:Uint8Array
//        publicKey:Uint8Array
//    };
//    x25519: {
//        privateKey:Uint8Array
//        publicKey:Uint8Array
//     }
//  }

Encrypt a new message

This returns a tuple of [Message, { keys }], where keys is the new keypair that was created for this message. A string version of the public key is embedded in the message.

function message (
    text:string|Uint8Array,
    theirPublicKey:string|X25519Keys['publicKey'],
    author:DID,
    newKeypair?:{
        privateKey:string|X25519Keys['publicKey'],
        publicKey: string|X25519Keys['privateKey']
    },
    info?:string
):[Message, { keys:X25519Keys }]
import { message } from '@nichoth/ratchet'

// a message from Alice to Bob
const [msg, { keys }] = message(
    'hello world',
    bob.x25519.publicKey,
    alicesDid
)

Pass in the public key from the previous message to ratchet the keys.

const [newMsg, { keys }] = message(
    'hello again',
    prevMsg.keys.publicKey,
    alicesDid
)

Decrypt a message

Decrypt the given message with the matching private key.

import { decryptMsg } from '@nichoth/ratchet'

// pass in the message and the keypair containing the relevant secret key
const decrypted =  decryptMsg(msg, bob.x25519)

Types

All the key types are just aliases to Uint8Array.

Ed25519Keys

interface Ed25519Keys {
    privateKey:Uint8Array;
    publicKey:Uint8Array;
}

X25519Keys

type X25519Keys = Ed25519Keys;

DID

type DID = `did:key:z${string}`;

Keys

These are aliases to Uint8Array.

interface Keys {
    ed25519: {
        privateKey:Ed25519Keys['privateKey'];
        publicKey:Ed25519Keys['publicKey'];
    };
    x25519: {
        privateKey:X25519Keys['privateKey'];
        publicKey:X25519Keys['publicKey'];
    }
}

Message

interface Message {
    keys:{  // <-- base64pad encoded
        publicKey:string;
    };
    author:DID;
    body:{
        text:string;
    };
}

An encrypted message looks like this:

{
    keys: { publicKey: 'W+V510cXyL6LT8+MIT7KmE9+PccQtTOZwWNCYG+EVxY=' },
    author: 'did:key:z6Mker5GURbWxk3YxW8vet9dt1Mk55D97hzLDGBtSpMBm21S',
    body: {
        text: 'HnlVO3QvJJQhdqmM8EGnsJgmgYpu/GOXl2OR/EFPptk8RdGvLxxmG4vQQ2pNpm2JxEvlfoZC'
    }
}

Decrypted, it looks like this:

{
    keys: { publicKey: 'W+V510cXyL6LT8+MIT7KmE9+PccQtTOZwWNCYG+EVxY=' },
    author: 'did:key:z6Mker5GURbWxk3YxW8vet9dt1Mk55D97hzLDGBtSpMBm21S',
    body: { text: 'hello messages' }
}

API

This exposes ESM and common JS via package.json exports field.

ESM

import { create, encrypt } from '@nichoth/ratchet'

Common JS

const { create, encrypt } = require('@nichoth/ratchet')