Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CSecp256k1

Release Upstream Watch Swift Platforms License

Swift Package Manager binary distribution of Bitcoin Core libsecp256k1 for Apple platforms.

This package exists because SwiftPM is good at distributing Swift packages, but Apple apps still need a correctly sliced, module-map-backed XCFramework when they consume libsecp256k1 as C. CSecp256k1 gives Swift projects a small, auditable package URL instead of asking each app to vendor a binary framework or repeat the C build machinery.

The C source is not forked or patched. Releases pin upstream bitcoin-core/secp256k1, build a static-library XCFramework in GitHub Actions, publish the binary as a release asset, and record the SwiftPM checksum in Package.swift.

Platforms

  • iOS 16.0 and newer
  • macOS 13.0 and newer

The release artifact includes:

  • iOS device arm64
  • iOS simulator arm64 and x86_64
  • macOS arm64 and x86_64

Mac Catalyst and visionOS slices are not built. A Catalyst or visionOS target that links this package will fail at link time; file an issue if you need those slices added.

Install

Swift Package Manager consumes packages directly from Git repositories, so the GitHub URL is the package address. Add it to Package.swift:

.package(
    url: "https://github.com/reallyme/CSecp256k1",
    from: "0.1.0"
)

Add the product to your target:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "CSecp256k1", package: "CSecp256k1"),
    ]
)

Import the Clang module:

import CSecp256k1

Minimal smoke test:

import CSecp256k1

let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_NONE))
if let context {
    secp256k1_context_destroy(context)
}

What Is Included

The upstream library is pinned at bitcoin-core/secp256k1 v0.7.1.

Enabled modules (each pinned explicitly in the build script, so upstream default changes cannot alter the artifact):

  • ECDH
  • ECDSA public-key recovery
  • extrakeys
  • schnorrsig
  • MuSig2
  • ElligatorSwift

The binary artifact is produced from the pinned upstream source in vendor/secp256k1. The generated .xcframework and .zip are release artifacts only; they are intentionally not committed.

Verify a Release

Every release asset carries a build provenance attestation generated by the Release workflow. Verify that the zip you downloaded was built by CI from this repository:

gh attestation verify CSecp256k1.xcframework.zip --repo reallyme/CSecp256k1

SwiftPM independently enforces the checksum in Package.swift when it downloads the binary target, so a tampered asset fails resolution.

Each release also attaches a build-info.txt recording the runner image, Xcode version, upstream secp256k1 commit, and the workflow run that produced the artifact.

Build Locally

git submodule update --init --recursive
scripts/build_xcframework.sh

Outputs are written to out/:

  • CSecp256k1.xcframework
  • CSecp256k1.xcframework.zip
  • CSecp256k1.xcframework.checksum

The script finishes with a smoke test that compiles and runs a Swift program against the macOS slice through the Clang module.

Note that a locally built zip will not match the released checksum: the zip bytes depend on file timestamps and the exact toolchain, which is why releases are built only in CI (see below). Local builds are for development and verification of the build process, not for producing release assets.

Verify the slices:

lipo -info \
  out/CSecp256k1.xcframework/ios-arm64/libsecp256k1.a \
  out/CSecp256k1.xcframework/ios-arm64_x86_64-simulator/libsecp256k1.a \
  out/CSecp256k1.xcframework/macos-arm64_x86_64/libsecp256k1.a

Expected architectures:

ios-arm64: arm64
ios-arm64_x86_64-simulator: arm64 x86_64
macos-arm64_x86_64: arm64 x86_64

Release

Releases are cut by CI, never by hand. The Release workflow is the source of truth for the binary, its checksum, and the manifest that references it:

Before the first release, create a fine-grained GitHub token scoped only to reallyme/CSecp256k1 with Contents: Read and write, Actions: Read-only, and Metadata: Read-only, then store it as the repository secret CSECP256K1_RELEASE_TOKEN. The ReallyMe organization keeps the default GITHUB_TOKEN read-only, so the workflow uses this narrow token to commit the CI-generated checksum and create the release tag.

  1. Run the Release workflow (Actions → Release → Run workflow) with the version, for example 0.1.0. No v prefix.
  2. CI builds the XCFramework on a pinned runner image and pinned Xcode.
  3. CI computes the SwiftPM checksum of the zip it just built and patches the url and checksum in Package.swift.
  4. CI commits that manifest to main and creates the release tag on that commit, so the tag SwiftPM resolves always matches the asset it downloads.
  5. CI attests build provenance for the zip and publishes the GitHub Release with the zip, the checksum file, and build-info.txt.

Do not push release tags manually and do not edit the url or checksum in Package.swift by hand; the workflow refuses to overwrite an existing tag.

Do not commit the generated .xcframework or .zip. They belong in GitHub Releases.

Updating Upstream

The Upstream Watch workflow checks weekly whether bitcoin-core/secp256k1 has published a newer release tag than the pinned submodule. It only reports drift; it never updates the submodule and never cuts a package release.

Check the latest upstream release:

git -C vendor/secp256k1 fetch --tags origin
git -C vendor/secp256k1 tag --sort=-v:refname | head

Move to a new upstream release:

git -C vendor/secp256k1 checkout <tag>
git add vendor/secp256k1
scripts/build_xcframework.sh

Review upstream release notes, update the pinned ref recorded in NOTICE and this README, commit, then cut a release with the Release workflow.

License

ReallyMe package files, build scripts, and release automation are licensed under Apache-2.0.

Bitcoin Core libsecp256k1 is licensed under MIT. Its license text is included at vendor/secp256k1/COPYING.

Releases

Packages

Contributors

Languages