0.0.3 • Published 10 months ago

@nichoth/ratchet v0.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
10 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')