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'