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 Curve25519All 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 -> DataThe 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) -> BoolVRF 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 -> DataKey agreement
Create a shared secret between a private and a public key.
func calculateAgreement(privateKey: Data, publicKey: Data) throws -> DataErrors
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>!) -> Int32Documentation
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'