Skip to content

Commit

Permalink
Bootstrap swift package creation
Browse files Browse the repository at this point in the history
  • Loading branch information
csjones committed Jul 5, 2020
1 parent c659301 commit 06ea5a8
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 10 deletions.
17 changes: 10 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,20 @@ DerivedData/
timeline.xctimeline
playground.xcworkspace

## macOS
.DS_Store

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
Packages/
Package.pins
Package.resolved
*.xcodeproj

# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.swiftpm

.build/

Expand All @@ -57,7 +60,7 @@ playground.xcworkspace
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
*.xcworkspace

# Carthage
#
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "Sources/secp256k1/secp256k1"]
path = Sources/secp256k1/secp256k1
url = https://github.com/bitcoin-core/secp256k1
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 GigaBitcoin
Copyright (c) 2020 GigaBitcoin LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
55 changes: 55 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "secp256k1",
products: [
// The `libsecp256k1` bindings to programatically work with Swift.
//
// WARNING: These APIs should not be considered stable and may change at any time.
.library(
name: "secp256k1",
targets: ["secp256k1"]
)
],
targets: [
.target(
name: "secp256k1",
path: "Sources/secp256k1",
exclude: [
"secp256k1/src/asm",
"secp256k1/src/bench_ecdh.c",
"secp256k1/src/bench_ecmult.c",
"secp256k1/src/bench_internal.c",
"secp256k1/src/bench_recover.c",
"secp256k1/src/bench_sign.c",
"secp256k1/src/bench_verify.c",
"secp256k1/src/gen_context.c",
"secp256k1/src/tests_exhaustive.c",
"secp256k1/src/tests.c",
"secp256k1/src/valgrind_ctime_test.c"
],
cSettings: [
.headerSearchPath("secp256k1"),
// Basic config values that are universal and require no dependencies.
//
// https://github.com/bitcoin-core/secp256k1/blob/master/src/basic-config.h#L29-L34
.define("USE_NUM_NONE"),
.define("USE_FIELD_INV_BUILTIN"),
.define("USE_SCALAR_INV_BUILTIN"),
.define("USE_FIELD_10X26"),
.define("USE_SCALAR_8X32"),
.define("ECMULT_WINDOW_SIZE", to: "15", nil),
.define("ECMULT_GEN_PREC_BITS", to: "4", nil)
]
),
.testTarget(
name: "secp256k1Tests",
dependencies: ["secp256k1"]
)
],
swiftLanguageVersions: [.v5],
cLanguageStandard: .c89
)
65 changes: 63 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,63 @@
# secp256k1.swift
Swift bindings library for ECDSA signatures and secret/public key operations using the libsecp256k1 C library.
# 🔐 secp256k1.swift
Swift bindings library for ECDSA signatures and secret/public key operations using the [libsecp256k1](https://github.com/bitcoin-core/secp256k1) C library.

# Objective
This library aims is 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.

# Getting Started

In your `Package.swift`:

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

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).

# Usage

```swift
import secp256k1

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

// 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]

// 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 {
// 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, ... ]

// Destory context after creation
secp256k1_context_destroy(context)
```

# Contributing

To start developing, clone the package from github, and from the root directory, run the following commands:

```shell
git submodule update --init
swift build
```

Tests can be run by calling `swift test`

# Danger
These APIs should not be considered stable and may change at any time. libsecp256k1 is still experimental and has not been formally released.

4 changes: 4 additions & 0 deletions Sources/secp256k1/include/secp256k1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "../secp256k1/include/secp256k1_ecdh.h"
#include "../secp256k1/include/secp256k1_preallocated.h"
#include "../secp256k1/include/secp256k1_recovery.h"
#include "../secp256k1/include/secp256k1.h"
1 change: 1 addition & 0 deletions Sources/secp256k1/secp256k1
Submodule secp256k1 added at 3f4a5a
7 changes: 7 additions & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import XCTest

import secp256k1Tests

var tests = [XCTestCaseEntry]()
tests += secp256k1Tests.allTests()
XCTMain(tests)
9 changes: 9 additions & 0 deletions Tests/secp256k1Tests/XCTestManifests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import XCTest

#if !canImport(ObjectiveC)
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(secp256k1Tests.allTests),
]
}
#endif
47 changes: 47 additions & 0 deletions Tests/secp256k1Tests/secp256k1Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import XCTest
@testable import secp256k1

final class secp256k1Tests: XCTestCase {
/// Basic Keypair test
func testKeypairCreation() {
// 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 = 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]

// 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)

// 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
]

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

static var allTests = [
("testKeypairCreation", testKeypairCreation),
]
}
28 changes: 28 additions & 0 deletions bitrise.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
format_version: '8'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: other
trigger_map:
- push_branch: "*"
workflow: Entry-Workflow
- pull_request_source_branch: "*"
workflow: Entry-Workflow
workflows:
Distribute:
steps:
- swift-package-manager-test-for-mac@0: {}
- deploy-to-bitrise-io@1: {}
Entry-Workflow:
steps:
- activate-ssh-key@4:
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
- git-clone@4: {}
- script@1:
title: Trigger Bitrise Workflow
inputs:
- content: bitrise --ci run --secret-filtering --workflow Code-Review --config
bitrise.yml
Code-Review:
steps:
- swift-package-manager-test-for-mac@0: {}
- deploy-to-bitrise-io@1: {}

0 comments on commit 06ea5a8

Please sign in to comment.