x3dh

package module
v0.0.0-...-f0fcdf8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2018 License: MIT Imports: 5 Imported by: 0

README

x3dh

standard-readme compliant Build Status (master)

An x3dh implementation.

This is an almost complete implementation of the x3dh key agreement protocol. However, there are a few things that you need to take care of yourself:

  1. If you fetch a preKeyBundle (holds information about the person you would like to chat with, like the identity key, etc) you have to check the signature yourself. It's not built into the code. We only "ask you" IF the key is valid. You can then say yes/no. If you say no, the protocol will be aborted.
  2. You are responsible for handling the initial message (and the encoding), we only give you the calculated secret + the ephemeral key generated during the protocol run.
  3. Currently we only support curve25519 (but you can implement the Curve interface in order to use another curve).

Table of Contents

Security

If you find a security bug/ vulnerability please DO NOT open an issue. Write to security@bitnation.co PLEASE use this PGP key to encrypt your report / email.

Install

go get github.com/Bit-Nation/x3dh

It might make sense to chose a dependency manager of your choise to pin the version to a specific commit.

Usage

// create an instance of the curve util
c := &Curve25519{}

// make sure ot save this somewhere
myKeyPair, err := c.GenerateKeyPair()

x := x3dh.New(c, sha256.New(), "test", myKeyPair)

API

The following methods are available:

  • CalculateSecret calculate a secret based on your Idkey and a received PreKeyBundle.
  • SecretFromRemote create a secret based on the received intial data.

Maintainers

@florianlenz

Contribute

Pull requests are accepted.

Small note: If editing the README, please conform to the standard-readme specifications.

License

MIT © 2018 Bitnation

Documentation

Index

Constants

This section is empty.

Variables

View Source
var PreKeyBundleInvalidSignature = errors.New("the signature of the received pre key bundle is invalid")

returned in case the pre key bundle signature is invalid

Functions

This section is empty.

Types

type Curve

type Curve interface {
	KeyExchange(keys DHPair) [32]byte
	PreFix() []byte
	GenerateKeyPair() (KeyPair, error)
}

interface for the curve that should be used by x3dh we currently only support curve25519

type Curve25519

type Curve25519 struct {
	// contains filtered or unexported fields
}

func NewCurve25519

func NewCurve25519(randSource io.Reader) Curve25519

func (*Curve25519) GenerateKeyPair

func (c *Curve25519) GenerateKeyPair() (KeyPair, error)

create a new curve25519 key pair from a random source

func (*Curve25519) KeyExchange

func (c *Curve25519) KeyExchange(dh DHPair) [32]byte

calculate a diffie hellman key exchange with given key pair

func (*Curve25519) PreFix

func (c *Curve25519) PreFix() []byte

prefix for curve25519 is a byte array of length 32 filled with 0xFF

type DHPair

type DHPair struct {
	PrivateKey PrivateKey
	PublicKey  PublicKey
}

key pair for diffie hellman key exchange

type InitializedProtocol

type InitializedProtocol struct {
	SharedSecret      SharedSecret
	UsedOneTimePreKey *PublicKey
	UsedSignedPreKey  PublicKey
	EphemeralKey      PublicKey
}

type KeyPair

type KeyPair struct {
	PublicKey  PublicKey
	PrivateKey PrivateKey
}

type PreKeyBundle

type PreKeyBundle interface {
	IdentityKey() PublicKey
	SignedPreKey() PublicKey
	OneTimePreKey() *PublicKey
	// this is actually the method in which
	// you need to check if the signature
	// of the PreKey is valid. YOU HAVE
	// TO DO this your self. In case this
	// method returns false the process of
	// creating an shared secret will be aborted.
	ValidSignature() (bool, error)
}

the PreKeyBundle holds information about the person you would like to start chatting with. You need to implement this interface your self.

type PrivateKey

type PrivateKey [32]byte

type ProtocolInitialisation

type ProtocolInitialisation struct {
	RemoteIdKey        PublicKey
	RemoteEphemeralKey PublicKey
	MyOneTimePreKey    *PrivateKey
	MySignedPreKey     PrivateKey
}

type PublicKey

type PublicKey [32]byte

type SharedSecret

type SharedSecret = [32]byte

the shared secret between you and the partner

type TestPreKeyBundle

type TestPreKeyBundle struct {
	// contains filtered or unexported fields
}

ONLY FOR TESTING

func (TestPreKeyBundle) IdentityKey

func (b TestPreKeyBundle) IdentityKey() PublicKey

func (TestPreKeyBundle) OneTimePreKey

func (b TestPreKeyBundle) OneTimePreKey() *PublicKey

func (TestPreKeyBundle) SignedPreKey

func (b TestPreKeyBundle) SignedPreKey() PublicKey

func (TestPreKeyBundle) ValidSignature

func (b TestPreKeyBundle) ValidSignature() (bool, error)

type X3dh

type X3dh struct {
	// contains filtered or unexported fields
}

func New

func New(c Curve, h hash.Hash, info string, myIDKey KeyPair) X3dh

create a new X3dh key agreement protocol info is just your protocol name. Something like ("pangea") myIDKey is your curve25519 key pair

func (*X3dh) CalculateSecret

func (x *X3dh) CalculateSecret(b PreKeyBundle) (InitializedProtocol, error)

calculate a shared secret based on a received preKeyBundle

func (*X3dh) NewKeyPair

func (x *X3dh) NewKeyPair() (KeyPair, error)

func (*X3dh) SecretFromRemote

func (x *X3dh) SecretFromRemote(c ProtocolInitialisation) (SharedSecret, error)

calculate secret based on received on data from initial message

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL