Skip to content

Commit dcbf99a

Browse files
authored
Initial public Swift implementation (#54)
* Initial public Swift implementation * Updating bitrise.yml * Linux fix * Adding Zeroization.swift for linux support
1 parent 44b84fa commit dcbf99a

File tree

14 files changed

+420
-64
lines changed

14 files changed

+420
-64
lines changed

.gitmodules

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
[submodule "Sources/secp256k1/secp256k1"]
2-
path = Sources/secp256k1/secp256k1
1+
[submodule "Sources/bindings/secp256k1"]
2+
path = Sources/bindings/secp256k1
33
url = https://github.com/bitcoin-core/secp256k1
4-
[submodule "Sources/swift-crypto/swift-crypto"]
5-
path = Sources/swift-crypto/swift-crypto
4+
[submodule "Sources/implementation/swift-crypto"]
5+
path = Sources/implementation/swift-crypto
66
url = https://github.com/apple/swift-crypto

Package.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ let package = Package(
1111
.library(
1212
name: "secp256k1",
1313
targets: [
14-
"secp256k1",
15-
"secp256k1_utils"
14+
"secp256k1_bindings",
15+
"secp256k1_implementation"
1616
]
1717
)
1818
],
1919
targets: [
2020
.target(
21-
name: "secp256k1",
22-
path: "Sources/secp256k1",
21+
name: "secp256k1_bindings",
22+
path: "Sources/bindings",
2323
exclude: [
2424
"secp256k1/src/asm",
2525
"secp256k1/src/bench_ecdh.c",
@@ -54,21 +54,28 @@ let package = Package(
5454
),
5555
// Only include select utility extensions because most of Swift Crypto is not required
5656
.target(
57-
name: "secp256k1_utils",
58-
path: "Sources/swift-crypto",
59-
exclude: [
60-
"swift-crypto/Sources",
57+
name: "secp256k1_implementation",
58+
dependencies: [
59+
.target(name: "secp256k1_bindings")
6160
],
61+
path: "Sources/implementation",
6262
sources: [
6363
"swift-crypto/Tests/CryptoTests/Utils/BytesUtil.swift",
64-
"extensions/String.swift"
64+
"swift-crypto/Sources/Crypto/Util/SecureBytes.swift",
65+
"swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift",
66+
"swift-crypto/Sources/Crypto/Util/BoringSSL/SafeCompare_boring.swift",
67+
"Zeroization.swift",
68+
"String.swift",
69+
"secp256k1.swift",
70+
"SafeCompare.swift",
71+
"NISTCurvesKeys.swift"
6572
]
6673
),
6774
.testTarget(
6875
name: "secp256k1Tests",
6976
dependencies: [
70-
"secp256k1",
71-
"secp256k1_utils"
77+
"secp256k1_bindings",
78+
"secp256k1_implementation"
7279
]
7380
)
7481
],

README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# 🔐 secp256k1.swift [![Build Status](https://app.bitrise.io/app/ef44aebd8443b33b/status.svg?token=oDGzN3bMEwseXF_5MQUsTg&branch=main)](https://app.bitrise.io/app/ef44aebd8443b33b) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift)
2-
Swift bindings library for ECDSA signatures and secret/public key operations using [libsecp256k1](https://github.com/bitcoin-core/secp256k1).
1+
[![Build Status](https://app.bitrise.io/app/ef44aebd8443b33b/status.svg?token=oDGzN3bMEwseXF_5MQUsTg&branch=main)](https://app.bitrise.io/app/ef44aebd8443b33b) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGigaBitcoin%2Fsecp256k1.swift%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/GigaBitcoin/secp256k1.swift)
2+
3+
# 🔐 secp256k1.swift
4+
Swift library and bindings for ECDSA signatures and secret/public key operations using [libsecp256k1](https://github.com/bitcoin-core/secp256k1).
5+
36

47
# Objective
5-
This library aims to be a lightweight dependency for clients and wrapper libraries to include ECDSA functionality.
8+
This library aims to be a lightweight wrapper for clients to include ECDSA functionality in Swift. The package aims to stay up-to-date and uses a submodule set to the default git branch of secp256k1.
69

7-
This package is set to the default git branch of secp256k1 and aims to stay up-to-date without using a mirrored repository. An extra module is available for convenience functionality.
810

911
# Getting Started
1012

@@ -15,18 +17,29 @@ dependencies: [
1517
.package(
1618
name: "secp256k1",
1719
url: "https://github.com/GigaBitcoin/secp256k1.swift.git",
18-
from: "0.1.0"
20+
from: "0.2.0"
1921
),
2022
]
2123
```
2224

23-
Currently, this Swift package only provides a single product library built using the `libsecp256k1` [basic config](https://github.com/bitcoin-core/secp256k1/blob/master/src/basic-config.h).
2425

25-
# Usage
26+
# Basic Usage
27+
28+
```swift
29+
import secp256k1
30+
31+
let privateKeyBytes = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".byteArray()
32+
let privatekey = try! secp256k1.Signing.PrivateKey(rawRepresentation: privateKeyBytes)
33+
34+
35+
print(String(byteArray: privatekey.publicKey.rawRepresentation)) // 02734b3511150a60fc8cac329cd5ff804555728740f2f2e98bc4242135ef5d5e4e
36+
```
37+
38+
39+
# Advance Usage
2640

2741
```swift
2842
import secp256k1
29-
import secp256k1_utils
3043

3144
// Initialize context
3245
let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
@@ -52,17 +65,6 @@ print(String(byteArray: pubKey)) // 02734b3511150a60fc8cac329cd5ff804555728740f
5265
secp256k1_context_destroy(context)
5366
```
5467

55-
# Contributing
56-
57-
To start developing, clone the package from github, and from the root directory, run the following commands:
58-
59-
```shell
60-
git clone --recurse-submodules https://github.com/GigaBitcoin/secp256k1.swift
61-
cd secp256k1.swift
62-
swift build
63-
```
64-
65-
Tests can be run by calling `swift test`
6668

6769
# Danger
6870
These APIs should not be considered stable and may change at any time. libsecp256k1 is still experimental and has not been formally released.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// secp256k1.swift
3+
// GigaBitcoin/secp256k1.swift
4+
//
5+
// Modifications Copyright (c) 2020 GigaBitcoin LLC
6+
// Distributed under the MIT software license
7+
//
8+
// See the accompanying file LICENSE for information
9+
//
10+
//
11+
// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC
12+
// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENCE FROM THE
13+
// ORIGINAL WORK OF THE COMPANY Apple Inc.
14+
//
15+
// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT:
16+
//
17+
//
18+
//===----------------------------------------------------------------------===//
19+
//
20+
// This source file is part of the SwiftCrypto open source project
21+
//
22+
// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors
23+
// Licensed under Apache License v2.0
24+
//
25+
// See LICENSE.txt for license information
26+
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
27+
//
28+
// SPDX-License-Identifier: Apache-2.0
29+
//
30+
//===----------------------------------------------------------------------===//
31+
import Foundation
32+
33+
protocol ECPublicKey {
34+
init <Bytes: ContiguousBytes>(rawRepresentation: Bytes) throws
35+
var rawRepresentation: Data { get }
36+
}
37+
38+
protocol ECPrivateKey {
39+
associatedtype PublicKey
40+
var publicKey: PublicKey { get }
41+
}
42+
43+
protocol NISTECPublicKey: ECPublicKey {
44+
init<Bytes: ContiguousBytes>(compactRepresentation: Bytes) throws
45+
init<Bytes: ContiguousBytes>(x963Representation: Bytes) throws
46+
47+
var compactRepresentation: Data? { get }
48+
var x963Representation: Data { get }
49+
}
50+
51+
protocol NISTECPrivateKey: ECPrivateKey where PublicKey: NISTECPublicKey {
52+
init <Bytes: ContiguousBytes>(rawRepresentation: Bytes) throws
53+
var rawRepresentation: Data { get }
54+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// secp256k1.swift
3+
// GigaBitcoin/secp256k1.swift
4+
//
5+
// Modifications Copyright (c) 2020 GigaBitcoin LLC
6+
// Distributed under the MIT software license
7+
//
8+
// See the accompanying file LICENSE for information
9+
//
10+
//
11+
// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC
12+
// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENCE FROM THE
13+
// ORIGINAL WORK OF THE COMPANY Apple Inc.
14+
//
15+
// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT:
16+
//
17+
//
18+
//===----------------------------------------------------------------------===//
19+
//
20+
// This source file is part of the SwiftCrypto open source project
21+
//
22+
// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors
23+
// Licensed under Apache License v2.0
24+
//
25+
// See LICENSE.txt for license information
26+
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
27+
//
28+
// SPDX-License-Identifier: Apache-2.0
29+
//
30+
//===----------------------------------------------------------------------===//
31+
import Foundation
32+
33+
internal func safeCompare<LHS: ContiguousBytes, RHS: ContiguousBytes>(_ lhs: LHS, _ rhs: RHS) -> Bool {
34+
return openSSLSafeCompare(lhs, rhs)
35+
}
File renamed without changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// secp256k1.swift
3+
// GigaBitcoin/secp256k1.swift
4+
//
5+
// Modifications Copyright (c) 2020 GigaBitcoin LLC
6+
// Distributed under the MIT software license
7+
//
8+
// See the accompanying file LICENSE for information
9+
//
10+
//
11+
// NOTICE: THIS FILE HAS BEEN MODIFIED BY GigaBitcoin LLC
12+
// UNDER COMPLIANCE WITH THE APACHE 2.0 LICENCE FROM THE
13+
// ORIGINAL WORK OF THE COMPANY Apple Inc.
14+
//
15+
// THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT:
16+
//
17+
//
18+
//===----------------------------------------------------------------------===//
19+
//
20+
// This source file is part of the SwiftCrypto open source project
21+
//
22+
// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors
23+
// Licensed under Apache License v2.0
24+
//
25+
// See LICENSE.txt for license information
26+
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
27+
//
28+
// SPDX-License-Identifier: Apache-2.0
29+
//
30+
//===----------------------------------------------------------------------===//
31+
#if !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))
32+
33+
typealias errno_t = CInt
34+
35+
// This is a Swift wrapper for the libc function that does not exist on Linux. The original
36+
// shim used `OPENSSL_cleanse`, unfortunately we do not want to include openssl. This shim now
37+
// (1) starts with a `UnsafeMutableRawPointer`, (2) creates an `UnsafeMutableBufferPointer`,
38+
// and (3) iterates through the buffer pointer setting each element to 0.
39+
@discardableResult
40+
func memset_s(_ s: UnsafeMutableRawPointer!, _ smax: Int, _ byte: CInt, _ n: Int) -> errno_t {
41+
assert(smax == n, "memset_s invariant not met")
42+
assert(byte == 0, "memset_s used to not zero anything")
43+
let pointer = s.bindMemory(to: UInt8.self, capacity: smax)
44+
let bufferPointer = UnsafeMutableBufferPointer(start: pointer, count: smax)
45+
for i in stride(from: bufferPointer.startIndex, to: bufferPointer.endIndex, by: 1) {
46+
bufferPointer[i] = 0
47+
}
48+
return 0
49+
}
50+
#endif

0 commit comments

Comments
 (0)