Skip to content

Commit

Permalink
Adding utility module (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
csjones authored Sep 2, 2020
1 parent 2a6af20 commit 326e73b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "Sources/secp256k1/secp256k1"]
path = Sources/secp256k1/secp256k1
url = https://github.com/bitcoin-core/secp256k1
[submodule "Sources/swift-crypto/swift-crypto"]
path = Sources/swift-crypto/swift-crypto
url = https://github.com/apple/swift-crypto
21 changes: 19 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ let package = Package(
// WARNING: These APIs should not be considered stable and may change at any time.
.library(
name: "secp256k1",
targets: ["secp256k1"]
targets: [
"secp256k1",
"secp256k1_utils"
]
)
],
targets: [
Expand Down Expand Up @@ -42,9 +45,23 @@ let package = Package(
.define("ECMULT_GEN_PREC_BITS", to: "4", nil)
]
),
// Only include select utility extensions because most of Swift Crypto is not required
.target(
name: "secp256k1_utils",
path: "Sources/swift-crypto",
exclude: [
"swift-crypto/Sources",
],
sources: [
"swift-crypto/Tests/CryptoTests/Utils/BytesUtil.swift"
]
),
.testTarget(
name: "secp256k1Tests",
dependencies: ["secp256k1"]
dependencies: [
"secp256k1",
"secp256k1_utils"
]
)
],
swiftLanguageVersions: [.v5],
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# 🔐 secp256k1.swift [![Build Status](https://app.bitrise.io/app/ef44aebd8443b33b/status.svg?token=oDGzN3bMEwseXF_5MQUsTg&branch=main)](https://app.bitrise.io/app/ef44aebd8443b33b)
Swift bindings library for ECDSA signatures and secret/public key operations using the [libsecp256k1](https://github.com/bitcoin-core/secp256k1) C library.
Swift bindings library for ECDSA signatures and secret/public key operations using [libsecp256k1](https://github.com/bitcoin-core/secp256k1).

# Objective
This library aims to be a lightweight dependency for clients and wrapper libraries to include ECDSA functionality.

This package targets the default git branch of secp256k1 and aims to stay up-to-date without using a mirrored repository.
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.

# Getting Started

In your `Package.swift`:

```swift
dependencies: [
.package(name: "secp256k1", url: "https://github.com/GigaBitcoin/secp256k1.swift.git", from: "0.0.1"),
.package(name: "secp256k1", url: "https://github.com/GigaBitcoin/secp256k1.swift.git", from: "0.0.11"),
]
```

Expand All @@ -22,26 +22,27 @@ Currently, this Swift package only provides a single product library built using

```swift
import secp256k1
import secp256k1_utils

// Initialize context
let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!

// Setup private and public key variables
var pubkeyLen = 65
var pubkeyLen = 33
var cPubkey = secp256k1_pubkey()
var pubkey = [UInt8](repeating: 0, count: pubkeyLen)
let privkey: [UInt8] = [0,1,0,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,32,0]
let privkey = try! Array(hexString: "14e4a74438858920d8a35fb2d88677580b6a2ee9be4e711ae34ec6b396d87b5c")

// Verify the context and keys are setup correctly
guard secp256k1_context_randomize(context, privkey) == 1,
secp256k1_ec_pubkey_create(context, &cPubkey, privkey) == 1,
secp256k1_ec_pubkey_serialize(context, &pubkey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_UNCOMPRESSED)) == 1 else {
secp256k1_ec_pubkey_serialize(context, &pubkey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_COMPRESSED)) == 1 else {
// Destory context after creation
secp256k1_context_destroy(context)
return
}

print(pubkey) // [4,96,104, 212, 128, 165, 213, 207, 134, 132, 22, 247, 38, 114, 82, 108, 77, 43, 6, 56, ... ]
print(pubkey.hexString) // 02734b3511150a60fc8cac329cd5ff804555728740f2f2e98bc4242135ef5d5e4e

// Destory context after creation
secp256k1_context_destroy(context)
Expand Down
1 change: 1 addition & 0 deletions Sources/swift-crypto/swift-crypto
Submodule swift-crypto added at afe4c9
69 changes: 45 additions & 24 deletions Tests/secp256k1Tests/secp256k1Tests.swift
Original file line number Diff line number Diff line change
@@ -1,47 +1,68 @@
import XCTest
@testable import secp256k1
@testable import secp256k1_utils

final class secp256k1Tests: XCTestCase {
/// Basic Keypair test
func testKeypairCreation() {
/// Uncompressed Keypair test
func testUncompressedKeypairCreation() {
// Initialize context
let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!

// Destory context after execution
defer {
secp256k1_context_destroy(context)
}
defer { secp256k1_context_destroy(context) }

// Setup private and public key variables
var pubkeyLen = 65
var cPubkey = secp256k1_pubkey()
var pubkey = [UInt8](repeating: 0, count: pubkeyLen)
let privkey: [UInt8] = [0,1,0,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,0,0,1,0,0,1,1,0,0,1,0,0,32,0]
var publicKey = [UInt8](repeating: 0, count: pubkeyLen)

let privateKey = try! Array(hexString: "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".lowercased())

// Verify the context and keys are setup correctly
XCTAssertEqual(secp256k1_context_randomize(context, privateKey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_create(context, &cPubkey, privateKey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_serialize(context, &publicKey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_UNCOMPRESSED)), 1)

let hexString = """
04734B3511150A60FC8CAC329CD5FF804555728740F2F2E98BC4242135EF5D5E4E6C4918116B0866F50C46614F3015D8667FBFB058471D662A642B8EA2C9C78E8A
"""

// Define the expected public key
let expectedPublicKey = try! Array(hexString: hexString.lowercased())

// Verify the generated public key matches the expected public key
XCTAssertEqual(expectedPublicKey, publicKey)
}

/// Compressed Keypair test
func testCompressedKeypairCreation() {
// Initialize context
let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!

// Destory context after execution
defer { secp256k1_context_destroy(context) }

// Setup private and public key variables
var pubkeyLen = 33
var cPubkey = secp256k1_pubkey()
var publicKey = [UInt8](repeating: 0, count: pubkeyLen)

let privateKey = try! Array(hexString: "B035FCFC6ABF660856C5F3A6F9AC51FCA897BB4E76AD9ACA3EFD40DA6B9C864B".lowercased())

// Verify the context and keys are setup correctly
XCTAssertEqual(secp256k1_context_randomize(context, privkey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_create(context, &cPubkey, privkey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_serialize(context, &pubkey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_UNCOMPRESSED)), 1)
XCTAssertEqual(secp256k1_context_randomize(context, privateKey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_create(context, &cPubkey, privateKey), 1)
XCTAssertEqual(secp256k1_ec_pubkey_serialize(context, &publicKey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_COMPRESSED)), 1)

// Define the expected public key
let expectedPublicKey: [UInt8] = [
4,96,104, 212, 128, 165, 213,
207, 134, 132, 22, 247, 38,
114, 82, 108, 77, 43, 6, 56,
80, 113, 12, 11, 119, 7, 240,
188, 73, 170, 44, 202, 33, 225,
30, 248, 53, 138, 34, 22, 100,
96, 31, 76, 64, 125, 71, 127,
62, 155, 108, 243, 17, 222, 97,
234, 75, 247, 187, 83, 151, 206,
27, 38, 228
]
let expectedPublicKey = try! Array(hexString: "02EA724B70B48B61FB87E4310871A48C65BF38BF3FDFEFE73C2B90F8F32F9C1794".lowercased())

// Verify the generated public key matches the expected public key
XCTAssertEqual(expectedPublicKey, pubkey)
XCTAssertEqual(expectedPublicKey, publicKey)
}

static var allTests = [
("testKeypairCreation", testKeypairCreation),
("testUncompressedKeypairCreation", testUncompressedKeypairCreation),
("testCompressedKeypairCreation", testCompressedKeypairCreation),
]
}

0 comments on commit 326e73b

Please sign in to comment.