Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.1
21 changes: 21 additions & 0 deletions Ed25519.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Pod::Spec.new do |s|
s.name = 'Ed25519'
s.version = '1.1.0'
s.summary = 'Ed25519 for Swift 4'
s.homepage = 'https://github.com/AndrewBarba/ed25519'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = 'Zsolt Váradi'
s.source = { :git => 'https://github.com/AndrewBarba/ed25519.git', :tag => s.version.to_s }

s.pod_target_xcconfig = { 'SWIFT_WHOLE_MODULE_OPTIMIZATION' => 'YES',
'APPLICATION_EXTENSION_API_ONLY' => 'YES' }

s.ios.deployment_target = '10.0'
s.osx.deployment_target = '10.12'
s.tvos.deployment_target = '10.0'
s.watchos.deployment_target = '3.0'

s.source_files = 'Sources/Ed25519/**/*.swift'

s.dependency 'libCEd25519', '~> 1.1.0'
end
17 changes: 14 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
// swift-tools-version:3.1
// swift-tools-version:4.1

import PackageDescription

let package = Package(
name: "Ed25519",
products: [
.library(name: "Ed25519", targets: ["Ed25519"]),
],
targets: [
Target(name: "Ed25519", dependencies: ["CEd25519"])
]
.target(
name: "Ed25519",
dependencies: ["CEd25519"]
),
.target(
name: "CEd25519",
dependencies: []
)
],
swiftLanguageVersions: [4]
)
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Ed25519 for Swift 3.x
=====================
# Ed25519 for Swift 4

![Swift](http://img.shields.io/badge/swift-3.0-brightgreen.svg) [![CircleCI](https://circleci.com/gh/vzsg/ed25519.svg?style=shield)](https://circleci.com/gh/vzsg/ed25519)
[![CircleCI](https://circleci.com/gh/vzsg/ed25519.svg?style=shield)](https://circleci.com/gh/vzsg/ed25519)


This project is a Swift adaptation of the portable C [Ed25519](http://ed25519.cr.yp.to/)
implementation available [here](https://github.com/orlp/ed25519).
implementation available [here](https://github.com/orlp/ed25519).
The complete functionality,
including the key exchange and scalar addition functions are available.

Expand All @@ -17,7 +16,9 @@ Installation
To integrate the library in your SwiftPM project, add the following dependency to Package.swift:

```swift
.Package(url: "https://github.com/vzsg/ed25519.git", majorVersion: 0, minor: 1)
// swift-tools-version:4.1

.package(url: "https://github.com/AndrewBarba/ed25519.git", from: "1.0.0")
```

API
Expand All @@ -27,15 +28,15 @@ API
let seed = try Seed()
```

Creates a 32 byte random seed for key generation.
Creates a 32 byte random seed for key generation.
May throw `Ed25519Error.seedGenerationFailed` in case there was a problem with reading from `/dev/urandom`.

```swift
let seedBytes: [UInt8] = [ ... ]
let seed2 = try Seed(bytes: bytes)
```

Creates a seed for key generation with a previously known value.
Creates a seed for key generation with a previously known value.
`bytes` must be an array of 32 bytes, otherwise `Ed25519Error.invalidSeedLength` will be thrown.

```swift
Expand All @@ -50,7 +51,7 @@ let privBytes: [UInt8] = [ ... ]
let keyPair2 = try KeyPair(publicKey: pubBytes, privateKey: privBytes)
```

Creates a key pair from the previously known public and private keys.
Creates a key pair from the previously known public and private keys.
Throws `Ed25519Error.invalidPublicKeyLength` if the public key is not 32,
or `Ed25519Error.invalidPrivateKeyLength` if the private key is not 64 bytes long.

Expand All @@ -60,7 +61,7 @@ let privateKey = try PrivateKey(privBytes)
let keyPair3 = KeyPair(publicKey: publicKey, privateKey: privateKey)
```

Construct public and private keys directly.
Construct public and private keys directly.
The same length limitations and exceptions apply.

```swift
Expand All @@ -78,15 +79,15 @@ let message: [UInt8] = [ ... ]
let signature: [UInt8] = keyPair.sign(message: message)
```

Creates a signature of the given message with the given key pair.
Creates a signature of the given message with the given key pair.
`signature` will be an array of 64 bytes.

```swift
let valid: Bool = try keyPair.verify(signature: signature, message: message)
let valid2: Bool = try publicKey.verify(signature: signature, message: message)
```

Verifies the signature on the given message using a key pair or a public key.
Verifies the signature on the given message using a key pair or a public key.
Both methods throw `Ed25519Error.invalidSignatureLength` if `signature` is not an array of 64 bytes.

```swift
Expand Down Expand Up @@ -121,6 +122,6 @@ License

The Swift library is released under the MIT license. See LICENSE for details.

The C implementation is (c) 2015 Orson Peters, licensed under the permissive zlib license.
The original source code is not modified, only reorganized for SwiftPM consumption.
The C implementation is (c) 2015 Orson Peters, licensed under the permissive zlib license.
The original source code is not modified, only reorganized for SwiftPM consumption.
See license.txt in CEd25519 for details.
1 change: 1 addition & 0 deletions Sources/CEd25519/include/ed25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char
int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key);
void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);
void ED25519_DECLSPEC ed25519_extract_public_key(unsigned char *public_key, unsigned char *private_key);


#ifdef __cplusplus
Expand Down
7 changes: 7 additions & 0 deletions Sources/CEd25519/keypair.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_ke
ge_scalarmult_base(&A, private_key);
ge_p3_tobytes(public_key, &A);
}

void ed25519_extract_public_key(unsigned char *public_key, unsigned char *private_key) {
ge_p3 point;

ge_scalarmult_base(&point, private_key);
ge_p3_tobytes(public_key, &point);
}
31 changes: 24 additions & 7 deletions Sources/Ed25519/PublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import CEd25519

public final class PublicKey {
private let buffer: [UInt8]

public convenience init(_ bytes: [UInt8]) throws {
guard bytes.count == 32 else {
throw Ed25519Error.invalidPublicKeyLength
}

self.init(unchecked: bytes)
}

init(unchecked buffer: [UInt8]) {
self.buffer = buffer
}

public var bytes: [UInt8] {
return buffer
}
Expand All @@ -40,17 +40,34 @@ public final class PublicKey {
guard scalar.count == 32 else {
throw Ed25519Error.invalidScalarLength
}

var pub = buffer

pub.withUnsafeMutableBufferPointer { pub in
scalar.withUnsafeBufferPointer { scalar in
ed25519_add_scalar(pub.baseAddress,
nil,
scalar.baseAddress)
}
}


return PublicKey(unchecked: pub)
}
}

extension PublicKey {

public static func derive(fromSecret bytes: [UInt8]) -> PublicKey {
var buffer = bytes

var pub = [UInt8](repeating: 0, count: 32)

buffer.withUnsafeMutableBufferPointer { priv in
pub.withUnsafeMutableBufferPointer { pub in
ed25519_extract_public_key(pub.baseAddress, priv.baseAddress)
}
}

return PublicKey(unchecked: pub)
}
}
21 changes: 21 additions & 0 deletions libCEd25519.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Pod::Spec.new do |s|
s.name = 'libCEd25519'
s.module_name = 'CEd25519'
s.version = '1.1.0'
s.summary = 'Main dependency for Ed25519'
s.homepage = 'https://github.com/AndrewBarba/ed25519'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = 'Zsolt Váradi'
s.source = { :git => 'https://github.com/AndrewBarba/ed25519.git', :tag => s.version.to_s }

s.pod_target_xcconfig = { 'SWIFT_WHOLE_MODULE_OPTIMIZATION' => 'YES',
'APPLICATION_EXTENSION_API_ONLY' => 'YES' }

s.ios.deployment_target = '10.0'
s.osx.deployment_target = '10.12'
s.tvos.deployment_target = '10.0'
s.watchos.deployment_target = '3.0'

s.source_files = 'Sources/CEd25519/**/*.{c,h}'
s.public_header_files = 'Sources/CEd25519/**/*.h'
end