Curve25519 2.0.0

Curve25519 2.0.0

Maintained by Christoph Hagen.



  • By
  • Christoph Hagen

Curve25519

A small framework to use Curve25519 functions in Swift.

Purpose

This framework was created to provide a Swift API to the Elliptic Curve functions needed for the Signal Protocol. It encapsulates the pure C implementation found in libsignal-protocol-c.

The framework is used in the Swift implementation of the Signal Protocol.

Installation

The framework can be installed by using Cocoapods. Include in your Podfile:

pod 'Curve25519'

The version depends on the Swift version you use:

  • Swift 5: 1.1
  • Swift 4.2: 1.0.1
  • Swift 4: 1.0

Usage

Once the Framework is included in your project, simply

import Curve25519

All features are available through static functions of the Curve25519 class, for example:

let agreement = Curve25519.calculateAgreement(privateKey: priv, publicKey: pub)

Features

The framework provides the following features:

Creating public keys for private keys

Create the corresponding public key for a 32 byte private key.

func publicKey(for privateKey: Data, basepoint: Data) throws -> Data

The function will return nil if the inputs have the wrong size.

Signing and verifying messages

It is possible to sign a message with a private key, and then verify the message with a public key.

func signature(for message: Data, privateKey: Data, randomData: Data) throws -> Data

func verify(signature: Data, for message: Data, publicKey: Data) -> Bool

VRF signature and verification

Additionally it is possible to create and verify VRF (Verifiable Random Function) signatures.

func vrfSignature(for message: Data, privateKey: Data, randomData: Data) throws -> Data

func verify(vrfSignature: Data, for message: Data, publicKey: Data) throws -> Data

Key agreement

Create a shared secret between a private and a public key.

func calculateAgreement(privateKey: Data, publicKey: Data) throws -> Data

Errors

Some of the functions can throw errors if the inputs are invalid. All errors thrown for these functions are of type CurveError, which is an enum that conforms to the CustomStringConvertible protocol. This makes it easy to check for the errors in code, and to print them for debugging.

Directly using C functions

Additionally all C functions are exposed directly for use:

// Public key creation
func curve25519_donna(_ pub: UnsafeMutablePointer<UInt8>!,
                      _ priv: UnsafePointer<UInt8>!,
                      _ base: UnsafePointer<UInt8>!) -> Int32

// Signing
func curve25519_sign(
                  _ signature_out: UnsafeMutablePointer<UInt8>!,
                  _ curve25519_privkey: UnsafePointer<UInt8>!,
                  _ msg: UnsafePointer<UInt8>!,
                  _ msg_len: UInt,
                  _ random: UnsafePointer<UInt8>!) -> Int32

// Verification
func curve25519_verify(
                  _ signature: UnsafePointer<UInt8>!,
                  _ curve25519_pubkey: UnsafePointer<UInt8>!,
                  _ msg: UnsafePointer<UInt8>!,
                  _ msg_len: UInt) -> Int32

// VRF signature
func generalized_xveddsa_25519_sign(
                  _ signature_out: UnsafeMutablePointer<UInt8>!,
                  _ x25519_privkey_scalar: UnsafePointer<UInt8>!,
                  _ msg: UnsafePointer<UInt8>!,
                  _ msg_len: UInt,
                  _ random: UnsafePointer<UInt8>!,
                  _ customization_label: UnsafePointer<UInt8>!,
                  _ customization_label_len: UInt) -> Int32

// VRF verification
func generalized_xveddsa_25519_verify(
                  _ vrf_out: UnsafeMutablePointer<UInt8>!,
                  _ signature: UnsafePointer<UInt8>!,
                  _ x25519_pubkey_bytes: UnsafePointer<UInt8>!,
                  _ msg: UnsafePointer<UInt8>!,
                  _ msg_len: UInt,
                  _ customization_label: UnsafePointer<UInt8>!,
                  _ customization_label_len: UInt) -> Int32

// Agreement
func curve25519_donna(_ shared: UnsafeMutablePointer<UInt8>!,
                      _ priv: UnsafePointer<UInt8>!,
                      _ pub: UnsafePointer<UInt8>!) -> Int32

Documentation

The project is documented heavily because it helps other people understand the code. The documentation is created with jazzy, which creates awesome, apple-like docs.

The docs can be (re-)generated by running the following in the project directory:

jazzy --min-acl private -a 'Christoph Hagen' -u 'https://github.com/christophhagen' -g 'https://github.com/christophhagen/Curve25519' -o 'Documentation'