diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml
index dbca1ab4..93271ede 100644
--- a/.github/workflows/docker-image.yml
+++ b/.github/workflows/docker-image.yml
@@ -14,8 +14,12 @@ jobs:
with:
submodules: recursive
- name: Check symbolic links
- run: find . -type d -name .build -prune -o -type l ! -exec test -e {} \; -print | grep -q . && exit 1 || exit 0
+ run: |
+ broken_links=$(find . -type d -name .build -prune -o -type l ! -exec test -e {} \; -print)
+ if [ -n "$broken_links" ]; then
+ echo "Broken symbolic links found:"
+ echo "$broken_links"
+ exit 1
+ fi
- name: Build the Docker zkp image
- run: docker build .
- - name: Build the Docker secp256k1 image
- run: docker build -f Exhaustive/Package/Dockerfile .
+ run: docker build .
\ No newline at end of file
diff --git a/.github/workflows/xcframework-release.yml b/.github/workflows/xcframework-release.yml
new file mode 100644
index 00000000..97f5bcaf
--- /dev/null
+++ b/.github/workflows/xcframework-release.yml
@@ -0,0 +1,82 @@
+
+
+
+name: XCFramework Release
+on:
+ release:
+ types: [published]
+jobs:
+ macos:
+ name: Build XCFramework
+ runs-on: macos-15
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ - name: Generate Xcode project
+ run: swift package --disable-sandbox tuist generate -p Projects/ --no-open
+ - name: Archive & Create XCFramework
+ run: |
+ # Define workspace and scheme
+ WORKSPACE='Projects/XCFramework.xcworkspace'
+ SCHEME='P256K'
+ CONFIGURATION='Release'
+ ARCHIVE_DIR='Archives'
+
+ # Platforms to archive
+ PLATFORMS=(
+ "iOS"
+ "iOS Simulator"
+ "macOS"
+ "tvOS"
+ "tvOS Simulator"
+ "watchOS"
+ "watchOS Simulator"
+ "visionOS"
+ )
+
+ # Loop over platforms and archive for each one
+ for PLATFORM in "${PLATFORMS[@]}"; do
+ echo "Archiving for $PLATFORM..."
+
+ # Run xcodebuild archive for each platform
+ xcodebuild archive \
+ -workspace "$WORKSPACE" \
+ -scheme "$SCHEME" \
+ -configuration "$CONFIGURATION" \
+ -destination "generic/platform=$PLATFORM" \
+ -archivePath "$ARCHIVE_DIR/P256K-$PLATFORM.xcarchive"
+
+ # Check if archive command was successful
+ if [ $? -eq 0 ]; then
+ echo "$PLATFORM archive created successfully."
+ else
+ echo "Failed to archive for $PLATFORM. Exiting."
+ exit 1
+ fi
+ done
+
+ echo "All archives completed successfully."
+
+ # Create an XCFramework to support multiple platforms and architectures
+ # Each -archive parameter specifies a path to a .xcarchive built for a different platform
+ # -framework specifies the framework within those archives to include in the XCFramework
+ # The -output parameter specifies the name and location of the XCFramework to be created
+ xcodebuild -create-xcframework \
+ -archive "Archives/P256K-iOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-iOS Simulator.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-macOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-tvOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-tvOS Simulator.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-watchOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-watchOS Simulator.xcarchive" -framework P256K.framework \
+ -output P256K.xcframework
+ - name: 7z XCFramework
+ run: |
+ 7z a -tzip -mx=9 P256K.xcframework.zip P256K.xcframework
+ - name: Upload XCFramework
+ run: |
+ gh release upload ${{ github.ref_name }} P256K.xcframework.zip
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 9cfae45c..020fa4c2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,4 +8,4 @@ ADD . /LinuxTests
WORKDIR /LinuxTests
# Execute Linux test suite
-RUN swift test -v && swift build --target secp256k1
+RUN swift test
diff --git a/Exhaustive/Package/Dockerfile b/Exhaustive/Package/Dockerfile
deleted file mode 100644
index e39a7512..00000000
--- a/Exhaustive/Package/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Use an official Swift runtime image
-FROM swift:6.0.1
-
-# Copies the root directory of the repository into the image's filesystem at `/LinuxTests`
-ADD . /LinuxTests
-
-# Set the working directory to `/LinuxTests/Exhaustive/Package`
-WORKDIR /LinuxTests/Exhaustive/Package
-
-# Execute Linux test suite
-RUN swift test
diff --git a/Exhaustive/Package/Package.swift b/Exhaustive/Package/Package.swift
deleted file mode 100644
index 615eb384..00000000
--- a/Exhaustive/Package/Package.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-// swift-tools-version: 6.0
-
-import PackageDescription
-
-let package = Package(
- name: "Package",
- dependencies: [
- .package(name: "swift-secp256k1", path: "../..")
- ],
- targets: [
- .testTarget(
- name: "secp256k1Tests",
- dependencies: [
- .product(name: "secp256k1", package: "swift-secp256k1")
- ]
- )
- ]
-)
diff --git a/Exhaustive/Package/Tests/secp256k1Tests/XCTestManifests.swift b/Exhaustive/Package/Tests/secp256k1Tests/XCTestManifests.swift
deleted file mode 120000
index af3a06cd..00000000
--- a/Exhaustive/Package/Tests/secp256k1Tests/XCTestManifests.swift
+++ /dev/null
@@ -1 +0,0 @@
-../../../../Tests/zkpTests/XCTestManifests.swift
\ No newline at end of file
diff --git a/Exhaustive/Package/Tests/secp256k1Tests/secp256k1Tests.swift b/Exhaustive/Package/Tests/secp256k1Tests/secp256k1Tests.swift
deleted file mode 120000
index cda20c68..00000000
--- a/Exhaustive/Package/Tests/secp256k1Tests/secp256k1Tests.swift
+++ /dev/null
@@ -1 +0,0 @@
-../../../../Tests/zkpTests/secp256k1Tests.swift
\ No newline at end of file
diff --git a/Package.swift b/Package.swift
index cf1bc8c9..5986f2eb 100644
--- a/Package.swift
+++ b/Package.swift
@@ -6,24 +6,27 @@ let package = Package(
name: "swift-secp256k1",
products: [
// WARNING: These APIs should not be considered stable and may change at any time.
- .library(name: "secp256k1", targets: ["secp256k1"]),
- .library(name: "zkp", targets: ["zkp"])
+ .library(name: "libsecp256k1", targets: ["libsecp256k1"]),
+ .library(name: "libsecp256k1_zkp", targets: ["libsecp256k1_zkp"]),
+ .library(name: "P256K", targets: ["P256K"]),
+ .library(name: "ZKP", targets: ["ZKP"])
],
dependencies: [
// Dependencies used for package development
.package(url: "https://github.com/csjones/lefthook-plugin.git", exact: "1.11.2"),
+ .package(url: "https://github.com/21-DOT-DEV/swift-plugin-tuist.git", exact: "4.43.2"),
.package(url: "https://github.com/nicklockwood/SwiftFormat.git", exact: "0.55.5"),
.package(url: "https://github.com/realm/SwiftLint.git", exact: "0.58.2")
],
targets: [
- .target(name: "secp256k1", dependencies: ["secp256k1_bindings"]),
- .target(name: "zkp", dependencies: ["zkp_bindings"]),
+ .target(name: "P256K", dependencies: ["libsecp256k1"]),
+ .target(name: "ZKP", dependencies: ["libsecp256k1_zkp"]),
.target(
- name: "secp256k1_bindings",
+ name: "libsecp256k1",
cSettings: PackageDescription.CSetting.baseSettings
),
.target(
- name: "zkp_bindings",
+ name: "libsecp256k1_zkp",
cSettings: PackageDescription.CSetting.baseSettings + [
.define("ENABLE_MODULE_BPPP"),
.define("ENABLE_MODULE_ECDSA_ADAPTOR"),
@@ -38,7 +41,8 @@ let package = Package(
.headerSearchPath("../../Submodules/secp256k1-zkp/src")
]
),
- .testTarget(name: "zkpTests", dependencies: ["zkp"])
+ .testTarget(name: "libsecp256k1zkpTests", dependencies: ["ZKP", "libsecp256k1_zkp"]),
+ .testTarget(name: "ZKPTests", dependencies: ["ZKP"])
],
swiftLanguageModes: [.v5],
cLanguageStandard: .c89
diff --git a/Projects/.gitignore b/Projects/.gitignore
new file mode 100644
index 00000000..24b244f9
--- /dev/null
+++ b/Projects/.gitignore
@@ -0,0 +1,70 @@
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Xcode ###
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+### Xcode Patch ###
+*.xcodeproj/*
+!*.xcodeproj/project.pbxproj
+!*.xcodeproj/xcshareddata/
+!*.xcworkspace/contents.xcworkspacedata
+/*.gcno
+
+### Projects ###
+*.xcodeproj
+*.xcworkspace
+
+### Tuist derived files ###
+graph.dot
+Derived/
+
+### Tuist managed dependencies ###
+Tuist/.build
\ No newline at end of file
diff --git a/Projects/Project.swift b/Projects/Project.swift
new file mode 100644
index 00000000..399f4361
--- /dev/null
+++ b/Projects/Project.swift
@@ -0,0 +1,101 @@
+import ProjectDescription
+
+let deploymentTargets = ProjectDescription.DeploymentTargets.multiplatform(
+ iOS: "18.0",
+ macOS: "15.0",
+ watchOS: "11.0",
+ tvOS: "18.0",
+ visionOS: "2.0"
+)
+
+let project = Project(
+ name: "XCFramework",
+ packages: [
+ .package(path: "..")
+ ],
+ settings: .settings(
+ configurations: [
+ .debug(name: "Debug", xcconfig: "Resources/Project/Debug.xcconfig"),
+ .debug(name: "Release", xcconfig: "Resources/Project/Release.xcconfig")
+ ]
+ ),
+ targets: [
+ .target(
+ name: "P256K",
+ destinations: [.iPhone, .iPad, .mac, .appleWatch, .appleTv, .appleVision],
+ product: .staticFramework,
+ bundleId: "dev.21.P256K",
+ deploymentTargets: deploymentTargets,
+ sources: ["Sources/P256K/**"],
+ resources: [],
+ dependencies: [
+ .package(product: "libsecp256k1")
+ ],
+ settings: .settings(
+ base: [
+ "BUILD_LIBRARY_FOR_DISTRIBUTION": "YES",
+ "MACOSX_DEPLOYMENT_TARGET": "13.0"
+ ],
+ configurations: [
+ .debug(name: "Debug", xcconfig: "Resources/P256K/Debug.xcconfig"),
+ .release(name: "Release", xcconfig: "Resources/P256K/Release.xcconfig")
+ ],
+ defaultSettings: .recommended(
+ excluding: ["SKIP_INSTALL"]
+ )
+ )
+ ),
+ .target(
+ name: "P256KTests",
+ destinations: [.iPhone, .iPad, .mac, .appleWatch, .appleTv, .appleVision],
+ product: .unitTests,
+ bundleId: "dev.21.P256KTests",
+ deploymentTargets: deploymentTargets,
+ sources: ["Sources/P256KTests/**"],
+ dependencies: [.target(name: "P256K")],
+ settings: .settings(
+ configurations: [
+ .debug(name: "Debug", xcconfig: "Resources/P256KTests/Debug.xcconfig"),
+ .release(name: "Release", xcconfig: "Resources/P256KTests/Release.xcconfig")
+ ]
+ )
+ ),
+ .target(
+ name: "libsecp256k1Tests",
+ destinations: [.iPhone, .iPad, .mac, .appleWatch, .appleTv, .appleVision],
+ product: .unitTests,
+ bundleId: "dev.21.libsecp256k1Tests",
+ deploymentTargets: deploymentTargets,
+ sources: ["Sources/libsecp256k1Tests/**"],
+ dependencies: [.package(product: "libsecp256k1")],
+ settings: .settings(
+ configurations: [
+ .debug(name: "Debug", xcconfig: "Resources/libsecp256k1Tests/Debug.xcconfig"),
+ .release(name: "Release", xcconfig: "Resources/libsecp256k1Tests/Release.xcconfig")
+ ]
+ )
+ ),
+ .target(
+ name: "XCFrameworkApp",
+ destinations: [.iPhone, .iPad, .mac, .appleTv, .appleVision],
+ product: .app,
+ bundleId: "dev.21.XCFrameworkApp",
+ sources: ["Sources/XCFrameworkApp/**"],
+ resources: [
+ "Resources/XCFrameworkApp/Assets.xcassets/**",
+ "Resources/XCFrameworkApp/Preview Content/**"
+ ],
+ entitlements: "Resources/XCFrameworkApp/XCFrameworkApp.entitlements",
+ dependencies: [
+ .target(name: "P256K")
+ ],
+ settings: .settings(
+ base: ["ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME": ""],
+ configurations: [
+ .debug(name: "Debug", xcconfig: "Resources/XCFrameworkApp/Debug.xcconfig"),
+ .release(name: "Release", xcconfig: "Resources/XCFrameworkApp/Release.xcconfig")
+ ]
+ )
+ )
+ ]
+)
diff --git a/Exhaustive/Package/README.md b/Projects/README.md
similarity index 100%
rename from Exhaustive/Package/README.md
rename to Projects/README.md
diff --git a/Projects/Resources/P256K/Debug.xcconfig b/Projects/Resources/P256K/Debug.xcconfig
new file mode 100644
index 00000000..c83c5a41
--- /dev/null
+++ b/Projects/Resources/P256K/Debug.xcconfig
@@ -0,0 +1,80 @@
+//
+// Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+#include "Shared.xcconfig"
+
+
+//********************************************//
+//* Architectures *//
+//********************************************//
+
+
+// Build Active Architecture Only
+//
+// If enabled, only the active architecture is built. This setting will be ignored when
+// building with a run destination which does not define a specific architecture, such as
+// a 'Generic Device' run destination.
+
+ONLY_ACTIVE_ARCH = YES
+
+
+//********************************************//
+//* Build Options *//
+//********************************************//
+
+
+// Debug Information Format
+//
+// The type of debug information to produce.
+//
+// * DWARF: Object files and linked products will use DWARF as the debug information
+// format. [dwarf]
+// * DWARF with dSYM File: Object files and linked products will use DWARF as the debug
+// information format, and Xcode will also produce a dSYM file containing the debug
+// information from the individual object files (except that a dSYM file is not needed
+// and will not be created for static library or object file products). [dwarf-with-dsym]
+
+DEBUG_INFORMATION_FORMAT = dwarf
+
+
+// Enable Testability
+//
+// Enabling this setting will build the target with options appropriate for running
+// automated tests against its product.
+//
+// This setting can be enabled when building targets for debugging if their products will
+// be tested. This may result in tests running slower than otherwise.
+//
+// When this setting is enabled:
+//
+// * `GCC_SYMBOLS_PRIVATE_EXTERN` is disabled (`-fvisibility=hidden` will not be passed
+// to `clang`).
+// * `-enable-testing` is passed to the Swift compiler.
+// * `-export_dynamic` is passed to the linker.
+// * `STRIP_INSTALLED_PRODUCT` is disabled (`strip` will not be run on the produced
+// binary).
+
+ENABLE_TESTABILITY = YES
+
+
+// Validate Built Product
+//
+// If enabled, perform validation checks on the product as part of the build process.
+
+VALIDATE_PRODUCT = NO
+
+//********************************************//
+//* Deployment *//
+//********************************************//
+
+
+// Skip Install
+//
+// If enabled, don't install built products even if deployment locations are active.
+
+SKIP_INSTALL = YES
\ No newline at end of file
diff --git a/Projects/Resources/P256K/Release.xcconfig b/Projects/Resources/P256K/Release.xcconfig
new file mode 100644
index 00000000..29dafa9a
--- /dev/null
+++ b/Projects/Resources/P256K/Release.xcconfig
@@ -0,0 +1,145 @@
+//
+// Release.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+#include "Shared.xcconfig"
+
+
+//********************************************//
+//* Architectures *//
+//********************************************//
+
+
+// Build Active Architecture Only
+//
+// If enabled, only the active architecture is built. This setting will be ignored when
+// building with a run destination which does not define a specific architecture, such as
+// a 'Generic Device' run destination.
+
+ONLY_ACTIVE_ARCH = NO
+
+
+//********************************************//
+//* Build Options *//
+//********************************************//
+
+
+// Debug Information Format
+//
+// The type of debug information to produce.
+//
+// * DWARF: Object files and linked products will use DWARF as the debug information
+// format. [dwarf]
+// * DWARF with dSYM File: Object files and linked products will use DWARF as the debug
+// information format, and Xcode will also produce a dSYM file containing the debug
+// information from the individual object files (except that a dSYM file is not needed
+// and will not be created for static library or object file products). [dwarf-with-dsym]
+
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
+
+
+// Enable Testability
+//
+// Enabling this setting will build the target with options appropriate for running
+// automated tests against its product.
+//
+// This setting can be enabled when building targets for debugging if their products will
+// be tested. This may result in tests running slower than otherwise.
+//
+// When this setting is enabled:
+//
+// * `GCC_SYMBOLS_PRIVATE_EXTERN` is disabled (`-fvisibility=hidden` will not be passed
+// to `clang`).
+// * `-enable-testing` is passed to the Swift compiler.
+// * `-export_dynamic` is passed to the linker.
+// * `STRIP_INSTALLED_PRODUCT` is disabled (`strip` will not be run on the produced
+// binary).
+
+ENABLE_TESTABILITY = NO
+
+
+// Validate Built Product
+//
+// If enabled, perform validation checks on the product as part of the build process.
+
+VALIDATE_PRODUCT = YES
+
+
+//********************************************//
+//* Deployment *//
+//********************************************//
+
+
+// Skip Install
+//
+// If enabled, don't install built products even if deployment locations are active.
+
+SKIP_INSTALL = NO
+
+
+//********************************************//
+//* Apple Clang - Code Generation *//
+//********************************************//
+
+
+// Optimization Level
+//
+// Specifies the degree to which the generated code is optimized for speed and binary
+// size.
+//
+// * None: Do not optimize. [-O0]
+// With this setting, the compiler's goal is to reduce the cost of compilation and to
+// make debugging produce the expected results. Statements are independent—if you stop
+// the program with a breakpoint between statements, you can then assign a new value to
+// any variable or change the program counter to any other statement in the function and
+// get exactly the results you would expect from the source code.
+// * Fast: Optimizing compilation takes somewhat more time, and a lot more memory for a
+// large function. [-O1]
+// With this setting, the compiler tries to reduce code size and execution time,
+// without performing any optimizations that take a great deal of compilation time. In
+// Apple's compiler, strict aliasing, block reordering, and inter-block scheduling are
+// disabled by default when optimizing.
+// * Faster: The compiler performs nearly all supported optimizations that do not
+// involve a space-speed tradeoff. [-O2]
+// With this setting, the compiler does not perform loop unrolling or function
+// inlining, or register renaming. As compared to the `Fast` setting, this setting
+// increases both compilation time and the performance of the generated code.
+// * Fastest: Turns on all optimizations specified by the `Faster` setting and also
+// turns on function inlining and register renaming options. This setting may result in a
+// larger binary. [-O3]
+// * Fastest, Smallest: Optimize for size. This setting enables all `Faster`
+// optimizations that do not typically increase code size. It also performs further
+// optimizations designed to reduce code size. [-Os]
+// * Fastest, Aggressive Optimizations: This setting enables `Fastest` but also enables
+// aggressive optimizations that may break strict standards compliance but should work
+// well on well-behaved code. [-Ofast]
+// * Smallest, Aggressive Size Optimizations: This setting enables additional size
+// savings by isolating repetitive code patterns into a compiler generated function.
+// [-Oz]
+
+GCC_OPTIMIZATION_LEVEL = s
+
+
+//********************************************//
+//* Apple Clang - Preprocessing *//
+//********************************************//
+
+
+// Enable Foundation Assertions
+//
+// Controls whether assertion logic provided by `NSAssert` is included in the
+// preprocessed source code or is elided during preprocessing. Disabling assertions can
+// improve code performance.
+
+ENABLE_NS_ASSERTIONS = NO
+
+
+// Preprocessor Macros
+//
+// Space-separated list of preprocessor macros of the form foo or foo=bar.
+
+GCC_PREPROCESSOR_DEFINITIONS =
diff --git a/Projects/Resources/P256K/Shared.xcconfig b/Projects/Resources/P256K/Shared.xcconfig
new file mode 100644
index 00000000..d0cf46a1
--- /dev/null
+++ b/Projects/Resources/P256K/Shared.xcconfig
@@ -0,0 +1,259 @@
+//
+// Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+//********************************************//
+//* Build Options *//
+//********************************************//
+
+
+// Allow Multi-Platform Builds
+//
+// If enabled, allows targets to build multiple times within a single build operation.
+// Targets will build for the platform of the active run destination, as well as the
+// platforms of any targets which depend on them.
+
+ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES
+
+
+// User Script Sandboxing
+//
+// If enabled, the build system will sandbox user scripts to disallow undeclared
+// input/output dependencies.
+
+ENABLE_USER_SCRIPT_SANDBOXING = YES
+
+
+//********************************************//
+//* Deployment *//
+//********************************************//
+
+
+// Targeted Device Families
+//
+// Comma-separated list of integers corresponding to device families supported by this
+// target.
+//
+// The build system uses this information to set the correct value for the
+// `UIDeviceFamily` key it adds to the target's `Info.plist` file. Values inapplicable to
+// the current platform will be removed automatically. This also drives the
+// `--target-device` flag to actool, which determines the idioms selected during catalog
+// compilation.
+//
+// Possible values include:
+// * *1*: iPhone, iPod touch
+// * *2*: iPad, Mac Catalyst using "Scaled to Match iPad" Interface
+// * *3*: Apple TV
+// * *4*: Apple Watch
+// * *6*: Mac Catalyst using "Optimize for Mac" Interface
+// * *7*: Apple Vision
+
+TARGETED_DEVICE_FAMILY = 1,2,3,4,5,6,7
+
+
+//********************************************//
+//* Linking General *//
+//********************************************//
+
+
+// Compatibility Version
+//
+// Determines the compatibility version of the resulting library, bundle, or framework
+// binary. See [Dynamic Library Design
+// Guidelines](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW19)
+// in [Dynamic Library Programming
+// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html)
+// for details on assigning version numbers of dynamic libraries.
+
+DYLIB_COMPATIBILITY_VERSION = 1
+
+
+// Current Library Version
+//
+// This setting defines the current version of any framework built by the project. As
+// with `CURRENT_PROJECT_VERSION`, the value must be an integer or floating point number,
+// such as `57` or `365.8`. See [Dynamic Library Design
+// Guidelines](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW19)
+// in [Dynamic Library Programming
+// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html)
+// for details on assigning version numbers of dynamic libraries.
+
+DYLIB_CURRENT_VERSION = 1
+
+
+// Dynamic Library Install Name
+//
+// Sets the value for the internal `install path` (`LC_ID_DYLIB`) in a dynamic
+// library. This will be combined with the `EXECUTABLE_PATH` to form the full install
+// path. Setting this directly will override any other settings that affect it.
+// This setting defaults to the target's `INSTALL_PATH`. It is ignored when building
+// any product other than a dynamic library.
+
+LD_DYLIB_INSTALL_NAME = $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)
+
+
+// Dynamic Library Install Name Base
+//
+// Sets the base value for the internal `install path` (`LC_ID_DYLIB`) in a dynamic
+// library. This will be combined with the `EXECUTABLE_PATH` to form the full install
+// path. Setting `LD_DYLIB_INSTALL_NAME` directly will override this setting. This
+// setting defaults to the target's `INSTALL_PATH`. It is ignored when building any
+// product other than a dynamic library.
+
+DYLIB_INSTALL_NAME_BASE = @rpath
+
+
+// Generate Position-Independent Executable (PIE)
+//
+// When enabled, the linker produces a position-independent executable (PIE).
+// PIE executables have address space layout randomization (ASLR) enabled, which
+// enhances security by randomizing the memory addresses used by the program,
+// making it more difficult for attackers to predict the location of specific
+// functions within the code. Setting this to `NO` means the resulting executable
+// will not be position-independent.
+
+LD_NO_PIE = NO
+
+
+//********************************************//
+//* Packaging *//
+//********************************************//
+
+
+// Defines Module
+//
+// If enabled, the product will be treated as defining its own module. This enables
+// automatic production of LLVM module map files when appropriate, and allows the product
+// to be imported as a module.
+
+DEFINES_MODULE = YES
+
+
+// Product Name
+//
+// This is the basename of the product generated by the target.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleName](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
+
+
+// Strings File Output Encoding
+//
+// Specify the output encoding to be used for Strings files - the
+// default is UTF-16. The value can be either an NSStringEncoding,
+// such as one of the numeric values recognized by NSString, or an
+// IANA character set name as understood by CFString. It is
+// recommended that the source file be in UTF-8 encoding, which is
+// the default encoding for standard strings files, and Xcode will
+// automatically process it to the output encoding. Processing
+// will fail if the file cannot be converted to the specified encoding.
+
+STRINGS_FILE_OUTPUT_ENCODING = binary
+
+
+//********************************************//
+//* Versioning *//
+//********************************************//
+
+
+// Current Project Version
+//
+// This setting defines the current version of the project. The value must be a integer
+// or floating point number, such as `57` or `365.8`.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion)
+// key in the `Info.plist` file to the value of this build setting.
+
+CURRENT_PROJECT_VERSION = 1
+
+
+// Marketing Version
+//
+// This setting defines the user-visible version of the project.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring)
+// key in the `Info.plist` file to the value of this build setting.
+
+MARKETING_VERSION = 1.0
+
+
+// Versioning System
+//
+// Selects the process used for version-stamping generated files.
+//
+// * None: Use no versioning system.
+// * Apple Generic: Use the current project version setting. [apple-generic]
+// * Apple Generic (Hidden Symbols): Use the current project version setting with
+// hidden-visibility symbols. [apple-generic-hidden]
+
+VERSIONING_SYSTEM = apple-generic
+
+
+//********************************************//
+//* Apple Clang Module Verifier - Options *//
+//********************************************//
+
+
+// Enable Module Verifier
+//
+// If enabled, the build system will use the Apple Clang Module Verifier to perform
+// additional checks on module imports and usage. This can help identify issues with
+// module boundaries and conform to supported language standards.
+
+ENABLE_MODULE_VERIFIER = YES
+
+
+// Module Verifier Supported Language Standards
+//
+// Specifies which C and C++ language standards the module verifier will recognize
+// and work with. Compatibility with these standards must be maintained for module
+// verification to succeed.
+
+MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = gnu99 gnu++20
+
+
+// Module Verifier Supported Languages
+//
+// Lists the programming languages for which the module verifier can perform its
+// checks. Only these languages will be subject to verification.
+
+MODULE_VERIFIER_SUPPORTED_LANGUAGES = objective-c objective-c++
+
+
+//********************************************//
+//* Swift Compiler - General *//
+//********************************************//
+
+
+// Install Generated Header
+//
+// For frameworks, install the C++/Objective-C generated header describing bridged
+// Swift types into the PUBLIC_HEADERS_FOLDER_PATH so they may be accessed from
+// Objective-C or C++ code using the framework. Defaults to YES.
+
+SWIFT_INSTALL_OBJC_HEADER = YES
+
+
+//********************************************//
+//* Static Analysis - Issues - Security *//
+//********************************************//
+
+
+// Warn on Insecure rand() API Usage
+//
+// If enabled, the Clang Static Analyzer will provide warnings for uses of the
+// insecure `rand()` function from the C standard library. This is part of security
+// checks to encourage the usage of more secure alternatives such as `arc4random()`
+// or `random()`, which offer better randomness properties suitable for cryptographic
+// use cases.
+
+CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES
diff --git a/Projects/Resources/P256KTests/Debug.xcconfig b/Projects/Resources/P256KTests/Debug.xcconfig
new file mode 100644
index 00000000..9011fb1d
--- /dev/null
+++ b/Projects/Resources/P256KTests/Debug.xcconfig
@@ -0,0 +1,12 @@
+//
+// Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/P256KTests/Release.xcconfig b/Projects/Resources/P256KTests/Release.xcconfig
new file mode 100644
index 00000000..c327866e
--- /dev/null
+++ b/Projects/Resources/P256KTests/Release.xcconfig
@@ -0,0 +1,12 @@
+//
+// Release.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/P256KTests/Shared.xcconfig b/Projects/Resources/P256KTests/Shared.xcconfig
new file mode 100644
index 00000000..104c27ce
--- /dev/null
+++ b/Projects/Resources/P256KTests/Shared.xcconfig
@@ -0,0 +1,116 @@
+//
+// Shared.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+// Code Signing Style
+//
+// This setting specifies the method used to acquire and locate signing assets. Choose
+// `Automatic` to let Xcode automatically create and update profiles, app IDs, and
+// certificates. Choose `Manual` to create and update these yourself on the developer
+// website.
+
+CODE_SIGN_STYLE = Automatic
+
+
+
+// Current Project Version
+//
+// This setting defines the current version of the project. The value must be a integer
+// or floating point number, such as `57` or `365.8`.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion)
+// key in the `Info.plist` file to the value of this build setting.
+
+CURRENT_PROJECT_VERSION = 1
+
+
+
+// Generate Info.plist File
+//
+// If enabled, automatically generate an Info.plist file with content from build
+// settings, and from content in the file pointed to by `INFOPLIST_FILE`, if defined.
+
+GENERATE_INFOPLIST_FILE = YES
+
+
+
+// Marketing Version
+//
+// This setting defines the user-visible version of the project.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring)
+// key in the `Info.plist` file to the value of this build setting.
+
+MARKETING_VERSION = 1.0
+
+
+
+// Product Bundle Identifier
+//
+// A string that uniquely identifies the bundle. The string should be in reverse DNS
+// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and
+// the hyphen (`-`).
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleIdentifier](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_BUNDLE_IDENTIFIER = dev.21.P256KTests
+
+
+
+// Product Name
+//
+// This is the basename of the product generated by the target.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleName](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_NAME = $(TARGET_NAME)
+
+
+
+// Use Compiler to Extract Swift Strings
+//
+// When enabled, the Swift compiler will be used to extract Swift string literal and
+// interpolation `LocalizedStringKey` and `LocalizationKey` types during localization
+// export.
+
+SWIFT_EMIT_LOC_STRINGS = NO
+
+
+
+// Swift Language Version
+//
+// The language version used to compile the target's Swift code.
+
+SWIFT_VERSION = 5.0
+
+
+
+// Targeted Device Families
+//
+// Comma-separated list of integers corresponding to device families supported by this
+// target.
+//
+// The build system uses this information to set the correct value for the
+// `UIDeviceFamily` key it adds to the target's `Info.plist` file. Values inapplicable to
+// the current platform will be removed automatically. This also drives the
+// `--target-device` flag to actool, which determines the idioms selected during catalog
+// compilation.
+//
+// Possible values include:
+// * *1*: iPhone, iPod touch
+// * *2*: iPad, Mac Catalyst using "Scaled to Match iPad" Interface
+// * *3*: Apple TV
+// * *4*: Apple Watch
+// * *6*: Mac Catalyst using "Optimize for Mac" Interface
+// * *7*: Apple Vision
+
+TARGETED_DEVICE_FAMILY = 1,2
diff --git a/Projects/Resources/Project/Debug.xcconfig b/Projects/Resources/Project/Debug.xcconfig
new file mode 100644
index 00000000..1370ded5
--- /dev/null
+++ b/Projects/Resources/Project/Debug.xcconfig
@@ -0,0 +1,24 @@
+//
+// Project-Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+#include "Shared.xcconfig"
+
+
+//********************************************//
+//* Swift Compiler - Code Generation *//
+//********************************************//
+
+
+// Swift Optimization Level
+//
+// * None: Compile without any optimization. [-Onone]
+// * Optimize for Speed: [-O]
+// * Optimize for Size: [-Osize]
+// * Whole Module Optimization: [-O -whole-module-optimization]
+
+SWIFT_OPTIMIZATION_LEVEL = -Onone
\ No newline at end of file
diff --git a/Projects/Resources/Project/Release.xcconfig b/Projects/Resources/Project/Release.xcconfig
new file mode 100644
index 00000000..4dc92ea1
--- /dev/null
+++ b/Projects/Resources/Project/Release.xcconfig
@@ -0,0 +1,36 @@
+//
+// Project-Release.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+#include "Shared.xcconfig"
+
+
+//********************************************//
+//* Swift Compiler - Code Generation *//
+//********************************************//
+
+
+// Swift Compilation Mode
+//
+// This setting controls the way the Swift files in a module are rebuilt.
+//
+// * Incremental: Only rebuild the Swift source files in the module that are out of
+// date, running multiple compiler processes as needed.
+// * Whole Module: Always rebuild all Swift source files in the module, in a single
+// compiler process.
+
+SWIFT_COMPILATION_MODE = wholemodule
+
+
+// Swift Optimization Level
+//
+// * None: Compile without any optimization. [-Onone]
+// * Optimize for Speed: [-O]
+// * Optimize for Size: [-Osize]
+// * Whole Module Optimization: [-O -whole-module-optimization]
+
+SWIFT_OPTIMIZATION_LEVEL = -O -whole-module-optimization
\ No newline at end of file
diff --git a/Projects/Resources/Project/Shared.xcconfig b/Projects/Resources/Project/Shared.xcconfig
new file mode 100644
index 00000000..82d7108e
--- /dev/null
+++ b/Projects/Resources/Project/Shared.xcconfig
@@ -0,0 +1,53 @@
+//
+// Shared.xcconfig
+//
+// Generated by BuildSettingExtractor on 1/22/25
+// https://buildsettingextractor.com
+//
+
+
+//********************************************//
+//* Localization *//
+//********************************************//
+
+
+// Localization Prefers String Catalogs
+//
+// When enabled, string tables generated in a localization export will prefer the String
+// Catalog format.
+
+LOCALIZATION_PREFERS_STRING_CATALOGS = YES
+
+
+// Use Compiler to Extract Swift Strings
+//
+// When enabled, the Swift compiler will be used to extract Swift string literal and
+// interpolation `LocalizedStringKey` and `LocalizationKey` types during localization
+// export.
+
+SWIFT_EMIT_LOC_STRINGS = NO
+
+
+//********************************************//
+//* Packaging *//
+//********************************************//
+
+
+// Generate Info.plist File
+//
+// If enabled, automatically generate an Info.plist file with content from build
+// settings, and from content in the file pointed to by `INFOPLIST_FILE`, if defined.
+
+GENERATE_INFOPLIST_FILE = YES
+
+
+//********************************************//
+//* Swift Compiler - Language *//
+//********************************************//
+
+
+// Swift Language Version
+//
+// The language version used to compile the target's Swift code.
+
+SWIFT_VERSION = 5.0
\ No newline at end of file
diff --git a/Projects/Resources/XCFrameworkApp/Assets.xcassets/AccentColor.colorset/Contents.json b/Projects/Resources/XCFrameworkApp/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Projects/Resources/XCFrameworkApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/Projects/Resources/XCFrameworkApp/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..ffdfe150
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,85 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "tinted"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "512x512"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "512x512"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Projects/Resources/XCFrameworkApp/Assets.xcassets/Contents.json b/Projects/Resources/XCFrameworkApp/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Projects/Resources/XCFrameworkApp/Debug.xcconfig b/Projects/Resources/XCFrameworkApp/Debug.xcconfig
new file mode 100644
index 00000000..9011fb1d
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Debug.xcconfig
@@ -0,0 +1,12 @@
+//
+// Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/XCFrameworkApp/Preview Content/Preview Assets.xcassets/Contents.json b/Projects/Resources/XCFrameworkApp/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Projects/Resources/XCFrameworkApp/Release.xcconfig b/Projects/Resources/XCFrameworkApp/Release.xcconfig
new file mode 100644
index 00000000..c327866e
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Release.xcconfig
@@ -0,0 +1,12 @@
+//
+// Release.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/XCFrameworkApp/Shared.xcconfig b/Projects/Resources/XCFrameworkApp/Shared.xcconfig
new file mode 100644
index 00000000..dadc6a00
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/Shared.xcconfig
@@ -0,0 +1,276 @@
+//
+// Shared.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+// Primary App Icon Set Name
+//
+// Name of an app icon set for the target's default app icon. The contents will be merged
+// into the `Info.plist`.
+
+ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
+
+
+
+// Global Accent Color Name
+//
+// The name of a color resource to use as a the target's accent color, used as the
+// default tint color on iOS and watchOS, and accent color on macOS.
+
+ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor
+
+
+
+// Code Signing Entitlements
+//
+// The path to a file specifying code-signing entitlements.
+
+CODE_SIGN_ENTITLEMENTS = Resources/XCFrameworkApp/XCFrameworkApp.entitlements
+
+
+
+// Code Signing Style
+//
+// This setting specifies the method used to acquire and locate signing assets. Choose
+// `Automatic` to let Xcode automatically create and update profiles, app IDs, and
+// certificates. Choose `Manual` to create and update these yourself on the developer
+// website.
+
+CODE_SIGN_STYLE = Automatic
+
+
+
+// Current Project Version
+//
+// This setting defines the current version of the project. The value must be a integer
+// or floating point number, such as `57` or `365.8`.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion)
+// key in the `Info.plist` file to the value of this build setting.
+
+CURRENT_PROJECT_VERSION = 1
+
+
+
+// Development Assets
+//
+// Files and directories used only for development. Archive and install builds will
+// exclude this content.
+
+DEVELOPMENT_ASSET_PATHS = "Resources/XCFrameworkApp/Preview Content"
+
+
+
+ENABLE_PREVIEWS = YES
+
+
+
+// Generate Info.plist File
+//
+// If enabled, automatically generate an Info.plist file with content from build
+// settings, and from content in the file pointed to by `INFOPLIST_FILE`, if defined.
+
+GENERATE_INFOPLIST_FILE = YES
+
+
+
+// Application Scene Manifest (Generation)
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UIApplicationSceneManifest](https://developer.apple.com/documentation/bundleresources/information_property_list/uiapplicationscenemanifest)
+// key in the Info.plist file to an entry suitable for a multi-window application.
+
+INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*] = YES
+INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*] = YES
+
+
+
+// Supports Indirect Events
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UIApplicationSupportsIndirectInputEvents](https://developer.apple.com/documentation/bundleresources/information_property_list/uiapplicationsupportsindirectinputevents)
+// key in the `Info.plist` file to the value of this build setting.
+
+INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*] = YES
+INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*] = YES
+
+
+
+// Launch Screen (Generation)
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UILaunchScreen](https://developer.apple.com/documentation/bundleresources/information_property_list/uilaunchscreen)
+// key in the Info.plist file to an empty dictionary.
+
+INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*] = YES
+INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*] = YES
+
+
+
+// Status Bar Style
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UIStatusBarStyle](https://developer.apple.com/documentation/bundleresources/information_property_list/uistatusbarstyle)
+// key in the `Info.plist` file to the value of this build setting.
+
+INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*] = UIStatusBarStyleDefault
+INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*] = UIStatusBarStyleDefault
+
+
+
+// Supported Interface Orientations (iPad)
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UISupportedInterfaceOrientations~iPad](https://developer.apple.com/documentation/bundleresources/information_property_list/uisupportedinterfaceorientations)
+// key in the `Info.plist` file to the value of this build setting.
+
+INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
+
+
+
+// Supported Interface Orientations (iPhone)
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [UISupportedInterfaceOrientations~iPhone](https://developer.apple.com/documentation/bundleresources/information_property_list/uisupportedinterfaceorientations)
+// key in the `Info.plist` file to the value of this build setting.
+
+INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
+
+
+
+// iOS Deployment Target
+//
+// Code will load on this and later versions of iOS. Framework APIs that are unavailable
+// in earlier versions will be weak-linked; your code should check for null function
+// pointers or specific system versions before calling newer APIs.
+
+IPHONEOS_DEPLOYMENT_TARGET = 18.2
+
+
+
+// Runpath Search Paths
+//
+// This is a list of paths to be added to the `runpath` search path list for the image
+// being created. At runtime, `dyld` uses the `runpath` when searching for dylibs whose
+// load path begins with `@rpath/`. See [Dynamic Library Programming
+// Topics](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html).
+
+LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks
+LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = @executable_path/../Frameworks
+
+
+
+// macOS Deployment Target
+//
+// Code will load on this and later versions of macOS. Framework APIs that are
+// unavailable in earlier versions will be weak-linked; your code should check for `null`
+// function pointers or specific system versions before calling newer APIs.
+
+MACOSX_DEPLOYMENT_TARGET = 15.2
+
+
+
+// Marketing Version
+//
+// This setting defines the user-visible version of the project.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring)
+// key in the `Info.plist` file to the value of this build setting.
+
+MARKETING_VERSION = 1.0
+
+
+
+// Product Bundle Identifier
+//
+// A string that uniquely identifies the bundle. The string should be in reverse DNS
+// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and
+// the hyphen (`-`).
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleIdentifier](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_BUNDLE_IDENTIFIER = dev.21.XCFrameworkApp
+
+
+
+// Product Name
+//
+// This is the basename of the product generated by the target.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleName](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_NAME = $(TARGET_NAME)
+
+
+
+// Base SDK
+//
+// The name or path of the base SDK being used during the build. The product will be
+// built against the headers and libraries located inside the indicated SDK. This path
+// will be prepended to all search paths, and will be passed through the environment to
+// the compiler and linker. Additional SDKs can be specified in the `ADDITIONAL_SDKS`
+// setting.
+
+SDKROOT = auto
+
+
+
+// Supported Platforms
+//
+// The list of supported platforms from which a base SDK can be used. This setting is
+// used if the product can be built for multiple platforms using different SDKs.
+
+SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx xros xrsimulator
+
+
+
+// Use Compiler to Extract Swift Strings
+//
+// When enabled, the Swift compiler will be used to extract Swift string literal and
+// interpolation `LocalizedStringKey` and `LocalizationKey` types during localization
+// export.
+
+SWIFT_EMIT_LOC_STRINGS = YES
+
+
+
+// Swift Language Version
+//
+// The language version used to compile the target's Swift code.
+
+SWIFT_VERSION = 5.0
+
+
+
+// Targeted Device Families
+//
+// Comma-separated list of integers corresponding to device families supported by this
+// target.
+//
+// The build system uses this information to set the correct value for the
+// `UIDeviceFamily` key it adds to the target's `Info.plist` file. Values inapplicable to
+// the current platform will be removed automatically. This also drives the
+// `--target-device` flag to actool, which determines the idioms selected during catalog
+// compilation.
+//
+// Possible values include:
+// * *1*: iPhone, iPod touch
+// * *2*: iPad, Mac Catalyst using "Scaled to Match iPad" Interface
+// * *3*: Apple TV
+// * *4*: Apple Watch
+// * *6*: Mac Catalyst using "Optimize for Mac" Interface
+// * *7*: Apple Vision
+
+TARGETED_DEVICE_FAMILY = 1,2,3,6,7
+
+
+
+XROS_DEPLOYMENT_TARGET = 2.2
diff --git a/Projects/Resources/XCFrameworkApp/XCFrameworkApp.entitlements b/Projects/Resources/XCFrameworkApp/XCFrameworkApp.entitlements
new file mode 100644
index 00000000..f2ef3ae0
--- /dev/null
+++ b/Projects/Resources/XCFrameworkApp/XCFrameworkApp.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/Projects/Resources/libsecp256k1Tests/Debug.xcconfig b/Projects/Resources/libsecp256k1Tests/Debug.xcconfig
new file mode 100644
index 00000000..9011fb1d
--- /dev/null
+++ b/Projects/Resources/libsecp256k1Tests/Debug.xcconfig
@@ -0,0 +1,12 @@
+//
+// Debug.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/libsecp256k1Tests/Release.xcconfig b/Projects/Resources/libsecp256k1Tests/Release.xcconfig
new file mode 100644
index 00000000..c327866e
--- /dev/null
+++ b/Projects/Resources/libsecp256k1Tests/Release.xcconfig
@@ -0,0 +1,12 @@
+//
+// Release.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+#include "Shared.xcconfig"
+
+//********************************************//
+//* Currently no build settings in this file *//
+//********************************************//
diff --git a/Projects/Resources/libsecp256k1Tests/Shared.xcconfig b/Projects/Resources/libsecp256k1Tests/Shared.xcconfig
new file mode 100644
index 00000000..008091f9
--- /dev/null
+++ b/Projects/Resources/libsecp256k1Tests/Shared.xcconfig
@@ -0,0 +1,116 @@
+//
+// Shared.xcconfig
+//
+// Generated by BuildSettingExtractor on 2/3/25
+// https://buildsettingextractor.com
+//
+
+// Code Signing Style
+//
+// This setting specifies the method used to acquire and locate signing assets. Choose
+// `Automatic` to let Xcode automatically create and update profiles, app IDs, and
+// certificates. Choose `Manual` to create and update these yourself on the developer
+// website.
+
+CODE_SIGN_STYLE = Automatic
+
+
+
+// Current Project Version
+//
+// This setting defines the current version of the project. The value must be a integer
+// or floating point number, such as `57` or `365.8`.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion)
+// key in the `Info.plist` file to the value of this build setting.
+
+CURRENT_PROJECT_VERSION = 1
+
+
+
+// Generate Info.plist File
+//
+// If enabled, automatically generate an Info.plist file with content from build
+// settings, and from content in the file pointed to by `INFOPLIST_FILE`, if defined.
+
+GENERATE_INFOPLIST_FILE = YES
+
+
+
+// Marketing Version
+//
+// This setting defines the user-visible version of the project.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring)
+// key in the `Info.plist` file to the value of this build setting.
+
+MARKETING_VERSION = 1.0
+
+
+
+// Product Bundle Identifier
+//
+// A string that uniquely identifies the bundle. The string should be in reverse DNS
+// format using only alphanumeric characters (`A-Z`, `a-z`, `0-9`), the dot (`.`), and
+// the hyphen (`-`).
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleIdentifier](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_BUNDLE_IDENTIFIER = dev.21.libsecp256k1Tests
+
+
+
+// Product Name
+//
+// This is the basename of the product generated by the target.
+//
+// When `GENERATE_INFOPLIST_FILE` is enabled, sets the value of the
+// [CFBundleName](https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename)
+// key in the `Info.plist` file to the value of this build setting.
+
+PRODUCT_NAME = $(TARGET_NAME)
+
+
+
+// Use Compiler to Extract Swift Strings
+//
+// When enabled, the Swift compiler will be used to extract Swift string literal and
+// interpolation `LocalizedStringKey` and `LocalizationKey` types during localization
+// export.
+
+SWIFT_EMIT_LOC_STRINGS = NO
+
+
+
+// Swift Language Version
+//
+// The language version used to compile the target's Swift code.
+
+SWIFT_VERSION = 5.0
+
+
+
+// Targeted Device Families
+//
+// Comma-separated list of integers corresponding to device families supported by this
+// target.
+//
+// The build system uses this information to set the correct value for the
+// `UIDeviceFamily` key it adds to the target's `Info.plist` file. Values inapplicable to
+// the current platform will be removed automatically. This also drives the
+// `--target-device` flag to actool, which determines the idioms selected during catalog
+// compilation.
+//
+// Possible values include:
+// * *1*: iPhone, iPod touch
+// * *2*: iPad, Mac Catalyst using "Scaled to Match iPad" Interface
+// * *3*: Apple TV
+// * *4*: Apple Watch
+// * *6*: Mac Catalyst using "Optimize for Mac" Interface
+// * *7*: Apple Vision
+
+TARGETED_DEVICE_FAMILY = 1,2
diff --git a/Projects/Sources/P256K/ASN1/ASN1.swift b/Projects/Sources/P256K/ASN1/ASN1.swift
new file mode 120000
index 00000000..dba95190
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/ASN1.swift
@@ -0,0 +1 @@
+../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/ASN1.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Any.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Any.swift
new file mode 120000
index 00000000..e3be5381
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Any.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1BitString.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1BitString.swift
new file mode 120000
index 00000000..2daefccd
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1BitString.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Boolean.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Boolean.swift
new file mode 120000
index 00000000..06cfb91d
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Boolean.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Identifier.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Identifier.swift
new file mode 120000
index 00000000..5581210d
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Identifier.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Integer.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Integer.swift
new file mode 120000
index 00000000..a67dfb5f
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Integer.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Null.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Null.swift
new file mode 120000
index 00000000..42c8083e
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Null.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1OctetString.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1OctetString.swift
new file mode 120000
index 00000000..7fb7d63c
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1OctetString.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Strings.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Strings.swift
new file mode 120000
index 00000000..436bb002
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Strings.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ArraySliceBigint.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
new file mode 120000
index 00000000..b7d6a566
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/GeneralizedTime.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/GeneralizedTime.swift
new file mode 120000
index 00000000..6a56b692
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/GeneralizedTime.swift
@@ -0,0 +1 @@
+../../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
new file mode 120000
index 00000000..adb5b8ba
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
@@ -0,0 +1 @@
+../../../../../Sources/ZKP/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/ECDSASignature.swift b/Projects/Sources/P256K/ASN1/ECDSASignature.swift
new file mode 120000
index 00000000..3bc6013c
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/ECDSASignature.swift
@@ -0,0 +1 @@
+../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/ECDSASignature.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/PEMDocument.swift b/Projects/Sources/P256K/ASN1/PEMDocument.swift
new file mode 120000
index 00000000..fce10dce
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/PEMDocument.swift
@@ -0,0 +1 @@
+../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/PEMDocument.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/PKCS8PrivateKey.swift b/Projects/Sources/P256K/ASN1/PKCS8PrivateKey.swift
new file mode 120000
index 00000000..73bb6f04
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/PKCS8PrivateKey.swift
@@ -0,0 +1 @@
+../../../../Submodules/swift-crypto/Sources/Crypto/ASN1/PKCS8PrivateKey.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/SEC1PrivateKey.swift b/Projects/Sources/P256K/ASN1/SEC1PrivateKey.swift
new file mode 120000
index 00000000..bba18879
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/SEC1PrivateKey.swift
@@ -0,0 +1 @@
+../../../../Sources/ZKP/ASN1/SEC1PrivateKey.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift b/Projects/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift
new file mode 120000
index 00000000..85bffd95
--- /dev/null
+++ b/Projects/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift
@@ -0,0 +1 @@
+../../../../Sources/ZKP/ASN1/SubjectPublicKeyInfo.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Asymmetric.swift b/Projects/Sources/P256K/Asymmetric.swift
new file mode 120000
index 00000000..f2d2bd04
--- /dev/null
+++ b/Projects/Sources/P256K/Asymmetric.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Asymmetric.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Combine.swift b/Projects/Sources/P256K/Combine.swift
new file mode 120000
index 00000000..a2442445
--- /dev/null
+++ b/Projects/Sources/P256K/Combine.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Combine.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Context.swift b/Projects/Sources/P256K/Context.swift
new file mode 120000
index 00000000..c2b74020
--- /dev/null
+++ b/Projects/Sources/P256K/Context.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Context.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/CryptoKitErrors.swift b/Projects/Sources/P256K/CryptoKitErrors.swift
new file mode 120000
index 00000000..ffdd9c70
--- /dev/null
+++ b/Projects/Sources/P256K/CryptoKitErrors.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/CryptoKitErrors.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/DH.swift b/Projects/Sources/P256K/DH.swift
new file mode 120000
index 00000000..9a1e5636
--- /dev/null
+++ b/Projects/Sources/P256K/DH.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/DH.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Digest.swift b/Projects/Sources/P256K/Digest.swift
new file mode 120000
index 00000000..d12d052d
--- /dev/null
+++ b/Projects/Sources/P256K/Digest.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/Digests/Digest.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ECDH.swift b/Projects/Sources/P256K/ECDH.swift
new file mode 120000
index 00000000..a1811b56
--- /dev/null
+++ b/Projects/Sources/P256K/ECDH.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/ECDH.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/ECDSA.swift b/Projects/Sources/P256K/ECDSA.swift
new file mode 120000
index 00000000..b395692b
--- /dev/null
+++ b/Projects/Sources/P256K/ECDSA.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/ECDSA.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/EdDSA.swift b/Projects/Sources/P256K/EdDSA.swift
new file mode 120000
index 00000000..114902d4
--- /dev/null
+++ b/Projects/Sources/P256K/EdDSA.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/EdDSA.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Errors.swift b/Projects/Sources/P256K/Errors.swift
new file mode 120000
index 00000000..bfc4bf5a
--- /dev/null
+++ b/Projects/Sources/P256K/Errors.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Errors.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/HashDigest.swift b/Projects/Sources/P256K/HashDigest.swift
new file mode 120000
index 00000000..bc0301da
--- /dev/null
+++ b/Projects/Sources/P256K/HashDigest.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/HashDigest.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/MuSig.swift b/Projects/Sources/P256K/MuSig.swift
new file mode 120000
index 00000000..7db22d42
--- /dev/null
+++ b/Projects/Sources/P256K/MuSig.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/MuSig.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Nonces.swift b/Projects/Sources/P256K/Nonces.swift
new file mode 120000
index 00000000..2bdbf904
--- /dev/null
+++ b/Projects/Sources/P256K/Nonces.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Nonces.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/P256K.swift b/Projects/Sources/P256K/P256K.swift
new file mode 120000
index 00000000..966f6f75
--- /dev/null
+++ b/Projects/Sources/P256K/P256K.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/P256K.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/PrettyBytes.swift b/Projects/Sources/P256K/PrettyBytes.swift
new file mode 120000
index 00000000..73957235
--- /dev/null
+++ b/Projects/Sources/P256K/PrettyBytes.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/Util/PrettyBytes.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/RNG_boring.swift b/Projects/Sources/P256K/RNG_boring.swift
new file mode 120000
index 00000000..93aa8279
--- /dev/null
+++ b/Projects/Sources/P256K/RNG_boring.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/Util/BoringSSL/RNG_boring.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Recovery.swift b/Projects/Sources/P256K/Recovery.swift
new file mode 120000
index 00000000..1d8594ea
--- /dev/null
+++ b/Projects/Sources/P256K/Recovery.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Recovery.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/SHA256.swift b/Projects/Sources/P256K/SHA256.swift
new file mode 120000
index 00000000..0dffa2ce
--- /dev/null
+++ b/Projects/Sources/P256K/SHA256.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/SHA256.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/SafeCompare.swift b/Projects/Sources/P256K/SafeCompare.swift
new file mode 120000
index 00000000..cb333962
--- /dev/null
+++ b/Projects/Sources/P256K/SafeCompare.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/SafeCompare.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Schnorr.swift b/Projects/Sources/P256K/Schnorr.swift
new file mode 120000
index 00000000..e6952807
--- /dev/null
+++ b/Projects/Sources/P256K/Schnorr.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Schnorr.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/SecureBytes.swift b/Projects/Sources/P256K/SecureBytes.swift
new file mode 120000
index 00000000..baf6b87d
--- /dev/null
+++ b/Projects/Sources/P256K/SecureBytes.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/Util/SecureBytes.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Signature.swift b/Projects/Sources/P256K/Signature.swift
new file mode 120000
index 00000000..95ac535a
--- /dev/null
+++ b/Projects/Sources/P256K/Signature.swift
@@ -0,0 +1 @@
+../../../Submodules/swift-crypto/Sources/Crypto/Signatures/Signature.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Tweak.swift b/Projects/Sources/P256K/Tweak.swift
new file mode 120000
index 00000000..dc644f7d
--- /dev/null
+++ b/Projects/Sources/P256K/Tweak.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Tweak.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Utility.swift b/Projects/Sources/P256K/Utility.swift
new file mode 120000
index 00000000..081b78d7
--- /dev/null
+++ b/Projects/Sources/P256K/Utility.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Utility.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256K/Zeroization.swift b/Projects/Sources/P256K/Zeroization.swift
new file mode 120000
index 00000000..d74cf167
--- /dev/null
+++ b/Projects/Sources/P256K/Zeroization.swift
@@ -0,0 +1 @@
+../../../Sources/ZKP/Zeroization.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/AsymmetricTests.swift b/Projects/Sources/P256KTests/AsymmetricTests.swift
new file mode 120000
index 00000000..806d2dce
--- /dev/null
+++ b/Projects/Sources/P256KTests/AsymmetricTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/AsymmetricTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/ECDHTests.swift b/Projects/Sources/P256KTests/ECDHTests.swift
new file mode 120000
index 00000000..d55907ef
--- /dev/null
+++ b/Projects/Sources/P256KTests/ECDHTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/ECDHTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/ECDSATests.swift b/Projects/Sources/P256KTests/ECDSATests.swift
new file mode 120000
index 00000000..5b36fc15
--- /dev/null
+++ b/Projects/Sources/P256KTests/ECDSATests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/ECDSATests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/MusigTests.swift b/Projects/Sources/P256KTests/MusigTests.swift
new file mode 120000
index 00000000..6980ea04
--- /dev/null
+++ b/Projects/Sources/P256KTests/MusigTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/MusigTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/RecoveryTests.swift b/Projects/Sources/P256KTests/RecoveryTests.swift
new file mode 120000
index 00000000..7f88c293
--- /dev/null
+++ b/Projects/Sources/P256KTests/RecoveryTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/RecoveryTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/SHA256Tests.swift b/Projects/Sources/P256KTests/SHA256Tests.swift
new file mode 120000
index 00000000..0d889c48
--- /dev/null
+++ b/Projects/Sources/P256KTests/SHA256Tests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/SHA256Tests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/SchnorrTests.swift b/Projects/Sources/P256KTests/SchnorrTests.swift
new file mode 120000
index 00000000..1cc3e833
--- /dev/null
+++ b/Projects/Sources/P256KTests/SchnorrTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/SchnorrTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/TaprootTests.swift b/Projects/Sources/P256KTests/TaprootTests.swift
new file mode 120000
index 00000000..5cb50d52
--- /dev/null
+++ b/Projects/Sources/P256KTests/TaprootTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/TaprootTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/TweakTests.swift b/Projects/Sources/P256KTests/TweakTests.swift
new file mode 120000
index 00000000..c8d04f25
--- /dev/null
+++ b/Projects/Sources/P256KTests/TweakTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/TweakTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/P256KTests/UtilityTests.swift b/Projects/Sources/P256KTests/UtilityTests.swift
new file mode 120000
index 00000000..e50121f1
--- /dev/null
+++ b/Projects/Sources/P256KTests/UtilityTests.swift
@@ -0,0 +1 @@
+../../../Tests/ZKPTests/UtilityTests.swift
\ No newline at end of file
diff --git a/Projects/Sources/XCFrameworkApp/ContentView.swift b/Projects/Sources/XCFrameworkApp/ContentView.swift
new file mode 100644
index 00000000..e38b525a
--- /dev/null
+++ b/Projects/Sources/XCFrameworkApp/ContentView.swift
@@ -0,0 +1,21 @@
+import SwiftUI
+import P256K
+
+public struct ContentView: View {
+ public init() {}
+
+ public var body: some View {
+ let privateKey = try! P256K.Signing.PrivateKey()
+ let stringKey = String(bytes: privateKey.dataRepresentation)
+
+ Text("KEY: \(stringKey)")
+ .padding()
+ }
+}
+
+
+struct ContentView_Previews: PreviewProvider {
+ static var previews: some View {
+ ContentView()
+ }
+}
diff --git a/Projects/Sources/XCFrameworkApp/XCFrameworkApp.swift b/Projects/Sources/XCFrameworkApp/XCFrameworkApp.swift
new file mode 100644
index 00000000..f3d7e52f
--- /dev/null
+++ b/Projects/Sources/XCFrameworkApp/XCFrameworkApp.swift
@@ -0,0 +1,10 @@
+import SwiftUI
+
+@main
+struct XCFrameworkApp: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
diff --git a/Projects/Sources/XCFrameworkAppTests/XCFrameworkTests.swift b/Projects/Sources/XCFrameworkAppTests/XCFrameworkTests.swift
new file mode 100644
index 00000000..f067eec3
--- /dev/null
+++ b/Projects/Sources/XCFrameworkAppTests/XCFrameworkTests.swift
@@ -0,0 +1,8 @@
+import Foundation
+import XCTest
+
+final class XCFrameworkTests: XCTestCase {
+ func test_twoPlusTwo_isFour() {
+ XCTAssertEqual(2+2, 4)
+ }
+}
\ No newline at end of file
diff --git a/Projects/Sources/libsecp256k1Tests/BindingsTests.swift b/Projects/Sources/libsecp256k1Tests/BindingsTests.swift
new file mode 120000
index 00000000..002d2308
--- /dev/null
+++ b/Projects/Sources/libsecp256k1Tests/BindingsTests.swift
@@ -0,0 +1 @@
+../../../Tests/libsecp256k1zkpTests/BindingsTests.swift
\ No newline at end of file
diff --git a/README.md b/README.md
index 3a301822..6a80bb86 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Swift package for elliptic curve public key cryptography, ECDSA, and Schnorr Sig
- Provide lightweight ECDSA & Schnorr Signatures functionality
- Support simple and advanced usage, including BIP-327 and BIP-340
-- Expose C bindings for full control of the secp256k1 implementation
+- Expose libsecp256k1 bindings for full control of the implementation
- Offer a familiar API design inspired by [Swift Crypto](https://github.com/apple/swift-crypto)
- Maintain automatic updates for Swift and libsecp256k1
- Ensure availability for Linux and Apple platform ecosystems
@@ -28,14 +28,14 @@ This package uses Swift Package Manager. To add it to your project:
Add the following to your `Package.swift` file:
```swift
-.package(name: "swift-secp256k1", url: "https://github.com/21-DOT-DEV/swift-secp256k1", exact: "0.18.0"),
+.package(name: "swift-secp256k1", url: "https://github.com/21-DOT-DEV/swift-secp256k1", exact: "0.19.0"),
```
Then, include `secp256k1` as a dependency in your target:
```swift
.target(name: "", dependencies: [
- .product(name: "secp256k1", package: "swift-secp256k1")
+ .product(name: "P256K", package: "swift-secp256k1")
]),
```
@@ -54,11 +54,11 @@ arena 21-DOT-DEV/swift-secp256k1
### ECDSA
```swift
-import secp256k1
+import P256K
// Private key
let privateBytes = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
-let privateKey = try! secp256k1.Signing.PrivateKey(rawRepresentation: privateBytes)
+let privateKey = try! P256K.Signing.PrivateKey(rawRepresentation: privateBytes)
// Public key
print(String(bytes: privateKey.publicKey.rawRepresentation))
@@ -74,7 +74,7 @@ print(try! signature.derRepresentation.base64EncodedString())
### Schnorr
```swift
// Strict BIP340 mode is disabled by default for Schnorr signatures with variable length messages
-let privateKey = try! secp256k1.Schnorr.PrivateKey()
+let privateKey = try! P256K.Schnorr.PrivateKey()
// Extra params for custom signing
var auxRand = try! "C87AA53824B4D7AE2EB035A2B5BBBCCC080E76CDC6D1692C4B0B62D798E6D906".bytes
@@ -87,7 +87,7 @@ let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand
## Tweak
```swift
-let privateKey = try! secp256k1.Signing.PrivateKey()
+let privateKey = try! P256K.Signing.PrivateKey()
// Adding a tweak to the private key and public key
let tweak = try! "5f0da318c6e02f653a789950e55756ade9f194e1ec228d7f368de1bd821322b6".bytes
@@ -98,8 +98,8 @@ let tweakedPublicKeyKey = try! privateKey.publicKey.add(tweak)
## Elliptic Curve Diffie Hellman
```swift
-let privateKey = try! secp256k1.KeyAgreement.PrivateKey()
-let publicKey = try! secp256k1.KeyAgreement.PrivateKey().publicKey
+let privateKey = try! P256K.KeyAgreement.PrivateKey()
+let publicKey = try! P256K.KeyAgreement.PrivateKey().publicKey
// Create a compressed shared secret with a private key from only a public key
let sharedSecret = try! privateKey.sharedSecretFromKeyAgreement(with: publicKey, format: .compressed)
@@ -111,17 +111,17 @@ let symmetricKey = SHA256.hash(data: sharedSecret.bytes)
## Silent Payments Scheme
```swift
-let privateSign1 = try! secp256k1.Signing.PrivateKey()
-let privateSign2 = try! secp256k1.Signing.PrivateKey()
+let privateSign1 = try! P256K.Signing.PrivateKey()
+let privateSign2 = try! P256K.Signing.PrivateKey()
-let privateKey1 = try! secp256k1.KeyAgreement.PrivateKey(rawRepresentation: privateSign1.rawRepresentation)
-let privateKey2 = try! secp256k1.KeyAgreement.PrivateKey(rawRepresentation: privateSign2.rawRepresentation)
+let privateKey1 = try! P256K.KeyAgreement.PrivateKey(rawRepresentation: privateSign1.rawRepresentation)
+let privateKey2 = try! P256K.KeyAgreement.PrivateKey(rawRepresentation: privateSign2.rawRepresentation)
let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey)
let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: privateKey1.publicKey)
-let sharedSecretSign1 = try! secp256k1.Signing.PrivateKey(rawRepresentation: sharedSecret1.bytes)
-let sharedSecretSign2 = try! secp256k1.Signing.PrivateKey(rawRepresentation: sharedSecret2.bytes)
+let sharedSecretSign1 = try! P256K.Signing.PrivateKey(rawRepresentation: sharedSecret1.bytes)
+let sharedSecretSign2 = try! P256K.Signing.PrivateKey(rawRepresentation: sharedSecret2.bytes)
// Payable Silent Payment public key
let xonlyTweak2 = try! sharedSecretSign2.publicKey.xonly.add(privateSign1.publicKey.xonly.bytes)
@@ -133,14 +133,14 @@ let privateTweak1 = try! sharedSecretSign1.add(xonly: privateSign1.publicKey.xon
## Recovery
```swift
-let privateKey = try! secp256k1.Recovery.PrivateKey()
+let privateKey = try! P256K.Recovery.PrivateKey()
let messageData = "We're all Satoshi.".data(using: .utf8)!
// Create a recoverable ECDSA signature
let recoverySignature = try! privateKey.signature(for: messageData)
// Recover an ECDSA public key from a signature
-let publicKey = try! secp256k1.Recovery.PublicKey(messageData, signature: recoverySignature)
+let publicKey = try! P256K.Recovery.PublicKey(messageData, signature: recoverySignature)
// Convert a recoverable signature into a normal signature
let signature = try! recoverySignature.normalize
@@ -149,8 +149,8 @@ let signature = try! recoverySignature.normalize
## Combine Public Keys
```swift
-let privateKey = try! secp256k1.Signing.PrivateKey()
-let publicKey = try! secp256k1.Signing.PrivateKey().public
+let privateKey = try! P256K.Signing.PrivateKey()
+let publicKey = try! P256K.Signing.PrivateKey().public
// The Combine API arguments are an array of PublicKey objects and an optional format
publicKey.combine([privateKey.publicKey], format: .uncompressed)
@@ -168,38 +168,38 @@ oUQDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMAcjHIrTDS6HEELgguOatmFBOp
"""
// Import keys generated from OpenSSL
-let privateKey = try! secp256k1.Signing.PrivateKey(pemRepresentation: privateKeyString)
+let privateKey = try! P256K.Signing.PrivateKey(pemRepresentation: privateKeyString)
```
## MuSig2
```swift
// Initialize private keys for two signers
-let firstPrivateKey = try secp256k1.Schnorr.PrivateKey()
-let secondPrivateKey = try secp256k1.Schnorr.PrivateKey()
+let firstPrivateKey = try P256K.Schnorr.PrivateKey()
+let secondPrivateKey = try P256K.Schnorr.PrivateKey()
// Aggregate the public keys using MuSig
-let aggregateKey = try secp256k1.MuSig.aggregate([firstPrivateKey.publicKey, secondPrivateKey.publicKey])
+let aggregateKey = try P256K.MuSig.aggregate([firstPrivateKey.publicKey, secondPrivateKey.publicKey])
// Message to be signed
let message = "Vires in Numeris.".data(using: .utf8)!
let messageHash = SHA256.hash(data: message)
// Generate nonces for each signer
-let firstNonce = try secp256k1.MuSig.Nonce.generate(
+let firstNonce = try P256K.MuSig.Nonce.generate(
secretKey: firstPrivateKey,
publicKey: firstPrivateKey.publicKey,
msg32: Array(messageHash)
)
-let secondNonce = try secp256k1.MuSig.Nonce.generate(
+let secondNonce = try P256K.MuSig.Nonce.generate(
secretKey: secondPrivateKey,
publicKey: secondPrivateKey.publicKey,
msg32: Array(messageHash)
)
// Aggregate nonces
-let aggregateNonce = try secp256k1.MuSig.Nonce(aggregating: [firstNonce.pubnonce, secondNonce.pubnonce])
+let aggregateNonce = try P256K.MuSig.Nonce(aggregating: [firstNonce.pubnonce, secondNonce.pubnonce])
// Create partial signatures
let firstPartialSignature = try firstPrivateKey.partialSignature(
@@ -219,7 +219,7 @@ let secondPartialSignature = try secondPrivateKey.partialSignature(
)
// Aggregate partial signatures into a full signature
-let aggregateSignature = try secp256k1.MuSig.aggregateSignatures([firstPartialSignature, secondPartialSignature])
+let aggregateSignature = try P256K.MuSig.aggregateSignatures([firstPartialSignature, secondPartialSignature])
// Verify the aggregate signature
let isValid = aggregateKey.isValidSignature(
diff --git a/Sources/secp256k1/ASN1/ASN1.swift b/Sources/P256K/ASN1/ASN1.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/ASN1.swift
rename to Sources/P256K/ASN1/ASN1.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Any.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Any.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Any.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Any.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1BitString.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1BitString.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1BitString.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1BitString.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Boolean.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Boolean.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Boolean.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Boolean.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Identifier.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Identifier.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Identifier.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Identifier.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Integer.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Integer.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Integer.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Integer.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Null.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Null.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Null.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Null.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1OctetString.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1OctetString.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1OctetString.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1OctetString.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Strings.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ASN1Strings.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ASN1Strings.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ASN1Strings.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ArraySliceBigint.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/GeneralizedTime.swift b/Sources/P256K/ASN1/Basic ASN1 Types/GeneralizedTime.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/Basic ASN1 Types/GeneralizedTime.swift
rename to Sources/P256K/ASN1/Basic ASN1 Types/GeneralizedTime.swift
diff --git a/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
new file mode 120000
index 00000000..9e06c264
--- /dev/null
+++ b/Sources/P256K/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
@@ -0,0 +1 @@
+../../../ZKP/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/ASN1/ECDSASignature.swift b/Sources/P256K/ASN1/ECDSASignature.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/ECDSASignature.swift
rename to Sources/P256K/ASN1/ECDSASignature.swift
diff --git a/Sources/secp256k1/ASN1/PEMDocument.swift b/Sources/P256K/ASN1/PEMDocument.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/PEMDocument.swift
rename to Sources/P256K/ASN1/PEMDocument.swift
diff --git a/Sources/secp256k1/ASN1/PKCS8PrivateKey.swift b/Sources/P256K/ASN1/PKCS8PrivateKey.swift
similarity index 100%
rename from Sources/secp256k1/ASN1/PKCS8PrivateKey.swift
rename to Sources/P256K/ASN1/PKCS8PrivateKey.swift
diff --git a/Sources/P256K/ASN1/SEC1PrivateKey.swift b/Sources/P256K/ASN1/SEC1PrivateKey.swift
new file mode 120000
index 00000000..8eaa1fec
--- /dev/null
+++ b/Sources/P256K/ASN1/SEC1PrivateKey.swift
@@ -0,0 +1 @@
+../../ZKP/ASN1/SEC1PrivateKey.swift
\ No newline at end of file
diff --git a/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift b/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift
new file mode 120000
index 00000000..ad433221
--- /dev/null
+++ b/Sources/P256K/ASN1/SubjectPublicKeyInfo.swift
@@ -0,0 +1 @@
+../../ZKP/ASN1/SubjectPublicKeyInfo.swift
\ No newline at end of file
diff --git a/Sources/P256K/Asymmetric.swift b/Sources/P256K/Asymmetric.swift
new file mode 120000
index 00000000..ab9dec0e
--- /dev/null
+++ b/Sources/P256K/Asymmetric.swift
@@ -0,0 +1 @@
+../ZKP/Asymmetric.swift
\ No newline at end of file
diff --git a/Sources/P256K/Combine.swift b/Sources/P256K/Combine.swift
new file mode 120000
index 00000000..fc9f8691
--- /dev/null
+++ b/Sources/P256K/Combine.swift
@@ -0,0 +1 @@
+../ZKP/Combine.swift
\ No newline at end of file
diff --git a/Sources/P256K/Context.swift b/Sources/P256K/Context.swift
new file mode 120000
index 00000000..2294c4d2
--- /dev/null
+++ b/Sources/P256K/Context.swift
@@ -0,0 +1 @@
+../ZKP/Context.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/CryptoKitErrors.swift b/Sources/P256K/CryptoKitErrors.swift
similarity index 100%
rename from Sources/secp256k1/CryptoKitErrors.swift
rename to Sources/P256K/CryptoKitErrors.swift
diff --git a/Sources/P256K/DH.swift b/Sources/P256K/DH.swift
new file mode 120000
index 00000000..ed8caa90
--- /dev/null
+++ b/Sources/P256K/DH.swift
@@ -0,0 +1 @@
+../ZKP/DH.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Digest.swift b/Sources/P256K/Digest.swift
similarity index 100%
rename from Sources/secp256k1/Digest.swift
rename to Sources/P256K/Digest.swift
diff --git a/Sources/P256K/ECDH.swift b/Sources/P256K/ECDH.swift
new file mode 120000
index 00000000..81facd16
--- /dev/null
+++ b/Sources/P256K/ECDH.swift
@@ -0,0 +1 @@
+../ZKP/ECDH.swift
\ No newline at end of file
diff --git a/Sources/P256K/ECDSA.swift b/Sources/P256K/ECDSA.swift
new file mode 120000
index 00000000..08b5ee5a
--- /dev/null
+++ b/Sources/P256K/ECDSA.swift
@@ -0,0 +1 @@
+../ZKP/ECDSA.swift
\ No newline at end of file
diff --git a/Sources/P256K/EdDSA.swift b/Sources/P256K/EdDSA.swift
new file mode 120000
index 00000000..c2813ff4
--- /dev/null
+++ b/Sources/P256K/EdDSA.swift
@@ -0,0 +1 @@
+../ZKP/EdDSA.swift
\ No newline at end of file
diff --git a/Sources/P256K/Errors.swift b/Sources/P256K/Errors.swift
new file mode 120000
index 00000000..48aef72e
--- /dev/null
+++ b/Sources/P256K/Errors.swift
@@ -0,0 +1 @@
+../ZKP/Errors.swift
\ No newline at end of file
diff --git a/Sources/P256K/HashDigest.swift b/Sources/P256K/HashDigest.swift
new file mode 120000
index 00000000..a7aeb6c3
--- /dev/null
+++ b/Sources/P256K/HashDigest.swift
@@ -0,0 +1 @@
+../ZKP/HashDigest.swift
\ No newline at end of file
diff --git a/Sources/P256K/MuSig.swift b/Sources/P256K/MuSig.swift
new file mode 120000
index 00000000..5a452943
--- /dev/null
+++ b/Sources/P256K/MuSig.swift
@@ -0,0 +1 @@
+../ZKP/MuSig.swift
\ No newline at end of file
diff --git a/Sources/P256K/Nonces.swift b/Sources/P256K/Nonces.swift
new file mode 120000
index 00000000..10cc6190
--- /dev/null
+++ b/Sources/P256K/Nonces.swift
@@ -0,0 +1 @@
+../ZKP/Nonces.swift
\ No newline at end of file
diff --git a/Sources/P256K/P256K.swift b/Sources/P256K/P256K.swift
new file mode 120000
index 00000000..3bf0835d
--- /dev/null
+++ b/Sources/P256K/P256K.swift
@@ -0,0 +1 @@
+../ZKP/P256K.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/PrettyBytes.swift b/Sources/P256K/PrettyBytes.swift
similarity index 100%
rename from Sources/secp256k1/PrettyBytes.swift
rename to Sources/P256K/PrettyBytes.swift
diff --git a/Sources/secp256k1/RNG_boring.swift b/Sources/P256K/RNG_boring.swift
similarity index 100%
rename from Sources/secp256k1/RNG_boring.swift
rename to Sources/P256K/RNG_boring.swift
diff --git a/Sources/P256K/Recovery.swift b/Sources/P256K/Recovery.swift
new file mode 120000
index 00000000..899ccb4d
--- /dev/null
+++ b/Sources/P256K/Recovery.swift
@@ -0,0 +1 @@
+../ZKP/Recovery.swift
\ No newline at end of file
diff --git a/Sources/P256K/SHA256.swift b/Sources/P256K/SHA256.swift
new file mode 120000
index 00000000..e1ae70d9
--- /dev/null
+++ b/Sources/P256K/SHA256.swift
@@ -0,0 +1 @@
+../ZKP/SHA256.swift
\ No newline at end of file
diff --git a/Sources/P256K/SafeCompare.swift b/Sources/P256K/SafeCompare.swift
new file mode 120000
index 00000000..49ee0be0
--- /dev/null
+++ b/Sources/P256K/SafeCompare.swift
@@ -0,0 +1 @@
+../ZKP/SafeCompare.swift
\ No newline at end of file
diff --git a/Sources/P256K/Schnorr.swift b/Sources/P256K/Schnorr.swift
new file mode 120000
index 00000000..3f2548d6
--- /dev/null
+++ b/Sources/P256K/Schnorr.swift
@@ -0,0 +1 @@
+../ZKP/Schnorr.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/SecureBytes.swift b/Sources/P256K/SecureBytes.swift
similarity index 100%
rename from Sources/secp256k1/SecureBytes.swift
rename to Sources/P256K/SecureBytes.swift
diff --git a/Sources/secp256k1/Signature.swift b/Sources/P256K/Signature.swift
similarity index 100%
rename from Sources/secp256k1/Signature.swift
rename to Sources/P256K/Signature.swift
diff --git a/Sources/P256K/Tweak.swift b/Sources/P256K/Tweak.swift
new file mode 120000
index 00000000..7eae0431
--- /dev/null
+++ b/Sources/P256K/Tweak.swift
@@ -0,0 +1 @@
+../ZKP/Tweak.swift
\ No newline at end of file
diff --git a/Sources/P256K/Utility.swift b/Sources/P256K/Utility.swift
new file mode 120000
index 00000000..605dc116
--- /dev/null
+++ b/Sources/P256K/Utility.swift
@@ -0,0 +1 @@
+../ZKP/Utility.swift
\ No newline at end of file
diff --git a/Sources/P256K/Zeroization.swift b/Sources/P256K/Zeroization.swift
new file mode 120000
index 00000000..baa2a1fe
--- /dev/null
+++ b/Sources/P256K/Zeroization.swift
@@ -0,0 +1 @@
+../ZKP/Zeroization.swift
\ No newline at end of file
diff --git a/Sources/zkp/ASN1/ASN1.swift b/Sources/ZKP/ASN1/ASN1.swift
similarity index 100%
rename from Sources/zkp/ASN1/ASN1.swift
rename to Sources/ZKP/ASN1/ASN1.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Any.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Any.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Any.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Any.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1BitString.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1BitString.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1BitString.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1BitString.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Boolean.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Boolean.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Boolean.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Boolean.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Identifier.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Identifier.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Identifier.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Identifier.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Integer.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Integer.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Integer.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Integer.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Null.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Null.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Null.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Null.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1OctetString.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1OctetString.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1OctetString.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1OctetString.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ASN1Strings.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Strings.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ASN1Strings.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ASN1Strings.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ArraySliceBigint.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ArraySliceBigint.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/GeneralizedTime.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/GeneralizedTime.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/GeneralizedTime.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/GeneralizedTime.swift
diff --git a/Sources/zkp/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Sources/ZKP/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
similarity index 100%
rename from Sources/zkp/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
rename to Sources/ZKP/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
diff --git a/Sources/zkp/ASN1/ECDSASignature.swift b/Sources/ZKP/ASN1/ECDSASignature.swift
similarity index 100%
rename from Sources/zkp/ASN1/ECDSASignature.swift
rename to Sources/ZKP/ASN1/ECDSASignature.swift
diff --git a/Sources/zkp/ASN1/PEMDocument.swift b/Sources/ZKP/ASN1/PEMDocument.swift
similarity index 100%
rename from Sources/zkp/ASN1/PEMDocument.swift
rename to Sources/ZKP/ASN1/PEMDocument.swift
diff --git a/Sources/zkp/ASN1/PKCS8PrivateKey.swift b/Sources/ZKP/ASN1/PKCS8PrivateKey.swift
similarity index 100%
rename from Sources/zkp/ASN1/PKCS8PrivateKey.swift
rename to Sources/ZKP/ASN1/PKCS8PrivateKey.swift
diff --git a/Sources/zkp/ASN1/SEC1PrivateKey.swift b/Sources/ZKP/ASN1/SEC1PrivateKey.swift
similarity index 100%
rename from Sources/zkp/ASN1/SEC1PrivateKey.swift
rename to Sources/ZKP/ASN1/SEC1PrivateKey.swift
diff --git a/Sources/zkp/ASN1/SubjectPublicKeyInfo.swift b/Sources/ZKP/ASN1/SubjectPublicKeyInfo.swift
similarity index 100%
rename from Sources/zkp/ASN1/SubjectPublicKeyInfo.swift
rename to Sources/ZKP/ASN1/SubjectPublicKeyInfo.swift
diff --git a/Sources/zkp/Asymmetric.swift b/Sources/ZKP/Asymmetric.swift
similarity index 95%
rename from Sources/zkp/Asymmetric.swift
rename to Sources/ZKP/Asymmetric.swift
index 490f5d89..ef076c1b 100644
--- a/Sources/zkp/Asymmetric.swift
+++ b/Sources/ZKP/Asymmetric.swift
@@ -11,7 +11,7 @@
import Foundation
/// An elliptic curve that enables secp256k1 signatures and key agreement.
-public extension secp256k1 {
+public extension P256K {
/// A mechanism used to create or verify a cryptographic signature using the secp256k1
/// elliptic curve digital signature algorithm (ECDSA).
enum Signing {
@@ -49,7 +49,7 @@ public extension secp256k1 {
///
/// - Parameter format: The key format, default is .compressed.
/// - Throws: An error if the private key cannot be generated.
- public init(format: secp256k1.Format = .compressed) throws {
+ public init(format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(format: format)
}
@@ -58,7 +58,7 @@ public extension secp256k1 {
/// - Parameter data: A data representation of the key.
/// - Parameter format: The key format, default is .compressed.
/// - Throws: An error if the raw representation does not create a private key for signing.
- public init(dataRepresentation data: D, format: secp256k1.Format = .compressed) throws {
+ public init(dataRepresentation data: D, format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(dataRepresentation: data, format: format)
}
@@ -115,7 +115,7 @@ public extension secp256k1 {
/// The corresponding public key for the secp256k1 curve.
public struct PublicKey {
/// Generated secp256k1 public key.
- private let baseKey: PublicKeyImplementation
+ internal let baseKey: PublicKeyImplementation
/// The secp256k1 public key object.
var bytes: [UInt8] {
@@ -127,11 +127,6 @@ public extension secp256k1 {
baseKey.dataRepresentation
}
- /// A raw representation of the public key.
- public var rawRepresentation: secp256k1_pubkey {
- baseKey.rawRepresentation
- }
-
/// The associated x-only public key for verifying Schnorr signatures.
///
/// - Returns: The associated x-only public key.
@@ -140,7 +135,7 @@ public extension secp256k1 {
}
/// The key format representation of the public key.
- public var format: secp256k1.Format {
+ public var format: P256K.Format {
baseKey.format
}
@@ -175,7 +170,7 @@ public extension secp256k1 {
/// - Parameter data: A data representation of the key.
/// - Parameter format: The key format.
/// - Throws: An error if the data representation does not create a public key.
- public init(dataRepresentation data: D, format: secp256k1.Format) throws {
+ public init(dataRepresentation data: D, format: P256K.Format) throws {
self.baseKey = try PublicKeyImplementation(dataRepresentation: data, format: format)
}
@@ -210,7 +205,7 @@ public extension secp256k1 {
let length = x963Representation.withUnsafeBytes { $0.count }
switch length {
- case (2 * secp256k1.ByteLength.dimension) + 1:
+ case (2 * P256K.ByteLength.dimension) + 1:
self.baseKey = try PublicKeyImplementation(dataRepresentation: x963Representation, format: .uncompressed)
default:
diff --git a/Sources/zkp/Combine.swift b/Sources/ZKP/Combine.swift
similarity index 69%
rename from Sources/zkp/Combine.swift
rename to Sources/ZKP/Combine.swift
index 0b5be19f..b8f90ef8 100644
--- a/Sources/zkp/Combine.swift
+++ b/Sources/ZKP/Combine.swift
@@ -10,20 +10,27 @@
import Foundation
-public extension secp256k1.Signing.PublicKey {
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
+public extension P256K.Signing.PublicKey {
/// Create a new `PublicKey` by combining the current public key with an array of public keys.
/// - Parameters:
/// - pubkeys: the array of public key objects to be combined with
/// - format: the format of the combined `PublicKey` object
/// - Returns: combined `PublicKey` object
- func combine(_ pubkeys: [Self], format: secp256k1.Format = .compressed) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ func combine(_ pubkeys: [Self], format: P256K.Format = .compressed) throws -> Self {
+ let context = P256K.Context.rawRepresentation
let allPubKeys = [self] + pubkeys
var pubKeyLen = format.length
var combinedKey = secp256k1_pubkey()
var combinedBytes = [UInt8](repeating: 0, count: pubKeyLen)
- guard PointerArrayUtility.withUnsafePointerArray(allPubKeys.map { $0.rawRepresentation }, { pointers in
+ guard PointerArrayUtility
+ .withUnsafePointerArray(allPubKeys.map { $0.baseKey.rawRepresentation }, { pointers in
secp256k1_ec_pubkey_combine(context, &combinedKey, pointers, pointers.count).boolValue
}), secp256k1_ec_pubkey_serialize(context, &combinedBytes, &pubKeyLen, &combinedKey, format.rawValue).boolValue else {
throw secp256k1Error.underlyingCryptoError
diff --git a/Sources/zkp/Context.swift b/Sources/ZKP/Context.swift
similarity index 90%
rename from Sources/zkp/Context.swift
rename to Sources/ZKP/Context.swift
index 4a4e7699..b8acf077 100644
--- a/Sources/zkp/Context.swift
+++ b/Sources/ZKP/Context.swift
@@ -8,6 +8,12 @@
// See the accompanying file LICENSE for information
//
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
/// A public extension that provides additional functionality to the `secp256k1` structure.
///
/// This extension includes a nested structure, `Context`, which represents the context for `secp256k1` operations.
@@ -17,7 +23,7 @@
/// A constructed context can safely be used from multiple threads simultaneously, but API calls that take a non-const
/// pointer to a context need exclusive access to it. In particular this is the case for `secp256k1_context_destroy`,
/// `secp256k1_context_preallocated_destroy`, and `secp256k1_context_randomize`.
-public extension secp256k1 {
+public extension P256K {
/// A structure that represents the context flags for `secp256k1` operations.
///
/// This structure conforms to the `OptionSet` protocol, allowing you to combine different context flags.
@@ -28,7 +34,7 @@ public extension secp256k1 {
/// memory for the context.
struct Context: OptionSet {
/// The raw representation of `secp256k1.Context`
- public static let rawRepresentation = try! secp256k1.Context.create()
+ public static let rawRepresentation = try! P256K.Context.create()
/// The raw value of the context flags.
public let rawValue: UInt32
@@ -57,7 +63,7 @@ public extension secp256k1 {
/// the `Context` structure. The method throws an error if the context creation or randomization fails. If the
/// context creation is successful, the method returns an opaque pointer to the created context.
public static func create(_ context: Self = .none) throws -> OpaquePointer {
- var randomBytes = SecureBytes(count: secp256k1.ByteLength.privateKey).bytes
+ var randomBytes = SecureBytes(count: P256K.ByteLength.privateKey).bytes
guard let context = secp256k1_context_create(context.rawValue),
secp256k1_context_randomize(context, &randomBytes).boolValue else {
throw secp256k1Error.underlyingCryptoError
diff --git a/Sources/zkp/CryptoKitErrors.swift b/Sources/ZKP/CryptoKitErrors.swift
similarity index 100%
rename from Sources/zkp/CryptoKitErrors.swift
rename to Sources/ZKP/CryptoKitErrors.swift
diff --git a/Sources/zkp/DH.swift b/Sources/ZKP/DH.swift
similarity index 98%
rename from Sources/zkp/DH.swift
rename to Sources/ZKP/DH.swift
index b83c77e5..bf5cdff3 100644
--- a/Sources/zkp/DH.swift
+++ b/Sources/ZKP/DH.swift
@@ -53,7 +53,7 @@ public struct SharedSecret: ContiguousBytes {
var ss: SecureBytes
// An enum that represents the format of the shared secret
- let format: secp256k1.Format
+ let format: P256K.Format
public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
try ss.withUnsafeBytes(body)
diff --git a/Sources/zkp/Digest.swift b/Sources/ZKP/Digest.swift
similarity index 100%
rename from Sources/zkp/Digest.swift
rename to Sources/ZKP/Digest.swift
diff --git a/Sources/zkp/ECDH.swift b/Sources/ZKP/ECDH.swift
similarity index 82%
rename from Sources/zkp/ECDH.swift
rename to Sources/ZKP/ECDH.swift
index e369aab0..d8fc3d4f 100644
--- a/Sources/zkp/ECDH.swift
+++ b/Sources/ZKP/ECDH.swift
@@ -10,16 +10,22 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
// MARK: - secp256k1 + KeyAgreement
/// An elliptic curve that enables secp256k1 signatures and key agreement.
-public extension secp256k1 {
+public extension P256K {
/// A namespace for key agreement functionality using the secp256k1 elliptic curve.
enum KeyAgreement {
/// A public key for performing key agreement using the secp256k1 elliptic curve.
public struct PublicKey /*: NISTECPublicKey */ {
/// The underlying implementation of the secp256k1 public key.
- let baseKey: PublicKeyImplementation
+ internal let baseKey: PublicKeyImplementation
/// Creates a secp256k1 public key for key agreement from a collection of bytes.
///
@@ -27,7 +33,7 @@ public extension secp256k1 {
/// - data: A data representation of the public key as a collection of contiguous bytes.
/// - format: The format of the public key object.
/// - Throws: An error if the raw representation does not create a public key.
- public init(dataRepresentation data: D, format: secp256k1.Format = .compressed) throws {
+ public init(dataRepresentation data: D, format: P256K.Format = .compressed) throws {
self.baseKey = try PublicKeyImplementation(dataRepresentation: data, format: format)
}
@@ -41,16 +47,13 @@ public extension secp256k1 {
/// The associated x-only public key for verifying Schnorr signatures.
///
/// - Returns: The associated x-only public key.
- public var xonly: secp256k1.KeyAgreement.XonlyKey {
+ public var xonly: P256K.KeyAgreement.XonlyKey {
XonlyKey(baseKey: baseKey.xonly)
}
/// A data representation of the public key.
public var dataRepresentation: Data { baseKey.dataRepresentation }
- /// A raw representation of the public key.
- public var rawRepresentation: secp256k1_pubkey { baseKey.rawRepresentation }
-
/// Implementation public key object.
var bytes: [UInt8] { baseKey.bytes }
}
@@ -63,9 +66,6 @@ public extension secp256k1 {
/// A data representation of the backing x-only public key.
public var dataRepresentation: Data { baseKey.dataRepresentation }
- /// A raw representation of the backing x-only public key.
- public var rawRepresentation: secp256k1_xonly_pubkey { baseKey.rawRepresentation }
-
/// A boolean that will be set to true if the point encoded by xonly is the
/// negation of the pubkey and set to false otherwise.
public var parity: Bool { baseKey.keyParity.boolValue }
@@ -87,7 +87,7 @@ public extension secp256k1 {
///
/// - Parameter format: The format of the secp256k1 key (default is .compressed).
/// - Throws: An error is thrown when the key generation fails.
- public init(format: secp256k1.Format = .compressed) throws {
+ public init(format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(format: format)
}
@@ -97,7 +97,7 @@ public extension secp256k1 {
/// - data: A raw representation of the key.
/// - format: The format of the secp256k1 key (default is .compressed).
/// - Throws: An error is thrown when the raw representation does not create a private key for key agreement.
- public init(dataRepresentation data: D, format: secp256k1.Format = .compressed) throws {
+ public init(dataRepresentation data: D, format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(dataRepresentation: data, format: format)
}
@@ -109,7 +109,7 @@ public extension secp256k1 {
}
/// The associated public key for verifying signatures done with this private key.
- public var publicKey: secp256k1.KeyAgreement.PublicKey {
+ public var publicKey: P256K.KeyAgreement.PublicKey {
PublicKey(baseKey: baseKey.publicKey)
}
@@ -125,7 +125,7 @@ public extension secp256k1 {
// MARK: - secp256k1 + DH
/// An extension to the `secp256k1.KeyAgreement.PrivateKey` conforming to the `DiffieHellmanKeyAgreement` protocol.
-extension secp256k1.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
+extension P256K.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
/// A pointer to a function that hashes an EC point to obtain an ECDH secret.
public typealias HashFunctionType = @convention(c) (
UnsafeMutablePointer?,
@@ -139,7 +139,7 @@ extension secp256k1.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
/// - Parameter publicKeyShare: The public key to perform the ECDH with.
/// - Returns: Returns a shared secret.
/// - Throws: An error occurred while computing the shared secret.
- func sharedSecretFromKeyAgreement(with publicKeyShare: secp256k1.KeyAgreement.PublicKey) throws -> SharedSecret {
+ func sharedSecretFromKeyAgreement(with publicKeyShare: P256K.KeyAgreement.PublicKey) throws -> SharedSecret {
try sharedSecretFromKeyAgreement(with: publicKeyShare, format: .compressed)
}
@@ -151,11 +151,11 @@ extension secp256k1.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
/// - Returns: Returns a shared secret.
/// - Throws: An error occurred while computing the shared secret.
public func sharedSecretFromKeyAgreement(
- with publicKeyShare: secp256k1.KeyAgreement.PublicKey,
- format: secp256k1.Format = .compressed
+ with publicKeyShare: P256K.KeyAgreement.PublicKey,
+ format: P256K.Format = .compressed
) throws -> SharedSecret {
- let context = secp256k1.Context.rawRepresentation
- var publicKey = publicKeyShare.rawRepresentation
+ let context = P256K.Context.rawRepresentation
+ var publicKey = publicKeyShare.baseKey.rawRepresentation
var sharedSecret = [UInt8](repeating: 0, count: format.length)
var data = [UInt8](repeating: format == .compressed ? 1 : 0, count: 1)
@@ -173,15 +173,15 @@ extension secp256k1.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement {
{ output, x32, y32, data in
guard let output, let x32, let y32, let compressed = data?.load(as: Bool.self) else { return 0 }
- let lastByte = y32.advanced(by: secp256k1.ByteLength.dimension - 1).pointee
+ let lastByte = y32.advanced(by: P256K.ByteLength.dimension - 1).pointee
let version: UInt8 = compressed ? (lastByte & 0x01) | 0x02 : 0x04
output.update(repeating: version, count: 1)
- output.advanced(by: 1).update(from: x32, count: secp256k1.ByteLength.dimension)
+ output.advanced(by: 1).update(from: x32, count: P256K.ByteLength.dimension)
if compressed == false {
- output.advanced(by: secp256k1.ByteLength.dimension + 1)
- .update(from: y32, count: secp256k1.ByteLength.dimension)
+ output.advanced(by: P256K.ByteLength.dimension + 1)
+ .update(from: y32, count: P256K.ByteLength.dimension)
}
return 1
diff --git a/Sources/zkp/ECDSA.swift b/Sources/ZKP/ECDSA.swift
similarity index 83%
rename from Sources/zkp/ECDSA.swift
rename to Sources/ZKP/ECDSA.swift
index d3716d9a..ca39a6f3 100644
--- a/Sources/zkp/ECDSA.swift
+++ b/Sources/ZKP/ECDSA.swift
@@ -10,6 +10,12 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
typealias NISTECDSASignature = DERSignature & DataSignature
protocol DataSignature {
@@ -30,7 +36,7 @@ protocol CompactSignature {
// MARK: - secp256k1 + ECDSA Signature
/// An ECDSA (Elliptic Curve Digital Signature Algorithm) Signature
-public extension secp256k1.Signing {
+public extension P256K.Signing {
struct ECDSASignature: ContiguousBytes, NISTECDSASignature, CompactSignature {
/// Returns the data signature.
/// The raw signature format for ECDSA is r || s
@@ -41,7 +47,7 @@ public extension secp256k1.Signing {
/// - dataRepresentation: A data representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
public init(dataRepresentation: D) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -53,7 +59,7 @@ public extension secp256k1.Signing {
/// - dataRepresentation: A data representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
init(_ dataRepresentation: Data) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -64,7 +70,7 @@ public extension secp256k1.Signing {
/// - Parameter derRepresentation: A DER representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with parsing the derRepresentation
public init(derRepresentation: D) throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
let derSignatureBytes = Array(derRepresentation)
var signature = secp256k1_ecdsa_signature()
@@ -84,7 +90,7 @@ public extension secp256k1.Signing {
/// - Parameter derRepresentation: A Compact representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with parsing the derRepresentation
public init(compactRepresentation: D) throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_ecdsa_signature()
guard secp256k1_ecdsa_signature_parse_compact(
@@ -111,9 +117,9 @@ public extension secp256k1.Signing {
/// - Returns: a 64-byte data representation of the compact serialization
public var compactRepresentation: Data {
get throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_ecdsa_signature()
- var compactSignature = [UInt8](repeating: 0, count: secp256k1.ByteLength.signature)
+ var compactSignature = [UInt8](repeating: 0, count: P256K.ByteLength.signature)
dataRepresentation.copyToUnsafeMutableBytes(of: &signature.data)
@@ -125,7 +131,7 @@ public extension secp256k1.Signing {
throw secp256k1Error.underlyingCryptoError
}
- return Data(bytes: &compactSignature, count: secp256k1.ByteLength.signature)
+ return Data(bytes: &compactSignature, count: P256K.ByteLength.signature)
}
}
@@ -134,7 +140,7 @@ public extension secp256k1.Signing {
/// - Returns: a DER representation of the signature
public var derRepresentation: Data {
get throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_ecdsa_signature()
var derSignatureLength = 80
var derSignature = [UInt8](repeating: 0, count: derSignatureLength)
@@ -158,14 +164,14 @@ public extension secp256k1.Signing {
// MARK: - secp256k1 + Signing Key
-extension secp256k1.Signing.PrivateKey: DigestSigner {
+extension P256K.Signing.PrivateKey: DigestSigner {
/// Generates an ECDSA signature over the secp256k1 elliptic curve.
///
/// - Parameter digest: The digest to sign.
/// - Returns: The ECDSA Signature.
/// - Throws: If there is a failure producing the signature
- public func signature(for digest: D) throws -> secp256k1.Signing.ECDSASignature {
- let context = secp256k1.Context.rawRepresentation
+ public func signature(for digest: D) throws -> P256K.Signing.ECDSASignature {
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_ecdsa_signature()
guard secp256k1_ecdsa_sign(
@@ -179,35 +185,35 @@ extension secp256k1.Signing.PrivateKey: DigestSigner {
throw secp256k1Error.underlyingCryptoError
}
- return try secp256k1.Signing.ECDSASignature(signature.dataValue)
+ return try P256K.Signing.ECDSASignature(signature.dataValue)
}
}
-extension secp256k1.Signing.PrivateKey: Signer {
+extension P256K.Signing.PrivateKey: Signer {
/// Generates an ECDSA signature over the secp256k1 elliptic curve.
/// SHA256 is used as the hash function.
///
/// - Parameter data: The data to sign.
/// - Returns: The ECDSA Signature.
/// - Throws: If there is a failure producing the signature.
- public func signature(for data: D) throws -> secp256k1.Signing.ECDSASignature {
+ public func signature(for data: D) throws -> P256K.Signing.ECDSASignature {
try signature(for: SHA256.hash(data: data))
}
}
// MARK: - secp256k1 + Validating Key
-extension secp256k1.Signing.PublicKey: DigestValidator {
+extension P256K.Signing.PublicKey: DigestValidator {
/// Verifies an ECDSA signature over the secp256k1 elliptic curve.
///
/// - Parameters:
/// - signature: The signature to verify
/// - digest: The digest that was signed.
/// - Returns: True if the signature is valid, false otherwise.
- public func isValidSignature(_ signature: secp256k1.Signing.ECDSASignature, for digest: D) -> Bool {
- let context = secp256k1.Context.rawRepresentation
+ public func isValidSignature(_ signature: P256K.Signing.ECDSASignature, for digest: D) -> Bool {
+ let context = P256K.Context.rawRepresentation
var ecdsaSignature = secp256k1_ecdsa_signature()
- var publicKey = rawRepresentation
+ var publicKey = baseKey.rawRepresentation
signature.dataRepresentation.copyToUnsafeMutableBytes(of: &ecdsaSignature.data)
@@ -215,7 +221,7 @@ extension secp256k1.Signing.PublicKey: DigestValidator {
}
}
-extension secp256k1.Signing.PublicKey: DataValidator {
+extension P256K.Signing.PublicKey: DataValidator {
/// Verifies an ECDSA signature over the secp256k1 elliptic curve.
/// SHA256 is used as the hash function.
///
@@ -223,7 +229,7 @@ extension secp256k1.Signing.PublicKey: DataValidator {
/// - signature: The signature to verify
/// - data: The data that was signed.
/// - Returns: True if the signature is valid, false otherwise.
- public func isValidSignature(_ signature: secp256k1.Signing.ECDSASignature, for data: D) -> Bool {
+ public func isValidSignature(_ signature: P256K.Signing.ECDSASignature, for data: D) -> Bool {
isValidSignature(signature, for: SHA256.hash(data: data))
}
}
diff --git a/Sources/zkp/EdDSA.swift b/Sources/ZKP/EdDSA.swift
similarity index 100%
rename from Sources/zkp/EdDSA.swift
rename to Sources/ZKP/EdDSA.swift
diff --git a/Sources/zkp/Errors.swift b/Sources/ZKP/Errors.swift
similarity index 100%
rename from Sources/zkp/Errors.swift
rename to Sources/ZKP/Errors.swift
diff --git a/Sources/zkp/HashDigest.swift b/Sources/ZKP/HashDigest.swift
similarity index 100%
rename from Sources/zkp/HashDigest.swift
rename to Sources/ZKP/HashDigest.swift
diff --git a/Sources/zkp/MuSig.swift b/Sources/ZKP/MuSig.swift
similarity index 84%
rename from Sources/zkp/MuSig.swift
rename to Sources/ZKP/MuSig.swift
index 40872ed6..e4e82a2b 100644
--- a/Sources/zkp/MuSig.swift
+++ b/Sources/ZKP/MuSig.swift
@@ -10,7 +10,13 @@
import Foundation
-public extension secp256k1 {
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
+public extension P256K {
/// MuSig is a multi-signature scheme that allows multiple parties to sign a message using their own private keys,
/// but only reveal their public keys. The aggregated public key is then used to verify the signature.
///
@@ -19,7 +25,7 @@ public extension secp256k1 {
/// Represents a public key in the MuSig scheme.
public struct PublicKey {
/// Generated secp256k1 public key.
- private let baseKey: PublicKeyImplementation
+ internal let baseKey: PublicKeyImplementation
/// The secp256k1 public key object.
var bytes: [UInt8] {
@@ -32,7 +38,7 @@ public extension secp256k1 {
}
/// The key format representation of the public key.
- public var format: secp256k1.Format {
+ public var format: P256K.Format {
baseKey.format
}
@@ -41,11 +47,6 @@ public extension secp256k1 {
baseKey.dataRepresentation
}
- /// A raw representation of the public key.
- public var rawRepresentation: secp256k1_pubkey {
- baseKey.rawRepresentation
- }
-
/// The associated x-only public key for verifying Schnorr signatures.
///
/// - Returns: The associated x-only public key.
@@ -81,7 +82,7 @@ public extension secp256k1 {
/// - Throws: An error if the raw representation does not create a valid public key.
public init(
dataRepresentation data: D,
- format: secp256k1.Format,
+ format: P256K.Format,
cache: [UInt8]
) throws {
self.baseKey = try PublicKeyImplementation(
@@ -144,7 +145,7 @@ public extension secp256k1 {
// MARK: - secp256k1 + MuSig
-extension secp256k1.MuSig {
+extension P256K.MuSig {
/// Aggregates multiple Schnorr public keys into a single Schnorr public key using the MuSig algorithm.
///
/// This function implements the key aggregation process as described in BIP-327.
@@ -152,19 +153,20 @@ extension secp256k1.MuSig {
/// - Parameter pubkeys: An array of Schnorr public keys to aggregate.
/// - Returns: The aggregated Schnorr public key.
/// - Throws: An error if aggregation fails.
- static func aggregate(_ pubkeys: [secp256k1.Schnorr.PublicKey]) throws -> secp256k1.MuSig.PublicKey {
- let context = secp256k1.Context.rawRepresentation
- let format = secp256k1.Format.compressed
+ static func aggregate(_ pubkeys: [P256K.Schnorr.PublicKey]) throws -> P256K.MuSig.PublicKey {
+ let context = P256K.Context.rawRepresentation
+ let format = P256K.Format.compressed
var pubKeyLen = format.length
var aggPubkey = secp256k1_pubkey()
var cache = secp256k1_musig_keyagg_cache()
var pubBytes = [UInt8](repeating: 0, count: pubKeyLen)
- guard PointerArrayUtility.withUnsafePointerArray(pubkeys.map { $0.rawRepresentation }, { pointers in
-#if canImport(zkp_bindings)
+ guard PointerArrayUtility
+ .withUnsafePointerArray(pubkeys.map { $0.baseKey.rawRepresentation }, { pointers in
+#if canImport(libsecp256k1_zkp)
secp256k1_pubkey_sort(context, &pointers, pointers.count).boolValue &&
secp256k1_musig_pubkey_agg(context, nil, nil, &cache, pointers, pointers.count).boolValue
-#elseif canImport(secp256k1_bindings)
+#elseif canImport(libsecp256k1)
secp256k1_ec_pubkey_sort(context, &pointers, pointers.count).boolValue &&
secp256k1_musig_pubkey_agg(context, nil, &cache, pointers, pointers.count).boolValue
#endif
@@ -179,7 +181,7 @@ extension secp256k1.MuSig {
throw secp256k1Error.underlyingCryptoError
}
- return try secp256k1.MuSig.PublicKey(
+ return try P256K.MuSig.PublicKey(
dataRepresentation: pubBytes,
format: format,
cache: Swift.withUnsafeBytes(of: cache.data) { [UInt8]($0) }
@@ -187,7 +189,7 @@ extension secp256k1.MuSig {
}
}
-public extension secp256k1.MuSig.PublicKey {
+public extension P256K.MuSig.PublicKey {
/// Creates a new `PublicKey` by adding a tweak to the public key.
///
/// This function implements the tweaking process for MuSig public keys as described in BIP-327.
@@ -197,8 +199,8 @@ public extension secp256k1.MuSig.PublicKey {
/// - format: The format of the tweaked `PublicKey` object.
/// - Returns: A new tweaked `PublicKey` object.
/// - Throws: An error if tweaking fails.
- func add(_ tweak: [UInt8], format: secp256k1.Format = .compressed) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ func add(_ tweak: [UInt8], format: P256K.Format = .compressed) throws -> Self {
+ let context = P256K.Context.rawRepresentation
var pubKey = secp256k1_pubkey()
var cache = secp256k1_musig_keyagg_cache()
var pubKeyLen = format.length
@@ -221,7 +223,7 @@ public extension secp256k1.MuSig.PublicKey {
}
}
-public extension secp256k1.MuSig.XonlyKey {
+public extension P256K.MuSig.XonlyKey {
/// Creates a new `XonlyKey` by adding a tweak to the x-only public key.
///
/// This function implements the tweaking process for MuSig x-only public keys as described in BIP-327.
@@ -230,11 +232,11 @@ public extension secp256k1.MuSig.XonlyKey {
/// - Returns: A new tweaked `XonlyKey` object.
/// - Throws: An error if tweaking fails.
func add(_ tweak: [UInt8]) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var pubKey = secp256k1_pubkey()
var cache = secp256k1_musig_keyagg_cache()
var outXonlyPubKey = secp256k1_xonly_pubkey()
- var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.Schnorr.xonlyByteCount)
+ var xonlyBytes = [UInt8](repeating: 0, count: P256K.Schnorr.xonlyByteCount)
var keyParity = Int32()
self.cache.copyToUnsafeMutableBytes(of: &cache.data)
@@ -255,7 +257,7 @@ public extension secp256k1.MuSig.XonlyKey {
}
/// A Schnorr (Schnorr Digital Signature Scheme) Signature
-public extension secp256k1.Schnorr {
+public extension P256K.Schnorr {
struct PartialSignature: ContiguousBytes {
/// Returns the raw signature in a fixed 64-byte format.
public var dataRepresentation: Data
@@ -269,7 +271,7 @@ public extension secp256k1.Schnorr {
/// - session: The MuSig session data.
/// - Throws: An error if the data is invalid.
public init(dataRepresentation: D, session: D) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -282,7 +284,7 @@ public extension secp256k1.Schnorr {
/// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
init(_ dataRepresentation: Data, session: Data) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.partialSignature else {
+ guard dataRepresentation.count == P256K.ByteLength.partialSignature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -300,7 +302,7 @@ public extension secp256k1.Schnorr {
}
}
-extension secp256k1.MuSig.PublicKey {
+extension P256K.MuSig.PublicKey {
/// Verifies a partial signature against this public key.
///
/// This function implements the partial signature verification process as described in BIP-327.
@@ -312,15 +314,15 @@ extension secp256k1.MuSig.PublicKey {
/// - digest: The message digest being signed.
/// - Returns: `true` if the partial signature is valid, `false` otherwise.
public func isValidSignature(
- _ partialSignature: secp256k1.Schnorr.PartialSignature,
- publicKey: secp256k1.Schnorr.PublicKey,
- nonce: secp256k1.Schnorr.Nonce,
+ _ partialSignature: P256K.Schnorr.PartialSignature,
+ publicKey: P256K.Schnorr.PublicKey,
+ nonce: P256K.Schnorr.Nonce,
for digest: D
) -> Bool {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var partialSig = secp256k1_musig_partial_sig()
var pubnonce = secp256k1_musig_pubnonce()
- var publicKey = publicKey.rawRepresentation
+ var publicKey = publicKey.baseKey.rawRepresentation
var cache = secp256k1_musig_keyagg_cache()
var session = secp256k1_musig_session()
@@ -343,7 +345,7 @@ extension secp256k1.MuSig.PublicKey {
}
}
-extension secp256k1.Schnorr.PrivateKey {
+extension P256K.Schnorr.PrivateKey {
/// Generates a partial signature for MuSig.
///
/// This function implements the partial signing process as described in BIP-327.
@@ -358,19 +360,19 @@ extension secp256k1.Schnorr.PrivateKey {
/// - Throws: An error if partial signature generation fails.
public func partialSignature(
for digest: D,
- pubnonce: secp256k1.Schnorr.Nonce,
- secureNonce: consuming secp256k1.Schnorr.SecureNonce,
- publicNonceAggregate: secp256k1.MuSig.Nonce,
- publicKeyAggregate: secp256k1.MuSig.PublicKey
- ) throws -> secp256k1.Schnorr.PartialSignature {
- let context = secp256k1.Context.rawRepresentation
+ pubnonce: P256K.Schnorr.Nonce,
+ secureNonce: consuming P256K.Schnorr.SecureNonce,
+ publicNonceAggregate: P256K.MuSig.Nonce,
+ publicKeyAggregate: P256K.MuSig.PublicKey
+ ) throws -> P256K.Schnorr.PartialSignature {
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_musig_partial_sig()
var secnonce = secp256k1_musig_secnonce()
var keypair = secp256k1_keypair()
var cache = secp256k1_musig_keyagg_cache()
var session = secp256k1_musig_session()
var aggnonce = secp256k1_musig_aggnonce()
- var partialSignature = [UInt8](repeating: 0, count: secp256k1.ByteLength.partialSignature)
+ var partialSignature = [UInt8](repeating: 0, count: P256K.ByteLength.partialSignature)
guard secp256k1_keypair_create(context, &keypair, Array(dataRepresentation)).boolValue else {
throw secp256k1Error.underlyingCryptoError
@@ -380,14 +382,14 @@ extension secp256k1.Schnorr.PrivateKey {
publicKeyAggregate.keyAggregationCache.copyToUnsafeMutableBytes(of: &cache.data)
publicNonceAggregate.aggregatedNonce.copyToUnsafeMutableBytes(of: &aggnonce.data)
-#if canImport(zkp_bindings)
+#if canImport(libsecp256k1_zkp)
guard secp256k1_musig_nonce_process(context, &session, &aggnonce, Array(digest), &cache, nil).boolValue,
secp256k1_musig_partial_sign(context, &signature, &secnonce, &keypair, &cache, &session).boolValue,
secp256k1_musig_partial_sig_serialize(context, &partialSignature, &signature).boolValue
else {
throw secp256k1Error.underlyingCryptoError
}
-#else
+#elseif canImport(libsecp256k1)
guard secp256k1_musig_nonce_process(context, &session, &aggnonce, Array(digest), &cache).boolValue,
secp256k1_musig_partial_sign(context, &signature, &secnonce, &keypair, &cache, &session).boolValue,
secp256k1_musig_partial_sig_serialize(context, &partialSignature, &signature).boolValue
@@ -396,8 +398,8 @@ extension secp256k1.Schnorr.PrivateKey {
}
#endif
- return try secp256k1.Schnorr.PartialSignature(
- Data(bytes: &partialSignature, count: secp256k1.ByteLength.partialSignature),
+ return try P256K.Schnorr.PartialSignature(
+ Data(bytes: &partialSignature, count: P256K.ByteLength.partialSignature),
session: session.dataValue
)
}
@@ -416,11 +418,11 @@ extension secp256k1.Schnorr.PrivateKey {
/// - Throws: An error if partial signature generation fails.
public func partialSignature(
for data: D,
- pubnonce: secp256k1.Schnorr.Nonce,
- secureNonce: consuming secp256k1.Schnorr.SecureNonce,
- publicNonceAggregate: secp256k1.MuSig.Nonce,
- publicKeyAggregate: secp256k1.MuSig.PublicKey
- ) throws -> secp256k1.Schnorr.PartialSignature {
+ pubnonce: P256K.Schnorr.Nonce,
+ secureNonce: consuming P256K.Schnorr.SecureNonce,
+ publicNonceAggregate: P256K.MuSig.Nonce,
+ publicKeyAggregate: P256K.MuSig.PublicKey
+ ) throws -> P256K.Schnorr.PartialSignature {
try partialSignature(
for: SHA256.hash(data: data),
pubnonce: pubnonce,
@@ -432,7 +434,7 @@ extension secp256k1.Schnorr.PrivateKey {
}
/// An extension for secp256k1_musig_partial_sig providing a convenience property.
-public extension secp256k1_musig_partial_sig {
+internal extension secp256k1_musig_partial_sig {
/// A property that returns the Data representation of the `secp256k1_musig_partial_sig` object.
var dataValue: Data {
var mutableSig = self
@@ -441,7 +443,7 @@ public extension secp256k1_musig_partial_sig {
}
/// An extension for secp256k1_musig_session providing a convenience property.
-public extension secp256k1_musig_session {
+internal extension secp256k1_musig_session {
var dataValue: Data {
var mutableSession = self
return Data(bytes: &mutableSession.data, count: MemoryLayout.size(ofValue: data))
@@ -449,7 +451,7 @@ public extension secp256k1_musig_session {
}
/// A Schnorr (Schnorr Digital Signature Scheme) Signature
-public extension secp256k1.MuSig {
+public extension P256K.MuSig {
struct AggregateSignature: ContiguousBytes, DataSignature {
/// Returns the raw signature in a fixed 64-byte format.
public var dataRepresentation: Data
@@ -459,7 +461,7 @@ public extension secp256k1.MuSig {
/// - dataRepresentation: A raw representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the rawRepresentation count
public init(dataRepresentation: D) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -471,7 +473,7 @@ public extension secp256k1.MuSig {
/// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
init(_ dataRepresentation: Data) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -489,17 +491,17 @@ public extension secp256k1.MuSig {
}
}
-extension secp256k1.MuSig {
+extension P256K.MuSig {
/// Aggregates partial signatures into a complete signature.
///
/// - Parameter partialSignatures: An array of partial signatures to aggregate.
/// - Returns: The aggregated Schnorr signature.
/// - Throws: If there is a failure aggregating the signatures.
public static func aggregateSignatures(
- _ partialSignatures: [secp256k1.Schnorr.PartialSignature]
- ) throws -> secp256k1.MuSig.AggregateSignature {
- let context = secp256k1.Context.rawRepresentation
- var signature = [UInt8](repeating: 0, count: secp256k1.ByteLength.signature)
+ _ partialSignatures: [P256K.Schnorr.PartialSignature]
+ ) throws -> P256K.MuSig.AggregateSignature {
+ let context = P256K.Context.rawRepresentation
+ var signature = [UInt8](repeating: 0, count: P256K.ByteLength.signature)
var session = secp256k1_musig_session()
partialSignatures.first?.session.copyToUnsafeMutableBytes(of: &session.data)
@@ -507,14 +509,14 @@ extension secp256k1.MuSig {
guard PointerArrayUtility.withUnsafePointerArray(
partialSignatures.map {
var partialSig = secp256k1_musig_partial_sig()
- secp256k1_musig_partial_sig_parse(context, &partialSig, Array($0.dataRepresentation))
+ _ = secp256k1_musig_partial_sig_parse(context, &partialSig, Array($0.dataRepresentation))
return partialSig
}, { pointers in
secp256k1_musig_partial_sig_agg(context, &signature, &session, pointers, pointers.count).boolValue
}) else {
throw secp256k1Error.underlyingCryptoError
}
-
- return try secp256k1.MuSig.AggregateSignature(Data(signature))
+
+ return try P256K.MuSig.AggregateSignature(Data(signature))
}
}
diff --git a/Sources/zkp/Nonces.swift b/Sources/ZKP/Nonces.swift
similarity index 87%
rename from Sources/zkp/Nonces.swift
rename to Sources/ZKP/Nonces.swift
index 06b70b48..b301dd7d 100644
--- a/Sources/zkp/Nonces.swift
+++ b/Sources/ZKP/Nonces.swift
@@ -10,7 +10,13 @@
import Foundation
-public extension secp256k1.MuSig {
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
+public extension P256K.MuSig {
/// Represents an aggregated nonce for MuSig operations.
///
/// This struct is used in the MuSig multi-signature scheme to handle nonce aggregation.
@@ -22,8 +28,8 @@ public extension secp256k1.MuSig {
///
/// - Parameter pubnonces: An array of public nonces to aggregate.
/// - Throws: An error if nonce aggregation fails.
- public init(aggregating pubnonces: [secp256k1.Schnorr.Nonce]) throws {
- let context = secp256k1.Context.rawRepresentation
+ public init(aggregating pubnonces: [P256K.Schnorr.Nonce]) throws {
+ let context = P256K.Context.rawRepresentation
var aggNonce = secp256k1_musig_aggnonce()
guard PointerArrayUtility.withUnsafePointerArray(
@@ -68,8 +74,8 @@ public extension secp256k1.MuSig {
/// - Returns: A `NonceResult` containing the generated public and secret nonces.
/// - Throws: An error if nonce generation fails.
public static func generate(
- secretKey: secp256k1.Schnorr.PrivateKey?,
- publicKey: secp256k1.Schnorr.PublicKey,
+ secretKey: P256K.Schnorr.PrivateKey?,
+ publicKey: P256K.Schnorr.PublicKey,
msg32: [UInt8],
extraInput32: [UInt8]? = nil
) throws -> NonceResult {
@@ -97,15 +103,15 @@ public extension secp256k1.MuSig {
/// - Throws: An error if nonce generation fails.
public static func generate(
sessionID: [UInt8],
- secretKey: secp256k1.Schnorr.PrivateKey?,
- publicKey: secp256k1.Schnorr.PublicKey,
+ secretKey: P256K.Schnorr.PrivateKey?,
+ publicKey: P256K.Schnorr.PublicKey,
msg32: [UInt8],
extraInput32: [UInt8]?
) throws -> NonceResult {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var secnonce = secp256k1_musig_secnonce()
var pubnonce = secp256k1_musig_pubnonce()
- var pubkey = publicKey.rawRepresentation
+ var pubkey = publicKey.baseKey.rawRepresentation
#if canImport(zkp_bindings)
guard secp256k1_musig_nonce_gen(
@@ -140,8 +146,8 @@ public extension secp256k1.MuSig {
#endif
return NonceResult(
- pubnonce: secp256k1.Schnorr.Nonce(pubnonce: Swift.withUnsafeBytes(of: pubnonce) { Data($0) }),
- secnonce: secp256k1.Schnorr.SecureNonce(Swift.withUnsafeBytes(of: secnonce) { Data($0) })
+ pubnonce: P256K.Schnorr.Nonce(pubnonce: Swift.withUnsafeBytes(of: pubnonce) { Data($0) }),
+ secnonce: P256K.Schnorr.SecureNonce(Swift.withUnsafeBytes(of: secnonce) { Data($0) })
)
}
}
@@ -149,13 +155,13 @@ public extension secp256k1.MuSig {
/// Represents the result of nonce generation, containing both public and secret nonces.
@frozen struct NonceResult: ~Copyable {
/// The public nonce.
- let pubnonce: secp256k1.Schnorr.Nonce
+ let pubnonce: P256K.Schnorr.Nonce
/// The secret nonce.
- let secnonce: secp256k1.Schnorr.SecureNonce
+ let secnonce: P256K.Schnorr.SecureNonce
}
}
-public extension secp256k1.Schnorr {
+public extension P256K.Schnorr {
/// Represents a secure nonce used for MuSig operations.
///
/// This struct is used to handle secure nonces in the MuSig signing process.
diff --git a/Sources/zkp/secp256k1.swift b/Sources/ZKP/P256K.swift
similarity index 88%
rename from Sources/zkp/secp256k1.swift
rename to Sources/ZKP/P256K.swift
index 745e3482..3ca019a3 100644
--- a/Sources/zkp/secp256k1.swift
+++ b/Sources/ZKP/P256K.swift
@@ -1,5 +1,5 @@
//
-// secp256k1.swift
+// P256K.swift
// GigaBitcoin/secp256k1.swift
//
// Copyright (c) 2021 GigaBitcoin LLC
@@ -10,11 +10,17 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
/// The secp256k1 Elliptic Curve.
-public enum secp256k1 {}
+public enum P256K {}
/// An extension to secp256k1 containing an enum for public key formats.
-public extension secp256k1 {
+public extension P256K {
/// Enum representing public key formats to be passed to `secp256k1_ec_pubkey_serialize`.
enum Format: UInt32 {
/// Compressed public key format.
@@ -25,8 +31,8 @@ public extension secp256k1 {
/// The length of the public key in bytes, based on the format.
public var length: Int {
switch self {
- case .compressed: return secp256k1.ByteLength.dimension + 1
- case .uncompressed: return 2 * secp256k1.ByteLength.dimension + 1
+ case .compressed: return P256K.ByteLength.dimension + 1
+ case .uncompressed: return 2 * P256K.ByteLength.dimension + 1
}
}
@@ -45,7 +51,7 @@ public extension secp256k1 {
}
/// An extension for secp256k1 containing nested enum byte length details.
-extension secp256k1 {
+extension P256K {
/// An enum containing byte details about in secp256k1.
@usableFromInline
enum ByteLength {
@@ -86,7 +92,7 @@ extension secp256k1 {
@usableFromInline let xonlyBytes: [UInt8]
/// Backing public key format
- @usableFromInline let format: secp256k1.Format
+ @usableFromInline let format: P256K.Format
/// Backing key parity
@usableFromInline var keyParity: Int32
@@ -100,7 +106,7 @@ extension secp256k1 {
@usableFromInline var negation: Self {
get throws {
var privateBytes = privateBytes.bytes
- guard secp256k1_ec_seckey_negate(secp256k1.Context.rawRepresentation, &privateBytes).boolValue else {
+ guard secp256k1_ec_seckey_negate(P256K.Context.rawRepresentation, &privateBytes).boolValue else {
throw secp256k1Error.underlyingCryptoError
}
@@ -114,8 +120,8 @@ extension secp256k1 {
}
/// Backing initialization that creates a random secp256k1 private key for signing
- @usableFromInline init(format: secp256k1.Format = .compressed) throws {
- let privateKey = SecureBytes(count: secp256k1.ByteLength.privateKey)
+ @usableFromInline init(format: P256K.Format = .compressed) throws {
+ let privateKey = SecureBytes(count: P256K.ByteLength.privateKey)
self.keyParity = 0
self.format = format
self.privateBytes = privateKey
@@ -132,7 +138,7 @@ extension secp256k1 {
/// - Throws: An error is thrown when the raw representation does not create a private key for signing.
init(
dataRepresentation data: D,
- format: secp256k1.Format = .compressed
+ format: P256K.Format = .compressed
) throws {
let privateKey = SecureBytes(bytes: data)
// Verify Private Key here
@@ -160,7 +166,7 @@ extension secp256k1 {
@usableFromInline let keyParity: Int32
/// A key format representation of the backing public key
- @usableFromInline let format: secp256k1.Format
+ @usableFromInline let format: P256K.Format
/// Backing cache for information about public key aggregation.
@usableFromInline let cache: [UInt8]
@@ -176,16 +182,16 @@ extension secp256k1 {
}
/// A raw representation of the backing public key
- @usableFromInline var rawRepresentation: secp256k1_pubkey {
+ var rawRepresentation: secp256k1_pubkey {
var pubKey = secp256k1_pubkey()
- _ = secp256k1_ec_pubkey_parse(secp256k1.Context.rawRepresentation, &pubKey, bytes, bytes.count)
+ _ = secp256k1_ec_pubkey_parse(P256K.Context.rawRepresentation, &pubKey, bytes, bytes.count)
return pubKey
}
/// Negates a public key in place.
@usableFromInline var negation: Self {
get throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var key = rawRepresentation
var keyLength = format.length
var bytes = [UInt8](repeating: 0, count: keyLength)
@@ -205,7 +211,7 @@ extension secp256k1 {
/// - format: an enum that represents the format of the public key
@usableFromInline init(
dataRepresentation data: D,
- format: secp256k1.Format,
+ format: P256K.Format,
cache: [UInt8] = []
) throws {
var keyParity = Int32()
@@ -228,7 +234,7 @@ extension secp256k1 {
_ bytes: [UInt8],
xonly: [UInt8],
keyParity: Int32,
- format: secp256k1.Format,
+ format: P256K.Format,
cache: [UInt8] = []
) {
self.bytes = bytes
@@ -258,10 +264,10 @@ extension secp256k1 {
/// - Throws: An error is thrown when a public key is not recoverable from the signature.
@usableFromInline init(
_ digest: D,
- signature: secp256k1.Recovery.ECDSASignature,
- format: secp256k1.Format
+ signature: P256K.Recovery.ECDSASignature,
+ format: P256K.Format
) throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var keyParity = Int32()
var pubKeyLen = format.length
var pubKey = secp256k1_pubkey()
@@ -293,13 +299,13 @@ extension secp256k1 {
/// - Throws: An error is thrown when the bytes does not create a public key.
static func generate(
bytes privateBytes: inout SecureBytes,
- format: secp256k1.Format
+ format: P256K.Format
) throws -> [UInt8] {
- guard privateBytes.count == secp256k1.ByteLength.privateKey else {
+ guard privateBytes.count == P256K.ByteLength.privateKey else {
throw secp256k1Error.incorrectKeySize
}
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var pubKeyLen = format.length
var pubKey = secp256k1_pubkey()
var pubBytes = [UInt8](repeating: 0, count: pubKeyLen)
@@ -332,7 +338,7 @@ extension secp256k1 {
}
/// A raw representation of the backing x-only public key
- @usableFromInline var rawRepresentation: secp256k1_xonly_pubkey {
+ var rawRepresentation: secp256k1_xonly_pubkey {
var xonlyKey = secp256k1_xonly_pubkey()
dataRepresentation.copyToUnsafeMutableBytes(of: &xonlyKey.data)
return xonlyKey
@@ -369,16 +375,16 @@ extension secp256k1 {
static func generate(
bytes publicBytes: [UInt8],
keyParity: inout Int32,
- format: secp256k1.Format
+ format: P256K.Format
) throws -> [UInt8] {
guard publicBytes.count == format.length else {
throw secp256k1Error.incorrectKeySize
}
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var pubKey = secp256k1_pubkey()
var xonlyPubKey = secp256k1_xonly_pubkey()
- var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.ByteLength.privateKey)
+ var xonlyBytes = [UInt8](repeating: 0, count: P256K.ByteLength.privateKey)
guard secp256k1_ec_pubkey_parse(context, &pubKey, publicBytes, format.length).boolValue,
secp256k1_xonly_pubkey_from_pubkey(context, &xonlyPubKey, &keyParity, &pubKey).boolValue,
diff --git a/Sources/zkp/PrettyBytes.swift b/Sources/ZKP/PrettyBytes.swift
similarity index 100%
rename from Sources/zkp/PrettyBytes.swift
rename to Sources/ZKP/PrettyBytes.swift
diff --git a/Sources/zkp/RNG_boring.swift b/Sources/ZKP/RNG_boring.swift
similarity index 100%
rename from Sources/zkp/RNG_boring.swift
rename to Sources/ZKP/RNG_boring.swift
diff --git a/Sources/zkp/Recovery.swift b/Sources/ZKP/Recovery.swift
similarity index 85%
rename from Sources/zkp/Recovery.swift
rename to Sources/ZKP/Recovery.swift
index ce3dcd21..ef1617a6 100644
--- a/Sources/zkp/Recovery.swift
+++ b/Sources/ZKP/Recovery.swift
@@ -10,10 +10,16 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
// MARK: - secp256k1 + Recovery
/// An extension for secp256k1 with a nested Recovery enum.
-public extension secp256k1 {
+public extension P256K {
enum Recovery {
/// A representation of a secp256k1 private key used for signing.
public struct PrivateKey: Equatable {
@@ -36,7 +42,7 @@ public extension secp256k1 {
///
/// - Parameter format: The key format, default is .compressed.
/// - Throws: An error if the private key cannot be generated.
- public init(format: secp256k1.Format = .compressed) throws {
+ public init(format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(format: format)
}
@@ -45,7 +51,7 @@ public extension secp256k1 {
/// - Parameter data: A data representation of the key.
/// - Parameter format: The key format, default is .compressed.
/// - Throws: An error if the raw representation does not create a private key for signing.
- public init(dataRepresentation data: D, format: secp256k1.Format = .compressed) throws {
+ public init(dataRepresentation data: D, format: P256K.Format = .compressed) throws {
self.baseKey = try PrivateKeyImplementation(dataRepresentation: data, format: format)
}
@@ -62,15 +68,12 @@ public extension secp256k1 {
/// A struct representing a secp256k1 public key for recovery purposes.
public struct PublicKey {
+ /// Generated secp256k1 Public Key.
+ internal let baseKey: PublicKeyImplementation
+
/// A data representation of the public key.
public var dataRepresentation: Data { baseKey.dataRepresentation }
- /// A raw representation of the public key.
- public var rawRepresentation: secp256k1_pubkey { baseKey.rawRepresentation }
-
- /// Generated secp256k1 Public Key.
- private let baseKey: PublicKeyImplementation
-
/// Initializes a secp256k1 public key using a data message and a recovery signature.
/// - Parameters:
/// - data: The data to be hash and assumed signed.
@@ -78,8 +81,8 @@ public extension secp256k1 {
/// - format: The format of the public key object.
public init(
_ data: D,
- signature: secp256k1.Recovery.ECDSASignature,
- format: secp256k1.Format = .compressed
+ signature: P256K.Recovery.ECDSASignature,
+ format: P256K.Format = .compressed
) throws {
self.baseKey = try PublicKeyImplementation(
SHA256.hash(data: data),
@@ -95,8 +98,8 @@ public extension secp256k1 {
/// - format: The format of the public key object.
public init(
_ digest: D,
- signature: secp256k1.Recovery.ECDSASignature,
- format: secp256k1.Format = .compressed
+ signature: P256K.Recovery.ECDSASignature,
+ format: P256K.Format = .compressed
) throws {
self.baseKey = try PublicKeyImplementation(digest, signature: signature, format: format)
}
@@ -111,7 +114,7 @@ public extension secp256k1 {
}
/// An ECDSA (Elliptic Curve Digital Signature Algorithm) Recovery Signature
-public extension secp256k1.Recovery {
+public extension P256K.Recovery {
/// Recovery Signature
struct ECDSACompactSignature {
public let signature: Data
@@ -127,10 +130,10 @@ public extension secp256k1.Recovery {
/// - Returns: a 64-byte data representation of the compact serialization
public var compactRepresentation: ECDSACompactSignature {
get throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var recoveryId = Int32()
var recoverableSignature = secp256k1_ecdsa_recoverable_signature()
- var compactSignature = [UInt8](repeating: 0, count: secp256k1.ByteLength.signature)
+ var compactSignature = [UInt8](repeating: 0, count: P256K.ByteLength.signature)
dataRepresentation.copyToUnsafeMutableBytes(of: &recoverableSignature.data)
@@ -143,17 +146,17 @@ public extension secp256k1.Recovery {
throw secp256k1Error.underlyingCryptoError
}
- return secp256k1.Recovery.ECDSACompactSignature(
- signature: Data(bytes: &compactSignature, count: secp256k1.ByteLength.signature),
+ return P256K.Recovery.ECDSACompactSignature(
+ signature: Data(bytes: &compactSignature, count: P256K.ByteLength.signature),
recoveryId: recoveryId
)
}
}
/// Convert a recoverable signature into a normal signature.
- public var normalize: secp256k1.Signing.ECDSASignature {
+ public var normalize: P256K.Signing.ECDSASignature {
get throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var normalizedSignature = secp256k1_ecdsa_signature()
var recoverableSignature = secp256k1_ecdsa_recoverable_signature()
@@ -167,7 +170,7 @@ public extension secp256k1.Recovery {
throw secp256k1Error.underlyingCryptoError
}
- return try secp256k1.Signing.ECDSASignature(normalizedSignature.dataValue)
+ return try P256K.Signing.ECDSASignature(normalizedSignature.dataValue)
}
}
@@ -176,7 +179,7 @@ public extension secp256k1.Recovery {
/// - dataRepresentation: A data representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
public init(dataRepresentation: D) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature + 1 else {
+ guard dataRepresentation.count == P256K.ByteLength.signature + 1 else {
throw secp256k1Error.incorrectParameterSize
}
@@ -188,7 +191,7 @@ public extension secp256k1.Recovery {
/// - dataRepresentation: A data representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
init(_ dataRepresentation: Data) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature + 1 else {
+ guard dataRepresentation.count == P256K.ByteLength.signature + 1 else {
throw secp256k1Error.incorrectParameterSize
}
@@ -199,7 +202,7 @@ public extension secp256k1.Recovery {
/// - Parameter compactRepresentation: A Compact representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with parsing the derRepresentation
public init(compactRepresentation: D, recoveryId: Int32) throws {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var recoverableSignature = secp256k1_ecdsa_recoverable_signature()
guard secp256k1_ecdsa_recoverable_signature_parse_compact(
@@ -226,8 +229,8 @@ public extension secp256k1.Recovery {
// MARK: - secp256k1 + Recovery
-extension secp256k1.Recovery.PrivateKey: DigestSigner {
- public typealias Signature = secp256k1.Recovery.ECDSASignature
+extension P256K.Recovery.PrivateKey: DigestSigner {
+ public typealias Signature = P256K.Recovery.ECDSASignature
/// Generates a recoverable ECDSA signature.
///
@@ -235,7 +238,7 @@ extension secp256k1.Recovery.PrivateKey: DigestSigner {
/// - Returns: The recoverable ECDSA Signature.
/// - Throws: If there is a failure producing the signature
public func signature(for digest: D) throws -> Signature {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var signature = secp256k1_ecdsa_recoverable_signature()
guard secp256k1_ecdsa_sign_recoverable(
@@ -249,11 +252,11 @@ extension secp256k1.Recovery.PrivateKey: DigestSigner {
throw secp256k1Error.underlyingCryptoError
}
- return try secp256k1.Recovery.ECDSASignature(signature.dataValue)
+ return try P256K.Recovery.ECDSASignature(signature.dataValue)
}
}
-extension secp256k1.Recovery.PrivateKey: Signer {
+extension P256K.Recovery.PrivateKey: Signer {
/// Generates a recoverable ECDSA signature. SHA256 is used as the hash function.
///
/// - Parameter data: The data to sign.
diff --git a/Sources/zkp/SHA256.swift b/Sources/ZKP/SHA256.swift
similarity index 88%
rename from Sources/zkp/SHA256.swift
rename to Sources/ZKP/SHA256.swift
index cf4dee57..276554dc 100644
--- a/Sources/zkp/SHA256.swift
+++ b/Sources/ZKP/SHA256.swift
@@ -10,6 +10,12 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
/// The SHA256 hashing algorithm.
public enum SHA256 {
/// The number of bytes in a SHA256 digest.
@@ -37,7 +43,7 @@ public enum SHA256 {
/// - Throws: An error if the tagged hash computation fails.
/// - Returns: The computed digest.
public static func taggedHash(tag: D, data: D) throws -> SHA256Digest {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
let tagBytes = Array(tag)
let messageBytes = Array(data)
var output = [UInt8](repeating: 0, count: Self.digestByteCount)
diff --git a/Sources/zkp/SafeCompare.swift b/Sources/ZKP/SafeCompare.swift
similarity index 100%
rename from Sources/zkp/SafeCompare.swift
rename to Sources/ZKP/SafeCompare.swift
diff --git a/Sources/zkp/Schnorr.swift b/Sources/ZKP/Schnorr.swift
similarity index 89%
rename from Sources/zkp/Schnorr.swift
rename to Sources/ZKP/Schnorr.swift
index 9b65ed40..fb3d8b07 100644
--- a/Sources/zkp/Schnorr.swift
+++ b/Sources/ZKP/Schnorr.swift
@@ -10,7 +10,13 @@
import Foundation
-public extension secp256k1 {
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
+public extension P256K {
enum Schnorr {
/// Fixed number of bytes for Schnorr signature
///
@@ -32,7 +38,7 @@ public extension secp256k1 {
}
/// An elliptic curve that enables secp256k1 signatures and key agreement.
-public extension secp256k1.Schnorr {
+public extension P256K.Schnorr {
/// A representation of a secp256k1 private key used for signing.
struct PrivateKey: Equatable {
/// Generated secp256k1 Signing Key.
@@ -95,7 +101,7 @@ public extension secp256k1.Schnorr {
/// The corresponding public key for the secp256k1 curve.
struct PublicKey {
/// Generated secp256k1 public key.
- private let baseKey: PublicKeyImplementation
+ internal let baseKey: PublicKeyImplementation
/// The secp256k1 public key object.
var bytes: [UInt8] {
@@ -103,7 +109,7 @@ public extension secp256k1.Schnorr {
}
/// The key format representation of the public key.
- public var format: secp256k1.Format {
+ public var format: P256K.Format {
baseKey.format
}
@@ -112,11 +118,6 @@ public extension secp256k1.Schnorr {
baseKey.dataRepresentation
}
- /// A raw representation of the public key.
- public var rawRepresentation: secp256k1_pubkey {
- baseKey.rawRepresentation
- }
-
/// The associated x-only public key for verifying Schnorr signatures.
///
/// - Returns: The associated x-only public key.
@@ -149,7 +150,7 @@ public extension secp256k1.Schnorr {
/// - Throws: An error if the raw representation does not create a public key.
public init(
dataRepresentation data: D,
- format: secp256k1.Format
+ format: P256K.Format
) throws {
self.baseKey = try PublicKeyImplementation(
dataRepresentation: data,
@@ -208,7 +209,7 @@ public extension secp256k1.Schnorr {
// MARK: - Schnorr Signatures
/// A Schnorr (Schnorr Digital Signature Scheme) Signature
-public extension secp256k1.Schnorr {
+public extension P256K.Schnorr {
struct SchnorrSignature: ContiguousBytes, DataSignature {
/// Returns the raw signature in a fixed 64-byte format.
public var dataRepresentation: Data
@@ -218,7 +219,7 @@ public extension secp256k1.Schnorr {
/// - dataRepresentation: A raw representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the rawRepresentation count
public init(dataRepresentation: D) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -230,7 +231,7 @@ public extension secp256k1.Schnorr {
/// - rawRepresentation: A raw representation of the key as a collection of contiguous bytes.
/// - Throws: If there is a failure with the dataRepresentation count
init(_ dataRepresentation: Data) throws {
- guard dataRepresentation.count == secp256k1.ByteLength.signature else {
+ guard dataRepresentation.count == P256K.ByteLength.signature else {
throw secp256k1Error.incorrectParameterSize
}
@@ -250,7 +251,7 @@ public extension secp256k1.Schnorr {
// MARK: - secp256k1 + Schnorr
-extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
+extension P256K.Schnorr.PrivateKey: DigestSigner, Signer {
/// Generates an Schnorr signature from a hash of a variable length data object
///
/// This function uses SHA256 to create a hash of the variable length the data argument to ensure only 32-byte messages are signed.
@@ -262,8 +263,8 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
/// - data: The data object to hash and sign.
/// - Returns: The Schnorr Signature.
/// - Throws: If there is a failure producing the signature.
- public func signature(for data: D) throws -> secp256k1.Schnorr.SchnorrSignature {
- try signature(for: data, auxiliaryRand: SecureBytes(count: secp256k1.ByteLength.dimension).bytes)
+ public func signature(for data: D) throws -> P256K.Schnorr.SchnorrSignature {
+ try signature(for: data, auxiliaryRand: SecureBytes(count: P256K.ByteLength.dimension).bytes)
}
/// Generates an Schnorr signature from the hash digest object
@@ -277,8 +278,8 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
/// - digest: The digest to sign.
/// - Returns: The Schnorr Signature.
/// - Throws: If there is a failure producing the signature.
- public func signature(for digest: D) throws -> secp256k1.Schnorr.SchnorrSignature {
- try signature(for: digest, auxiliaryRand: SecureBytes(count: secp256k1.ByteLength.dimension).bytes)
+ public func signature(for digest: D) throws -> P256K.Schnorr.SchnorrSignature {
+ try signature(for: digest, auxiliaryRand: SecureBytes(count: P256K.ByteLength.dimension).bytes)
}
/// Generates an Schnorr signature from a hash of a variable length data object
@@ -293,7 +294,7 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
/// - auxiliaryRand: Auxiliary randomness.
/// - Returns: The Schnorr Signature.
/// - Throws: If there is a failure producing the signature.
- public func signature(for data: D, auxiliaryRand: [UInt8]) throws -> secp256k1.Schnorr.SchnorrSignature {
+ public func signature(for data: D, auxiliaryRand: [UInt8]) throws -> P256K.Schnorr.SchnorrSignature {
try signature(for: SHA256.hash(data: data), auxiliaryRand: auxiliaryRand)
}
@@ -309,7 +310,7 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
/// - auxiliaryRand: Auxiliary randomness; BIP340 requires 32-bytes.
/// - Returns: The Schnorr Signature.
/// - Throws: If there is a failure producing the signature.
- public func signature(for digest: D, auxiliaryRand: [UInt8]) throws -> secp256k1.Schnorr.SchnorrSignature {
+ public func signature(for digest: D, auxiliaryRand: [UInt8]) throws -> P256K.Schnorr.SchnorrSignature {
var hashDataBytes = Array(digest).bytes
var randomBytes = auxiliaryRand
@@ -332,15 +333,15 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
message: inout [UInt8],
auxiliaryRand: UnsafeMutableRawPointer?,
strict: Bool = false
- ) throws -> secp256k1.Schnorr.SchnorrSignature {
- guard strict == false || message.count == secp256k1.ByteLength.dimension else {
+ ) throws -> P256K.Schnorr.SchnorrSignature {
+ guard strict == false || message.count == P256K.ByteLength.dimension else {
throw secp256k1Error.incorrectParameterSize
}
- let context = secp256k1.Context.rawRepresentation
- let magic = secp256k1.Schnorr.magic
+ let context = P256K.Context.rawRepresentation
+ let magic = P256K.Schnorr.magic
var keypair = secp256k1_keypair()
- var signature = [UInt8](repeating: 0, count: secp256k1.ByteLength.signature)
+ var signature = [UInt8](repeating: 0, count: P256K.ByteLength.signature)
var extraParams = secp256k1_schnorrsig_extraparams(magic: magic, noncefp: nil, ndata: auxiliaryRand)
guard secp256k1_keypair_create(context, &keypair, Array(dataRepresentation)).boolValue,
@@ -355,13 +356,13 @@ extension secp256k1.Schnorr.PrivateKey: DigestSigner, Signer {
throw secp256k1Error.underlyingCryptoError
}
- return try secp256k1.Schnorr.SchnorrSignature(Data(bytes: signature, count: secp256k1.ByteLength.signature))
+ return try P256K.Schnorr.SchnorrSignature(Data(bytes: signature, count: P256K.ByteLength.signature))
}
}
// MARK: - Schnorr + Validating Key
-extension secp256k1.Schnorr.XonlyKey: DigestValidator, DataValidator {
+extension P256K.Schnorr.XonlyKey: DigestValidator, DataValidator {
/// Verifies a Schnorr signature with a variable length data object
///
/// This function uses SHA256 to create a hash of the variable length the data argument to ensure only 32-byte messages are verified.
@@ -373,7 +374,7 @@ extension secp256k1.Schnorr.XonlyKey: DigestValidator, DataValidator {
/// - signature: The signature to verify
/// - data: The data that was signed.
/// - Returns: True if the signature is valid, false otherwise.
- public func isValidSignature(_ signature: secp256k1.Schnorr.SchnorrSignature, for data: D) -> Bool {
+ public func isValidSignature(_ signature: P256K.Schnorr.SchnorrSignature, for data: D) -> Bool {
isValidSignature(signature, for: SHA256.hash(data: data))
}
@@ -388,7 +389,7 @@ extension secp256k1.Schnorr.XonlyKey: DigestValidator, DataValidator {
/// - signature: The signature to verify.
/// - digest: The digest that was signed.
/// - Returns: True if the signature is valid, false otherwise.
- public func isValidSignature(_ signature: secp256k1.Schnorr.SchnorrSignature, for digest: D) -> Bool {
+ public func isValidSignature(_ signature: P256K.Schnorr.SchnorrSignature, for digest: D) -> Bool {
var hashDataBytes = Array(digest).bytes
return isValid(signature, for: &hashDataBytes)
@@ -404,8 +405,8 @@ extension secp256k1.Schnorr.XonlyKey: DigestValidator, DataValidator {
/// - signature: The signature to verify.
/// - message: The message that was signed.
/// - Returns: True if the signature is valid, false otherwise.
- public func isValid(_ signature: secp256k1.Schnorr.SchnorrSignature, for message: inout [UInt8]) -> Bool {
- let context = secp256k1.Context.rawRepresentation
+ public func isValid(_ signature: P256K.Schnorr.SchnorrSignature, for message: inout [UInt8]) -> Bool {
+ let context = P256K.Context.rawRepresentation
var pubKey = secp256k1_xonly_pubkey()
return secp256k1_xonly_pubkey_parse(context, &pubKey, bytes).boolValue &&
diff --git a/Sources/zkp/SecureBytes.swift b/Sources/ZKP/SecureBytes.swift
similarity index 100%
rename from Sources/zkp/SecureBytes.swift
rename to Sources/ZKP/SecureBytes.swift
diff --git a/Sources/zkp/Signature.swift b/Sources/ZKP/Signature.swift
similarity index 100%
rename from Sources/zkp/Signature.swift
rename to Sources/ZKP/Signature.swift
diff --git a/Sources/zkp/Tweak.swift b/Sources/ZKP/Tweak.swift
similarity index 82%
rename from Sources/zkp/Tweak.swift
rename to Sources/ZKP/Tweak.swift
index 8442d93b..a2be4a81 100644
--- a/Sources/zkp/Tweak.swift
+++ b/Sources/ZKP/Tweak.swift
@@ -10,12 +10,18 @@
import Foundation
-public extension secp256k1.Signing.PrivateKey {
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
+public extension P256K.Signing.PrivateKey {
/// Create a new `PrivateKey` by adding tweak to the secret key.
/// - Parameter tweak: the 32-byte tweak object
/// - Returns: tweaked `PrivateKey` object
func add(_ tweak: [UInt8]) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var privateBytes = key.bytes
guard secp256k1_ec_seckey_tweak_add(context, &privateBytes, tweak).boolValue,
@@ -32,9 +38,9 @@ public extension secp256k1.Signing.PrivateKey {
/// - Parameter tweak: the 32-byte tweak object
/// - Returns: tweaked `PrivateKey` object
func add(xonly tweak: [UInt8]) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var keypair = secp256k1_keypair()
- var privateBytes = [UInt8](repeating: 0, count: secp256k1.ByteLength.privateKey)
+ var privateBytes = [UInt8](repeating: 0, count: P256K.ByteLength.privateKey)
var xonly = secp256k1_xonly_pubkey()
var keyParity = Int32()
@@ -52,7 +58,7 @@ public extension secp256k1.Signing.PrivateKey {
/// - Parameter tweak: the 32-byte tweak object
/// - Returns: tweaked `PrivateKey` object
func multiply(_ tweak: [UInt8]) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var privateBytes = key.bytes
guard secp256k1_ec_seckey_tweak_mul(context, &privateBytes, tweak).boolValue,
@@ -64,15 +70,15 @@ public extension secp256k1.Signing.PrivateKey {
}
}
-public extension secp256k1.Signing.PublicKey {
+public extension P256K.Signing.PublicKey {
/// Create a new `PublicKey` by adding tweak to the public key.
/// - Parameters:
/// - tweak: the 32-byte tweak object
/// - format: the format of the tweaked `PublicKey` object
/// - Returns: tweaked `PublicKey` object
- func add(_ tweak: [UInt8], format: secp256k1.Format = .compressed) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
- var pubKey = rawRepresentation
+ func add(_ tweak: [UInt8], format: P256K.Format = .compressed) throws -> Self {
+ let context = P256K.Context.rawRepresentation
+ var pubKey = baseKey.rawRepresentation
var pubKeyLen = format.length
var pubKeyBytes = [UInt8](repeating: 0, count: pubKeyLen)
@@ -89,9 +95,9 @@ public extension secp256k1.Signing.PublicKey {
/// - tweak: the 32-byte tweak object
/// - format: the format of the tweaked `PublicKey` object
/// - Returns: tweaked `PublicKey` object
- func multiply(_ tweak: [UInt8], format: secp256k1.Format = .compressed) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
- var pubKey = rawRepresentation
+ func multiply(_ tweak: [UInt8], format: P256K.Format = .compressed) throws -> Self {
+ let context = P256K.Context.rawRepresentation
+ var pubKey = baseKey.rawRepresentation
var pubKeyLen = format.length
var pubKeyBytes = [UInt8](repeating: 0, count: pubKeyLen)
@@ -104,18 +110,18 @@ public extension secp256k1.Signing.PublicKey {
}
}
-public extension secp256k1.Schnorr.XonlyKey {
+public extension P256K.Schnorr.XonlyKey {
/// Create a new `XonlyKey` by adding tweak to the x-only public key.
/// - Parameters:
/// - tweak: the 32-byte tweak object
/// - format: the format of the tweaked `XonlyKey` object
/// - Returns: tweaked `PublicKey` object
func add(_ tweak: [UInt8]) throws -> Self {
- let context = secp256k1.Context.rawRepresentation
+ let context = P256K.Context.rawRepresentation
var pubKey = secp256k1_pubkey()
var inXonlyPubKey = secp256k1_xonly_pubkey()
var outXonlyPubKey = secp256k1_xonly_pubkey()
- var xonlyBytes = [UInt8](repeating: 0, count: secp256k1.ByteLength.dimension)
+ var xonlyBytes = [UInt8](repeating: 0, count: P256K.ByteLength.dimension)
var keyParity = Int32()
guard secp256k1_xonly_pubkey_parse(context, &inXonlyPubKey, bytes).boolValue,
diff --git a/Sources/zkp/Utility.swift b/Sources/ZKP/Utility.swift
similarity index 94%
rename from Sources/zkp/Utility.swift
rename to Sources/ZKP/Utility.swift
index c4f0349a..a1f039c2 100644
--- a/Sources/zkp/Utility.swift
+++ b/Sources/ZKP/Utility.swift
@@ -10,6 +10,12 @@
import Foundation
+#if canImport(libsecp256k1_zkp)
+@_implementationOnly import libsecp256k1_zkp
+#elseif canImport(libsecp256k1)
+@_implementationOnly import libsecp256k1
+#endif
+
/// An extension for ContiguousBytes providing a convenience property.
public extension ContiguousBytes {
/// A property that returns an array of UInt8 bytes.
@@ -69,7 +75,7 @@ extension Int32 {
}
/// An extension for secp256k1_ecdsa_signature providing a convenience property.
-public extension secp256k1_ecdsa_signature {
+internal extension secp256k1_ecdsa_signature {
/// A property that returns the Data representation of the `secp256k1_ecdsa_signature` object.
var dataValue: Data {
var mutableSig = self
@@ -78,7 +84,7 @@ public extension secp256k1_ecdsa_signature {
}
/// An extension for secp256k1_ecdsa_recoverable_signature providing a convenience property.
-public extension secp256k1_ecdsa_recoverable_signature {
+internal extension secp256k1_ecdsa_recoverable_signature {
/// A property that returns the Data representation of the `secp256k1_ecdsa_recoverable_signature` object.
var dataValue: Data {
var mutableSig = self
diff --git a/Sources/zkp/Zeroization.swift b/Sources/ZKP/Zeroization.swift
similarity index 88%
rename from Sources/zkp/Zeroization.swift
rename to Sources/ZKP/Zeroization.swift
index cd528623..e1bd27c8 100644
--- a/Sources/zkp/Zeroization.swift
+++ b/Sources/ZKP/Zeroization.swift
@@ -29,6 +29,12 @@
//
//===----------------------------------------------------------------------===//
#if !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS))
+ #if canImport(libsecp256k1_zkp)
+ @_implementationOnly import libsecp256k1_zkp
+ #elseif canImport(libsecp256k1)
+ @_implementationOnly import libsecp256k1
+ #endif
+
public typealias errno_t = CInt
@discardableResult
diff --git a/Sources/secp256k1_bindings/include/Utility.h b/Sources/libsecp256k1/include/Utility.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/Utility.h
rename to Sources/libsecp256k1/include/Utility.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1.h b/Sources/libsecp256k1/include/secp256k1.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1.h
rename to Sources/libsecp256k1/include/secp256k1.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_ecdh.h b/Sources/libsecp256k1/include/secp256k1_ecdh.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_ecdh.h
rename to Sources/libsecp256k1/include/secp256k1_ecdh.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_ellswift.h b/Sources/libsecp256k1/include/secp256k1_ellswift.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_ellswift.h
rename to Sources/libsecp256k1/include/secp256k1_ellswift.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_extrakeys.h b/Sources/libsecp256k1/include/secp256k1_extrakeys.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_extrakeys.h
rename to Sources/libsecp256k1/include/secp256k1_extrakeys.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_musig.h b/Sources/libsecp256k1/include/secp256k1_musig.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_musig.h
rename to Sources/libsecp256k1/include/secp256k1_musig.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_preallocated.h b/Sources/libsecp256k1/include/secp256k1_preallocated.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_preallocated.h
rename to Sources/libsecp256k1/include/secp256k1_preallocated.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_recovery.h b/Sources/libsecp256k1/include/secp256k1_recovery.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_recovery.h
rename to Sources/libsecp256k1/include/secp256k1_recovery.h
diff --git a/Sources/secp256k1_bindings/include/secp256k1_schnorrsig.h b/Sources/libsecp256k1/include/secp256k1_schnorrsig.h
similarity index 100%
rename from Sources/secp256k1_bindings/include/secp256k1_schnorrsig.h
rename to Sources/libsecp256k1/include/secp256k1_schnorrsig.h
diff --git a/Sources/secp256k1_bindings/src/Utility.c b/Sources/libsecp256k1/src/Utility.c
similarity index 100%
rename from Sources/secp256k1_bindings/src/Utility.c
rename to Sources/libsecp256k1/src/Utility.c
diff --git a/Sources/secp256k1_bindings/src/assumptions.h b/Sources/libsecp256k1/src/assumptions.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/assumptions.h
rename to Sources/libsecp256k1/src/assumptions.h
diff --git a/Sources/secp256k1_bindings/src/checkmem.h b/Sources/libsecp256k1/src/checkmem.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/checkmem.h
rename to Sources/libsecp256k1/src/checkmem.h
diff --git a/Sources/secp256k1_bindings/src/ecdsa.h b/Sources/libsecp256k1/src/ecdsa.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecdsa.h
rename to Sources/libsecp256k1/src/ecdsa.h
diff --git a/Sources/secp256k1_bindings/src/ecdsa_impl.h b/Sources/libsecp256k1/src/ecdsa_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecdsa_impl.h
rename to Sources/libsecp256k1/src/ecdsa_impl.h
diff --git a/Sources/secp256k1_bindings/src/eckey.h b/Sources/libsecp256k1/src/eckey.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/eckey.h
rename to Sources/libsecp256k1/src/eckey.h
diff --git a/Sources/secp256k1_bindings/src/eckey_impl.h b/Sources/libsecp256k1/src/eckey_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/eckey_impl.h
rename to Sources/libsecp256k1/src/eckey_impl.h
diff --git a/Sources/secp256k1_bindings/src/ecmult.h b/Sources/libsecp256k1/src/ecmult.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult.h
rename to Sources/libsecp256k1/src/ecmult.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_compute_table.h b/Sources/libsecp256k1/src/ecmult_compute_table.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_compute_table.h
rename to Sources/libsecp256k1/src/ecmult_compute_table.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_compute_table_impl.h b/Sources/libsecp256k1/src/ecmult_compute_table_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_compute_table_impl.h
rename to Sources/libsecp256k1/src/ecmult_compute_table_impl.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_const.h b/Sources/libsecp256k1/src/ecmult_const.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_const.h
rename to Sources/libsecp256k1/src/ecmult_const.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_const_impl.h b/Sources/libsecp256k1/src/ecmult_const_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_const_impl.h
rename to Sources/libsecp256k1/src/ecmult_const_impl.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_gen.h b/Sources/libsecp256k1/src/ecmult_gen.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_gen.h
rename to Sources/libsecp256k1/src/ecmult_gen.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_gen_compute_table.h b/Sources/libsecp256k1/src/ecmult_gen_compute_table.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_gen_compute_table.h
rename to Sources/libsecp256k1/src/ecmult_gen_compute_table.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_gen_compute_table_impl.h b/Sources/libsecp256k1/src/ecmult_gen_compute_table_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_gen_compute_table_impl.h
rename to Sources/libsecp256k1/src/ecmult_gen_compute_table_impl.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_gen_impl.h b/Sources/libsecp256k1/src/ecmult_gen_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_gen_impl.h
rename to Sources/libsecp256k1/src/ecmult_gen_impl.h
diff --git a/Sources/secp256k1_bindings/src/ecmult_impl.h b/Sources/libsecp256k1/src/ecmult_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/ecmult_impl.h
rename to Sources/libsecp256k1/src/ecmult_impl.h
diff --git a/Sources/secp256k1_bindings/src/field.h b/Sources/libsecp256k1/src/field.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field.h
rename to Sources/libsecp256k1/src/field.h
diff --git a/Sources/secp256k1_bindings/src/field_10x26.h b/Sources/libsecp256k1/src/field_10x26.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_10x26.h
rename to Sources/libsecp256k1/src/field_10x26.h
diff --git a/Sources/secp256k1_bindings/src/field_10x26_impl.h b/Sources/libsecp256k1/src/field_10x26_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_10x26_impl.h
rename to Sources/libsecp256k1/src/field_10x26_impl.h
diff --git a/Sources/secp256k1_bindings/src/field_5x52.h b/Sources/libsecp256k1/src/field_5x52.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_5x52.h
rename to Sources/libsecp256k1/src/field_5x52.h
diff --git a/Sources/secp256k1_bindings/src/field_5x52_impl.h b/Sources/libsecp256k1/src/field_5x52_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_5x52_impl.h
rename to Sources/libsecp256k1/src/field_5x52_impl.h
diff --git a/Sources/secp256k1_bindings/src/field_5x52_int128_impl.h b/Sources/libsecp256k1/src/field_5x52_int128_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_5x52_int128_impl.h
rename to Sources/libsecp256k1/src/field_5x52_int128_impl.h
diff --git a/Sources/secp256k1_bindings/src/field_impl.h b/Sources/libsecp256k1/src/field_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/field_impl.h
rename to Sources/libsecp256k1/src/field_impl.h
diff --git a/Sources/secp256k1_bindings/src/group.h b/Sources/libsecp256k1/src/group.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/group.h
rename to Sources/libsecp256k1/src/group.h
diff --git a/Sources/secp256k1_bindings/src/group_impl.h b/Sources/libsecp256k1/src/group_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/group_impl.h
rename to Sources/libsecp256k1/src/group_impl.h
diff --git a/Sources/secp256k1_bindings/src/hash.h b/Sources/libsecp256k1/src/hash.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/hash.h
rename to Sources/libsecp256k1/src/hash.h
diff --git a/Sources/secp256k1_bindings/src/hash_impl.h b/Sources/libsecp256k1/src/hash_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/hash_impl.h
rename to Sources/libsecp256k1/src/hash_impl.h
diff --git a/Sources/secp256k1_bindings/src/hsort.h b/Sources/libsecp256k1/src/hsort.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/hsort.h
rename to Sources/libsecp256k1/src/hsort.h
diff --git a/Sources/secp256k1_bindings/src/hsort_impl.h b/Sources/libsecp256k1/src/hsort_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/hsort_impl.h
rename to Sources/libsecp256k1/src/hsort_impl.h
diff --git a/Sources/secp256k1_bindings/src/int128.h b/Sources/libsecp256k1/src/int128.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128.h
rename to Sources/libsecp256k1/src/int128.h
diff --git a/Sources/secp256k1_bindings/src/int128_impl.h b/Sources/libsecp256k1/src/int128_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128_impl.h
rename to Sources/libsecp256k1/src/int128_impl.h
diff --git a/Sources/secp256k1_bindings/src/int128_native.h b/Sources/libsecp256k1/src/int128_native.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128_native.h
rename to Sources/libsecp256k1/src/int128_native.h
diff --git a/Sources/secp256k1_bindings/src/int128_native_impl.h b/Sources/libsecp256k1/src/int128_native_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128_native_impl.h
rename to Sources/libsecp256k1/src/int128_native_impl.h
diff --git a/Sources/secp256k1_bindings/src/int128_struct.h b/Sources/libsecp256k1/src/int128_struct.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128_struct.h
rename to Sources/libsecp256k1/src/int128_struct.h
diff --git a/Sources/secp256k1_bindings/src/int128_struct_impl.h b/Sources/libsecp256k1/src/int128_struct_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/int128_struct_impl.h
rename to Sources/libsecp256k1/src/int128_struct_impl.h
diff --git a/Sources/secp256k1_bindings/src/modinv32.h b/Sources/libsecp256k1/src/modinv32.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modinv32.h
rename to Sources/libsecp256k1/src/modinv32.h
diff --git a/Sources/secp256k1_bindings/src/modinv32_impl.h b/Sources/libsecp256k1/src/modinv32_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modinv32_impl.h
rename to Sources/libsecp256k1/src/modinv32_impl.h
diff --git a/Sources/secp256k1_bindings/src/modinv64.h b/Sources/libsecp256k1/src/modinv64.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modinv64.h
rename to Sources/libsecp256k1/src/modinv64.h
diff --git a/Sources/secp256k1_bindings/src/modinv64_impl.h b/Sources/libsecp256k1/src/modinv64_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modinv64_impl.h
rename to Sources/libsecp256k1/src/modinv64_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/ecdh/main_impl.h b/Sources/libsecp256k1/src/modules/ecdh/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/ecdh/main_impl.h
rename to Sources/libsecp256k1/src/modules/ecdh/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/ellswift/main_impl.h b/Sources/libsecp256k1/src/modules/ellswift/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/ellswift/main_impl.h
rename to Sources/libsecp256k1/src/modules/ellswift/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/extrakeys/main_impl.h b/Sources/libsecp256k1/src/modules/extrakeys/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/extrakeys/main_impl.h
rename to Sources/libsecp256k1/src/modules/extrakeys/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/musig/keyagg.h b/Sources/libsecp256k1/src/modules/musig/keyagg.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/musig/keyagg.h
rename to Sources/libsecp256k1/src/modules/musig/keyagg.h
diff --git a/Sources/secp256k1_bindings/src/modules/musig/keyagg_impl.h b/Sources/libsecp256k1/src/modules/musig/keyagg_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/musig/keyagg_impl.h
rename to Sources/libsecp256k1/src/modules/musig/keyagg_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/musig/main_impl.h b/Sources/libsecp256k1/src/modules/musig/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/musig/main_impl.h
rename to Sources/libsecp256k1/src/modules/musig/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/musig/session.h b/Sources/libsecp256k1/src/modules/musig/session.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/musig/session.h
rename to Sources/libsecp256k1/src/modules/musig/session.h
diff --git a/Sources/secp256k1_bindings/src/modules/musig/session_impl.h b/Sources/libsecp256k1/src/modules/musig/session_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/musig/session_impl.h
rename to Sources/libsecp256k1/src/modules/musig/session_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/recovery/main_impl.h b/Sources/libsecp256k1/src/modules/recovery/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/recovery/main_impl.h
rename to Sources/libsecp256k1/src/modules/recovery/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/modules/schnorrsig/main_impl.h b/Sources/libsecp256k1/src/modules/schnorrsig/main_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/modules/schnorrsig/main_impl.h
rename to Sources/libsecp256k1/src/modules/schnorrsig/main_impl.h
diff --git a/Sources/secp256k1_bindings/src/precomputed_ecmult.c b/Sources/libsecp256k1/src/precomputed_ecmult.c
similarity index 100%
rename from Sources/secp256k1_bindings/src/precomputed_ecmult.c
rename to Sources/libsecp256k1/src/precomputed_ecmult.c
diff --git a/Sources/secp256k1_bindings/src/precomputed_ecmult.h b/Sources/libsecp256k1/src/precomputed_ecmult.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/precomputed_ecmult.h
rename to Sources/libsecp256k1/src/precomputed_ecmult.h
diff --git a/Sources/secp256k1_bindings/src/precomputed_ecmult_gen.c b/Sources/libsecp256k1/src/precomputed_ecmult_gen.c
similarity index 100%
rename from Sources/secp256k1_bindings/src/precomputed_ecmult_gen.c
rename to Sources/libsecp256k1/src/precomputed_ecmult_gen.c
diff --git a/Sources/secp256k1_bindings/src/precomputed_ecmult_gen.h b/Sources/libsecp256k1/src/precomputed_ecmult_gen.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/precomputed_ecmult_gen.h
rename to Sources/libsecp256k1/src/precomputed_ecmult_gen.h
diff --git a/Sources/secp256k1_bindings/src/scalar.h b/Sources/libsecp256k1/src/scalar.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar.h
rename to Sources/libsecp256k1/src/scalar.h
diff --git a/Sources/secp256k1_bindings/src/scalar_4x64.h b/Sources/libsecp256k1/src/scalar_4x64.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar_4x64.h
rename to Sources/libsecp256k1/src/scalar_4x64.h
diff --git a/Sources/secp256k1_bindings/src/scalar_4x64_impl.h b/Sources/libsecp256k1/src/scalar_4x64_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar_4x64_impl.h
rename to Sources/libsecp256k1/src/scalar_4x64_impl.h
diff --git a/Sources/secp256k1_bindings/src/scalar_8x32.h b/Sources/libsecp256k1/src/scalar_8x32.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar_8x32.h
rename to Sources/libsecp256k1/src/scalar_8x32.h
diff --git a/Sources/secp256k1_bindings/src/scalar_8x32_impl.h b/Sources/libsecp256k1/src/scalar_8x32_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar_8x32_impl.h
rename to Sources/libsecp256k1/src/scalar_8x32_impl.h
diff --git a/Sources/secp256k1_bindings/src/scalar_impl.h b/Sources/libsecp256k1/src/scalar_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scalar_impl.h
rename to Sources/libsecp256k1/src/scalar_impl.h
diff --git a/Sources/secp256k1_bindings/src/scratch.h b/Sources/libsecp256k1/src/scratch.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scratch.h
rename to Sources/libsecp256k1/src/scratch.h
diff --git a/Sources/secp256k1_bindings/src/scratch_impl.h b/Sources/libsecp256k1/src/scratch_impl.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/scratch_impl.h
rename to Sources/libsecp256k1/src/scratch_impl.h
diff --git a/Sources/secp256k1_bindings/src/secp256k1.c b/Sources/libsecp256k1/src/secp256k1.c
similarity index 100%
rename from Sources/secp256k1_bindings/src/secp256k1.c
rename to Sources/libsecp256k1/src/secp256k1.c
diff --git a/Sources/secp256k1_bindings/src/selftest.h b/Sources/libsecp256k1/src/selftest.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/selftest.h
rename to Sources/libsecp256k1/src/selftest.h
diff --git a/Sources/secp256k1_bindings/src/util.h b/Sources/libsecp256k1/src/util.h
similarity index 100%
rename from Sources/secp256k1_bindings/src/util.h
rename to Sources/libsecp256k1/src/util.h
diff --git a/Sources/zkp_bindings/include/Utility.h b/Sources/libsecp256k1_zkp/include/Utility.h
similarity index 100%
rename from Sources/zkp_bindings/include/Utility.h
rename to Sources/libsecp256k1_zkp/include/Utility.h
diff --git a/Sources/zkp_bindings/include/secp256k1.h b/Sources/libsecp256k1_zkp/include/secp256k1.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1.h
rename to Sources/libsecp256k1_zkp/include/secp256k1.h
diff --git a/Sources/zkp_bindings/include/secp256k1_bppp.h b/Sources/libsecp256k1_zkp/include/secp256k1_bppp.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_bppp.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_bppp.h
diff --git a/Sources/zkp_bindings/include/secp256k1_ecdh.h b/Sources/libsecp256k1_zkp/include/secp256k1_ecdh.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_ecdh.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_ecdh.h
diff --git a/Sources/zkp_bindings/include/secp256k1_ecdsa_adaptor.h b/Sources/libsecp256k1_zkp/include/secp256k1_ecdsa_adaptor.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_ecdsa_adaptor.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_ecdsa_adaptor.h
diff --git a/Sources/zkp_bindings/include/secp256k1_ecdsa_s2c.h b/Sources/libsecp256k1_zkp/include/secp256k1_ecdsa_s2c.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_ecdsa_s2c.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_ecdsa_s2c.h
diff --git a/Sources/zkp_bindings/include/secp256k1_ellswift.h b/Sources/libsecp256k1_zkp/include/secp256k1_ellswift.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_ellswift.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_ellswift.h
diff --git a/Sources/zkp_bindings/include/secp256k1_extrakeys.h b/Sources/libsecp256k1_zkp/include/secp256k1_extrakeys.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_extrakeys.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_extrakeys.h
diff --git a/Sources/zkp_bindings/include/secp256k1_generator.h b/Sources/libsecp256k1_zkp/include/secp256k1_generator.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_generator.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_generator.h
diff --git a/Sources/zkp_bindings/include/secp256k1_musig.h b/Sources/libsecp256k1_zkp/include/secp256k1_musig.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_musig.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_musig.h
diff --git a/Sources/zkp_bindings/include/secp256k1_preallocated.h b/Sources/libsecp256k1_zkp/include/secp256k1_preallocated.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_preallocated.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_preallocated.h
diff --git a/Sources/zkp_bindings/include/secp256k1_rangeproof.h b/Sources/libsecp256k1_zkp/include/secp256k1_rangeproof.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_rangeproof.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_rangeproof.h
diff --git a/Sources/zkp_bindings/include/secp256k1_recovery.h b/Sources/libsecp256k1_zkp/include/secp256k1_recovery.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_recovery.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_recovery.h
diff --git a/Sources/zkp_bindings/include/secp256k1_schnorrsig.h b/Sources/libsecp256k1_zkp/include/secp256k1_schnorrsig.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_schnorrsig.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_schnorrsig.h
diff --git a/Sources/zkp_bindings/include/secp256k1_schnorrsig_halfagg.h b/Sources/libsecp256k1_zkp/include/secp256k1_schnorrsig_halfagg.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_schnorrsig_halfagg.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_schnorrsig_halfagg.h
diff --git a/Sources/zkp_bindings/include/secp256k1_surjectionproof.h b/Sources/libsecp256k1_zkp/include/secp256k1_surjectionproof.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_surjectionproof.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_surjectionproof.h
diff --git a/Sources/zkp_bindings/include/secp256k1_whitelist.h b/Sources/libsecp256k1_zkp/include/secp256k1_whitelist.h
similarity index 100%
rename from Sources/zkp_bindings/include/secp256k1_whitelist.h
rename to Sources/libsecp256k1_zkp/include/secp256k1_whitelist.h
diff --git a/Sources/zkp_bindings/src/Utility.c b/Sources/libsecp256k1_zkp/src/Utility.c
similarity index 100%
rename from Sources/zkp_bindings/src/Utility.c
rename to Sources/libsecp256k1_zkp/src/Utility.c
diff --git a/Sources/zkp_bindings/src/assumptions.h b/Sources/libsecp256k1_zkp/src/assumptions.h
similarity index 100%
rename from Sources/zkp_bindings/src/assumptions.h
rename to Sources/libsecp256k1_zkp/src/assumptions.h
diff --git a/Sources/zkp_bindings/src/eccommit.h b/Sources/libsecp256k1_zkp/src/eccommit.h
similarity index 100%
rename from Sources/zkp_bindings/src/eccommit.h
rename to Sources/libsecp256k1_zkp/src/eccommit.h
diff --git a/Sources/zkp_bindings/src/eccommit_impl.h b/Sources/libsecp256k1_zkp/src/eccommit_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/eccommit_impl.h
rename to Sources/libsecp256k1_zkp/src/eccommit_impl.h
diff --git a/Sources/zkp_bindings/src/ecdsa.h b/Sources/libsecp256k1_zkp/src/ecdsa.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecdsa.h
rename to Sources/libsecp256k1_zkp/src/ecdsa.h
diff --git a/Sources/zkp_bindings/src/ecdsa_impl.h b/Sources/libsecp256k1_zkp/src/ecdsa_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecdsa_impl.h
rename to Sources/libsecp256k1_zkp/src/ecdsa_impl.h
diff --git a/Sources/zkp_bindings/src/eckey.h b/Sources/libsecp256k1_zkp/src/eckey.h
similarity index 100%
rename from Sources/zkp_bindings/src/eckey.h
rename to Sources/libsecp256k1_zkp/src/eckey.h
diff --git a/Sources/zkp_bindings/src/eckey_impl.h b/Sources/libsecp256k1_zkp/src/eckey_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/eckey_impl.h
rename to Sources/libsecp256k1_zkp/src/eckey_impl.h
diff --git a/Sources/zkp_bindings/src/ecmult.h b/Sources/libsecp256k1_zkp/src/ecmult.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult.h
rename to Sources/libsecp256k1_zkp/src/ecmult.h
diff --git a/Sources/zkp_bindings/src/ecmult_compute_table.h b/Sources/libsecp256k1_zkp/src/ecmult_compute_table.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_compute_table.h
rename to Sources/libsecp256k1_zkp/src/ecmult_compute_table.h
diff --git a/Sources/zkp_bindings/src/ecmult_compute_table_impl.h b/Sources/libsecp256k1_zkp/src/ecmult_compute_table_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_compute_table_impl.h
rename to Sources/libsecp256k1_zkp/src/ecmult_compute_table_impl.h
diff --git a/Sources/zkp_bindings/src/ecmult_const.h b/Sources/libsecp256k1_zkp/src/ecmult_const.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_const.h
rename to Sources/libsecp256k1_zkp/src/ecmult_const.h
diff --git a/Sources/zkp_bindings/src/ecmult_const_impl.h b/Sources/libsecp256k1_zkp/src/ecmult_const_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_const_impl.h
rename to Sources/libsecp256k1_zkp/src/ecmult_const_impl.h
diff --git a/Sources/zkp_bindings/src/ecmult_gen.h b/Sources/libsecp256k1_zkp/src/ecmult_gen.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_gen.h
rename to Sources/libsecp256k1_zkp/src/ecmult_gen.h
diff --git a/Sources/zkp_bindings/src/ecmult_gen_compute_table.h b/Sources/libsecp256k1_zkp/src/ecmult_gen_compute_table.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_gen_compute_table.h
rename to Sources/libsecp256k1_zkp/src/ecmult_gen_compute_table.h
diff --git a/Sources/zkp_bindings/src/ecmult_gen_compute_table_impl.h b/Sources/libsecp256k1_zkp/src/ecmult_gen_compute_table_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_gen_compute_table_impl.h
rename to Sources/libsecp256k1_zkp/src/ecmult_gen_compute_table_impl.h
diff --git a/Sources/zkp_bindings/src/ecmult_gen_impl.h b/Sources/libsecp256k1_zkp/src/ecmult_gen_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_gen_impl.h
rename to Sources/libsecp256k1_zkp/src/ecmult_gen_impl.h
diff --git a/Sources/zkp_bindings/src/ecmult_impl.h b/Sources/libsecp256k1_zkp/src/ecmult_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/ecmult_impl.h
rename to Sources/libsecp256k1_zkp/src/ecmult_impl.h
diff --git a/Sources/zkp_bindings/src/field.h b/Sources/libsecp256k1_zkp/src/field.h
similarity index 100%
rename from Sources/zkp_bindings/src/field.h
rename to Sources/libsecp256k1_zkp/src/field.h
diff --git a/Sources/zkp_bindings/src/field_10x26.h b/Sources/libsecp256k1_zkp/src/field_10x26.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_10x26.h
rename to Sources/libsecp256k1_zkp/src/field_10x26.h
diff --git a/Sources/zkp_bindings/src/field_10x26_impl.h b/Sources/libsecp256k1_zkp/src/field_10x26_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_10x26_impl.h
rename to Sources/libsecp256k1_zkp/src/field_10x26_impl.h
diff --git a/Sources/zkp_bindings/src/field_5x52.h b/Sources/libsecp256k1_zkp/src/field_5x52.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_5x52.h
rename to Sources/libsecp256k1_zkp/src/field_5x52.h
diff --git a/Sources/zkp_bindings/src/field_5x52_impl.h b/Sources/libsecp256k1_zkp/src/field_5x52_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_5x52_impl.h
rename to Sources/libsecp256k1_zkp/src/field_5x52_impl.h
diff --git a/Sources/zkp_bindings/src/field_5x52_int128_impl.h b/Sources/libsecp256k1_zkp/src/field_5x52_int128_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_5x52_int128_impl.h
rename to Sources/libsecp256k1_zkp/src/field_5x52_int128_impl.h
diff --git a/Sources/zkp_bindings/src/field_impl.h b/Sources/libsecp256k1_zkp/src/field_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/field_impl.h
rename to Sources/libsecp256k1_zkp/src/field_impl.h
diff --git a/Sources/zkp_bindings/src/group.h b/Sources/libsecp256k1_zkp/src/group.h
similarity index 100%
rename from Sources/zkp_bindings/src/group.h
rename to Sources/libsecp256k1_zkp/src/group.h
diff --git a/Sources/zkp_bindings/src/group_impl.h b/Sources/libsecp256k1_zkp/src/group_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/group_impl.h
rename to Sources/libsecp256k1_zkp/src/group_impl.h
diff --git a/Sources/zkp_bindings/src/hash.h b/Sources/libsecp256k1_zkp/src/hash.h
similarity index 100%
rename from Sources/zkp_bindings/src/hash.h
rename to Sources/libsecp256k1_zkp/src/hash.h
diff --git a/Sources/zkp_bindings/src/hash_impl.h b/Sources/libsecp256k1_zkp/src/hash_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/hash_impl.h
rename to Sources/libsecp256k1_zkp/src/hash_impl.h
diff --git a/Sources/zkp_bindings/src/modinv32.h b/Sources/libsecp256k1_zkp/src/modinv32.h
similarity index 100%
rename from Sources/zkp_bindings/src/modinv32.h
rename to Sources/libsecp256k1_zkp/src/modinv32.h
diff --git a/Sources/zkp_bindings/src/modinv32_impl.h b/Sources/libsecp256k1_zkp/src/modinv32_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modinv32_impl.h
rename to Sources/libsecp256k1_zkp/src/modinv32_impl.h
diff --git a/Sources/zkp_bindings/src/modinv64.h b/Sources/libsecp256k1_zkp/src/modinv64.h
similarity index 100%
rename from Sources/zkp_bindings/src/modinv64.h
rename to Sources/libsecp256k1_zkp/src/modinv64.h
diff --git a/Sources/zkp_bindings/src/modinv64_impl.h b/Sources/libsecp256k1_zkp/src/modinv64_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modinv64_impl.h
rename to Sources/libsecp256k1_zkp/src/modinv64_impl.h
diff --git a/Sources/zkp_bindings/src/modules/bppp/bppp_norm_product_impl.h b/Sources/libsecp256k1_zkp/src/modules/bppp/bppp_norm_product_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/bppp/bppp_norm_product_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/bppp/bppp_norm_product_impl.h
diff --git a/Sources/zkp_bindings/src/modules/bppp/bppp_transcript_impl.h b/Sources/libsecp256k1_zkp/src/modules/bppp/bppp_transcript_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/bppp/bppp_transcript_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/bppp/bppp_transcript_impl.h
diff --git a/Sources/zkp_bindings/src/modules/bppp/bppp_util.h b/Sources/libsecp256k1_zkp/src/modules/bppp/bppp_util.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/bppp/bppp_util.h
rename to Sources/libsecp256k1_zkp/src/modules/bppp/bppp_util.h
diff --git a/Sources/zkp_bindings/src/modules/bppp/main.h b/Sources/libsecp256k1_zkp/src/modules/bppp/main.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/bppp/main.h
rename to Sources/libsecp256k1_zkp/src/modules/bppp/main.h
diff --git a/Sources/zkp_bindings/src/modules/bppp/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/bppp/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/bppp/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/bppp/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/ecdh/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/ecdh/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/ecdh/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/ecdh/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/ecdsa_adaptor/dleq_impl.h b/Sources/libsecp256k1_zkp/src/modules/ecdsa_adaptor/dleq_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/ecdsa_adaptor/dleq_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/ecdsa_adaptor/dleq_impl.h
diff --git a/Sources/zkp_bindings/src/modules/ecdsa_adaptor/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/ecdsa_adaptor/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/ecdsa_adaptor/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/ecdsa_adaptor/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/ecdsa_s2c/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/ecdsa_s2c/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/ecdsa_s2c/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/ecdsa_s2c/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/ellswift/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/ellswift/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/ellswift/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/ellswift/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/extrakeys/hsort.h b/Sources/libsecp256k1_zkp/src/modules/extrakeys/hsort.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/extrakeys/hsort.h
rename to Sources/libsecp256k1_zkp/src/modules/extrakeys/hsort.h
diff --git a/Sources/zkp_bindings/src/modules/extrakeys/hsort_impl.h b/Sources/libsecp256k1_zkp/src/modules/extrakeys/hsort_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/extrakeys/hsort_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/extrakeys/hsort_impl.h
diff --git a/Sources/zkp_bindings/src/modules/extrakeys/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/extrakeys/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/extrakeys/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/extrakeys/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/generator/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/generator/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/generator/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/generator/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/generator/pedersen.h b/Sources/libsecp256k1_zkp/src/modules/generator/pedersen.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/generator/pedersen.h
rename to Sources/libsecp256k1_zkp/src/modules/generator/pedersen.h
diff --git a/Sources/zkp_bindings/src/modules/generator/pedersen_impl.h b/Sources/libsecp256k1_zkp/src/modules/generator/pedersen_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/generator/pedersen_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/generator/pedersen_impl.h
diff --git a/Sources/zkp_bindings/src/modules/musig/adaptor_impl.h b/Sources/libsecp256k1_zkp/src/modules/musig/adaptor_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/adaptor_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/adaptor_impl.h
diff --git a/Sources/zkp_bindings/src/modules/musig/keyagg.h b/Sources/libsecp256k1_zkp/src/modules/musig/keyagg.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/keyagg.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/keyagg.h
diff --git a/Sources/zkp_bindings/src/modules/musig/keyagg_impl.h b/Sources/libsecp256k1_zkp/src/modules/musig/keyagg_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/keyagg_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/keyagg_impl.h
diff --git a/Sources/zkp_bindings/src/modules/musig/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/musig/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/musig/session.h b/Sources/libsecp256k1_zkp/src/modules/musig/session.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/session.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/session.h
diff --git a/Sources/zkp_bindings/src/modules/musig/session_impl.h b/Sources/libsecp256k1_zkp/src/modules/musig/session_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/musig/session_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/musig/session_impl.h
diff --git a/Sources/zkp_bindings/src/modules/rangeproof/borromean.h b/Sources/libsecp256k1_zkp/src/modules/rangeproof/borromean.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/rangeproof/borromean.h
rename to Sources/libsecp256k1_zkp/src/modules/rangeproof/borromean.h
diff --git a/Sources/zkp_bindings/src/modules/rangeproof/borromean_impl.h b/Sources/libsecp256k1_zkp/src/modules/rangeproof/borromean_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/rangeproof/borromean_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/rangeproof/borromean_impl.h
diff --git a/Sources/zkp_bindings/src/modules/rangeproof/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/rangeproof/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/rangeproof/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/rangeproof/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/rangeproof/rangeproof.h b/Sources/libsecp256k1_zkp/src/modules/rangeproof/rangeproof.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/rangeproof/rangeproof.h
rename to Sources/libsecp256k1_zkp/src/modules/rangeproof/rangeproof.h
diff --git a/Sources/zkp_bindings/src/modules/rangeproof/rangeproof_impl.h b/Sources/libsecp256k1_zkp/src/modules/rangeproof/rangeproof_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/rangeproof/rangeproof_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/rangeproof/rangeproof_impl.h
diff --git a/Sources/zkp_bindings/src/modules/recovery/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/recovery/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/recovery/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/recovery/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/schnorrsig/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/schnorrsig/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/schnorrsig/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/schnorrsig/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/schnorrsig_halfagg/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/schnorrsig_halfagg/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/schnorrsig_halfagg/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/schnorrsig_halfagg/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/surjection/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/surjection/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/surjection/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/surjection/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/surjection/surjection.h b/Sources/libsecp256k1_zkp/src/modules/surjection/surjection.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/surjection/surjection.h
rename to Sources/libsecp256k1_zkp/src/modules/surjection/surjection.h
diff --git a/Sources/zkp_bindings/src/modules/surjection/surjection_impl.h b/Sources/libsecp256k1_zkp/src/modules/surjection/surjection_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/surjection/surjection_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/surjection/surjection_impl.h
diff --git a/Sources/zkp_bindings/src/modules/whitelist/main_impl.h b/Sources/libsecp256k1_zkp/src/modules/whitelist/main_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/whitelist/main_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/whitelist/main_impl.h
diff --git a/Sources/zkp_bindings/src/modules/whitelist/whitelist_impl.h b/Sources/libsecp256k1_zkp/src/modules/whitelist/whitelist_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/modules/whitelist/whitelist_impl.h
rename to Sources/libsecp256k1_zkp/src/modules/whitelist/whitelist_impl.h
diff --git a/Sources/zkp_bindings/src/precomputed_ecmult.c b/Sources/libsecp256k1_zkp/src/precomputed_ecmult.c
similarity index 100%
rename from Sources/zkp_bindings/src/precomputed_ecmult.c
rename to Sources/libsecp256k1_zkp/src/precomputed_ecmult.c
diff --git a/Sources/zkp_bindings/src/precomputed_ecmult.h b/Sources/libsecp256k1_zkp/src/precomputed_ecmult.h
similarity index 100%
rename from Sources/zkp_bindings/src/precomputed_ecmult.h
rename to Sources/libsecp256k1_zkp/src/precomputed_ecmult.h
diff --git a/Sources/zkp_bindings/src/precomputed_ecmult_gen.c b/Sources/libsecp256k1_zkp/src/precomputed_ecmult_gen.c
similarity index 100%
rename from Sources/zkp_bindings/src/precomputed_ecmult_gen.c
rename to Sources/libsecp256k1_zkp/src/precomputed_ecmult_gen.c
diff --git a/Sources/zkp_bindings/src/precomputed_ecmult_gen.h b/Sources/libsecp256k1_zkp/src/precomputed_ecmult_gen.h
similarity index 100%
rename from Sources/zkp_bindings/src/precomputed_ecmult_gen.h
rename to Sources/libsecp256k1_zkp/src/precomputed_ecmult_gen.h
diff --git a/Sources/zkp_bindings/src/scalar.h b/Sources/libsecp256k1_zkp/src/scalar.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar.h
rename to Sources/libsecp256k1_zkp/src/scalar.h
diff --git a/Sources/zkp_bindings/src/scalar_4x64.h b/Sources/libsecp256k1_zkp/src/scalar_4x64.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_4x64.h
rename to Sources/libsecp256k1_zkp/src/scalar_4x64.h
diff --git a/Sources/zkp_bindings/src/scalar_4x64_impl.h b/Sources/libsecp256k1_zkp/src/scalar_4x64_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_4x64_impl.h
rename to Sources/libsecp256k1_zkp/src/scalar_4x64_impl.h
diff --git a/Sources/zkp_bindings/src/scalar_8x32.h b/Sources/libsecp256k1_zkp/src/scalar_8x32.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_8x32.h
rename to Sources/libsecp256k1_zkp/src/scalar_8x32.h
diff --git a/Sources/zkp_bindings/src/scalar_8x32_impl.h b/Sources/libsecp256k1_zkp/src/scalar_8x32_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_8x32_impl.h
rename to Sources/libsecp256k1_zkp/src/scalar_8x32_impl.h
diff --git a/Sources/zkp_bindings/src/scalar_impl.h b/Sources/libsecp256k1_zkp/src/scalar_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_impl.h
rename to Sources/libsecp256k1_zkp/src/scalar_impl.h
diff --git a/Sources/zkp_bindings/src/scalar_low.h b/Sources/libsecp256k1_zkp/src/scalar_low.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_low.h
rename to Sources/libsecp256k1_zkp/src/scalar_low.h
diff --git a/Sources/zkp_bindings/src/scalar_low_impl.h b/Sources/libsecp256k1_zkp/src/scalar_low_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/scalar_low_impl.h
rename to Sources/libsecp256k1_zkp/src/scalar_low_impl.h
diff --git a/Sources/zkp_bindings/src/scratch.h b/Sources/libsecp256k1_zkp/src/scratch.h
similarity index 100%
rename from Sources/zkp_bindings/src/scratch.h
rename to Sources/libsecp256k1_zkp/src/scratch.h
diff --git a/Sources/zkp_bindings/src/scratch_impl.h b/Sources/libsecp256k1_zkp/src/scratch_impl.h
similarity index 100%
rename from Sources/zkp_bindings/src/scratch_impl.h
rename to Sources/libsecp256k1_zkp/src/scratch_impl.h
diff --git a/Sources/zkp_bindings/src/secp256k1.c b/Sources/libsecp256k1_zkp/src/secp256k1.c
similarity index 100%
rename from Sources/zkp_bindings/src/secp256k1.c
rename to Sources/libsecp256k1_zkp/src/secp256k1.c
diff --git a/Sources/zkp_bindings/src/selftest.h b/Sources/libsecp256k1_zkp/src/selftest.h
similarity index 100%
rename from Sources/zkp_bindings/src/selftest.h
rename to Sources/libsecp256k1_zkp/src/selftest.h
diff --git a/Sources/zkp_bindings/src/util.h b/Sources/libsecp256k1_zkp/src/util.h
similarity index 100%
rename from Sources/zkp_bindings/src/util.h
rename to Sources/libsecp256k1_zkp/src/util.h
diff --git a/Sources/secp256k1/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Sources/secp256k1/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
deleted file mode 120000
index 74978e23..00000000
--- a/Sources/secp256k1/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
+++ /dev/null
@@ -1 +0,0 @@
-../../../zkp/ASN1/Basic ASN1 Types/ObjectIdentifier.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/ASN1/SEC1PrivateKey.swift b/Sources/secp256k1/ASN1/SEC1PrivateKey.swift
deleted file mode 120000
index 00a47593..00000000
--- a/Sources/secp256k1/ASN1/SEC1PrivateKey.swift
+++ /dev/null
@@ -1 +0,0 @@
-../../zkp/ASN1/SEC1PrivateKey.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/ASN1/SubjectPublicKeyInfo.swift b/Sources/secp256k1/ASN1/SubjectPublicKeyInfo.swift
deleted file mode 120000
index ef5d73df..00000000
--- a/Sources/secp256k1/ASN1/SubjectPublicKeyInfo.swift
+++ /dev/null
@@ -1 +0,0 @@
-../../zkp/ASN1/SubjectPublicKeyInfo.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Asymmetric.swift b/Sources/secp256k1/Asymmetric.swift
deleted file mode 120000
index e9e135ab..00000000
--- a/Sources/secp256k1/Asymmetric.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Asymmetric.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Combine.swift b/Sources/secp256k1/Combine.swift
deleted file mode 120000
index 11fcbca4..00000000
--- a/Sources/secp256k1/Combine.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Combine.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Context.swift b/Sources/secp256k1/Context.swift
deleted file mode 120000
index 6c68f71f..00000000
--- a/Sources/secp256k1/Context.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Context.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/DH.swift b/Sources/secp256k1/DH.swift
deleted file mode 120000
index 2287d42c..00000000
--- a/Sources/secp256k1/DH.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/DH.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/ECDH.swift b/Sources/secp256k1/ECDH.swift
deleted file mode 120000
index f57c2c5d..00000000
--- a/Sources/secp256k1/ECDH.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/ECDH.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/ECDSA.swift b/Sources/secp256k1/ECDSA.swift
deleted file mode 120000
index e6be20a3..00000000
--- a/Sources/secp256k1/ECDSA.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/ECDSA.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/EdDSA.swift b/Sources/secp256k1/EdDSA.swift
deleted file mode 120000
index efa02aba..00000000
--- a/Sources/secp256k1/EdDSA.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/EdDSA.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Errors.swift b/Sources/secp256k1/Errors.swift
deleted file mode 120000
index bd5aeeae..00000000
--- a/Sources/secp256k1/Errors.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Errors.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Exports.swift b/Sources/secp256k1/Exports.swift
deleted file mode 120000
index e74cea5b..00000000
--- a/Sources/secp256k1/Exports.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Exports.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/HashDigest.swift b/Sources/secp256k1/HashDigest.swift
deleted file mode 120000
index c49bff3a..00000000
--- a/Sources/secp256k1/HashDigest.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/HashDigest.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/MuSig.swift b/Sources/secp256k1/MuSig.swift
deleted file mode 120000
index aa3b3dec..00000000
--- a/Sources/secp256k1/MuSig.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/MuSig.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Nonces.swift b/Sources/secp256k1/Nonces.swift
deleted file mode 120000
index 1bc8d76d..00000000
--- a/Sources/secp256k1/Nonces.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Nonces.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Recovery.swift b/Sources/secp256k1/Recovery.swift
deleted file mode 120000
index a6725e52..00000000
--- a/Sources/secp256k1/Recovery.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Recovery.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/SHA256.swift b/Sources/secp256k1/SHA256.swift
deleted file mode 120000
index 82de8dff..00000000
--- a/Sources/secp256k1/SHA256.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/SHA256.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/SafeCompare.swift b/Sources/secp256k1/SafeCompare.swift
deleted file mode 120000
index 60c3ae35..00000000
--- a/Sources/secp256k1/SafeCompare.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/SafeCompare.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Schnorr.swift b/Sources/secp256k1/Schnorr.swift
deleted file mode 120000
index a48c8923..00000000
--- a/Sources/secp256k1/Schnorr.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Schnorr.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Tweak.swift b/Sources/secp256k1/Tweak.swift
deleted file mode 120000
index 17bab9fc..00000000
--- a/Sources/secp256k1/Tweak.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Tweak.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Utility.swift b/Sources/secp256k1/Utility.swift
deleted file mode 120000
index 1b20d1a6..00000000
--- a/Sources/secp256k1/Utility.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Utility.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/Zeroization.swift b/Sources/secp256k1/Zeroization.swift
deleted file mode 120000
index 66e912fb..00000000
--- a/Sources/secp256k1/Zeroization.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/Zeroization.swift
\ No newline at end of file
diff --git a/Sources/secp256k1/secp256k1.swift b/Sources/secp256k1/secp256k1.swift
deleted file mode 120000
index cdbeba86..00000000
--- a/Sources/secp256k1/secp256k1.swift
+++ /dev/null
@@ -1 +0,0 @@
-../zkp/secp256k1.swift
\ No newline at end of file
diff --git a/Sources/zkp/Exports.swift b/Sources/zkp/Exports.swift
deleted file mode 100644
index abcbca2c..00000000
--- a/Sources/zkp/Exports.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Exports.swift
-// GigaBitcoin/secp256k1.swift
-//
-// Copyright (c) 2022 GigaBitcoin LLC
-// Distributed under the MIT software license
-//
-// See the accompanying file LICENSE for information
-//
-
-#if canImport(zkp_bindings)
- @_exported import zkp_bindings
-#else
- @_exported import secp256k1_bindings
-#endif
diff --git a/Tests/XCFrameworkTests/XCFrameworkTests.swift b/Tests/XCFrameworkTests/XCFrameworkTests.swift
new file mode 100644
index 00000000..1afe44f0
--- /dev/null
+++ b/Tests/XCFrameworkTests/XCFrameworkTests.swift
@@ -0,0 +1,26 @@
+//
+// XCFrameworkTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+import P256K
+import Testing
+
+struct XCFrameworkTestSuite {
+
+ @Test("Compressed Key pair test with raw data")
+ func compressedKeypairImplementationWithRaw() {
+ let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
+ let expectedPublicKey = "023521df7b94248ffdf0d37f738a4792cc3932b6b1b89ef71cddde8251383b26e7"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+
+ #expect(String(bytes: privateKey.dataRepresentation) == expectedPrivateKey)
+ #expect(String(bytes: privateKey.publicKey.dataRepresentation) == expectedPublicKey)
+ }
+}
diff --git a/Tests/ZKPTests/AsymmetricTests.swift b/Tests/ZKPTests/AsymmetricTests.swift
new file mode 100644
index 00000000..fd7f751e
--- /dev/null
+++ b/Tests/ZKPTests/AsymmetricTests.swift
@@ -0,0 +1,138 @@
+//
+// AsymmetricTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Testing
+
+struct AsymmetricTestSuite {
+
+ @Test("Compressed Key pair test with raw data")
+ func compressedKeypairImplementationWithRaw() {
+ let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
+ let expectedPublicKey = "023521df7b94248ffdf0d37f738a4792cc3932b6b1b89ef71cddde8251383b26e7"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+
+ #expect(String(bytes: privateKey.dataRepresentation) == expectedPrivateKey)
+ #expect(String(bytes: privateKey.publicKey.dataRepresentation) == expectedPublicKey)
+ }
+
+ @Test("Verify initialization of private key does not throw an error")
+ func testPrivateKey() {
+ #expect((try? P256K.Signing.PrivateKey()) != nil)
+ }
+
+ @Test("Verify compressed public key characteristics")
+ func testCompressedPublicKey() {
+ let privateKey = try! P256K.Signing.PrivateKey()
+ #expect(privateKey.publicKey.format == .compressed, "PublicKey format should be compressed")
+ #expect(privateKey.publicKey.dataRepresentation.count == P256K.Format.compressed.length, "PublicKey length mismatch for compressed format")
+ }
+
+ @Test("Verify uncompressed public key characteristics")
+ func testUncompressedPublicKey() {
+ let privateKey = try! P256K.Signing.PrivateKey(format: .uncompressed)
+ #expect(privateKey.publicKey.format == .uncompressed, "PublicKey format should be uncompressed")
+ #expect(privateKey.publicKey.dataRepresentation.count == P256K.Format.uncompressed.length, "PublicKey length mismatch for uncompressed format")
+ }
+
+ @Test("Verify uncompressed public key with specific bytes")
+ func testUncompressedPublicKeyWithKey() {
+ let privateBytes = try! "703d3b63e84421e59f9359f8b27c25365df9d85b6b1566e3168412fa599c12f4".bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateBytes, format: .uncompressed)
+ #expect(privateKey.publicKey.format == .uncompressed, "PublicKey format should be uncompressed")
+ #expect(privateKey.publicKey.dataRepresentation.count == P256K.Format.uncompressed.length, "PublicKey length mismatch for uncompressed format")
+
+ let expectedPublicKeyString = "04c9c68596824505dd6cd1993a16452b4b1a13bacde56f80e9049fd03850cce137c1fa4acb7bef7edcc04f4fa29e071ea17e34fa07fa5d87b5ebf6340df6558498"
+ let expectedPublicKey = try! expectedPublicKeyString.bytes
+
+ #expect(expectedPublicKey == privateKey.publicKey.bytes, "PublicKey bytes do not match expected value")
+ #expect(expectedPublicKeyString == String(bytes: privateKey.publicKey.bytes), "PublicKey string representation mismatch")
+ }
+
+ @Test("Verify invalid private key bytes throw appropriate error")
+ func testInvalidPrivateKeyBytes() {
+ let expectedPrivateKey = "55f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ #expect(throws: (any Error).self) {
+ _ = try expectedPrivateKey.bytes
+ }
+ }
+
+ @Test("Verify initialization with invalid private key length throws appropriate error")
+ func testInvalidPrivateKeyLength() {
+ let expectedPrivateKey = "555f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+
+ #expect(throws: secp256k1Error.incorrectKeySize) {
+ try P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ }
+ }
+
+ @Test("Test conversion of xonly public key to full public key")
+ func testXonlyToPublicKey() {
+ let privateKey = try! P256K.Signing.PrivateKey()
+ let publicKey = P256K.Signing.PublicKey(xonlyKey: privateKey.publicKey.xonly)
+
+ #expect(privateKey.publicKey.dataRepresentation == publicKey.dataRepresentation, "Public key data representations should match")
+ }
+
+ @Test("Public Key Combination Test")
+ func testPubkeyCombine() {
+ let publicKeyBytes1 = try! "021b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014".bytes
+ let publicKeyBytes2 = try! "0260303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752".bytes
+
+ let publicKey1 = try! P256K.Signing.PublicKey(dataRepresentation: publicKeyBytes1, format: .compressed)
+ let publicKey2 = try! P256K.Signing.PublicKey(dataRepresentation: publicKeyBytes2, format: .compressed)
+
+ let combinedPublicKey = try! publicKey1.combine([publicKey2])
+
+ let expectedCombinedKey = try! "03d6a3a9d62c7650fcac18f9ee68c7a004ebad71b7581b683062213ad9f37ddb28".bytes
+
+ #expect(combinedPublicKey.dataRepresentation.bytes == expectedCombinedKey, "Combined public key does not match the expected value.")
+ }
+
+ @Test("Private Key PEM Test")
+ func testPrivateKeyPEM() {
+ let privateKeyString = """
+ -----BEGIN EC PRIVATE KEY-----
+ MHQCAQEEIBXwHPDpec6b07GeLbnwetT0dvWzp0nV3MR+4pPKXIc7oAcGBSuBBAAK
+ oUQDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMAcjHIrTDS6HEELgguOatmFBOp
+ 2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
+ -----END EC PRIVATE KEY-----
+ """
+
+ let privateKey = try! P256K.Signing.PrivateKey(pemRepresentation: privateKeyString)
+ let expectedPrivateKey = "15f01cf0e979ce9bd3b19e2db9f07ad4f476f5b3a749d5dcc47ee293ca5c873b"
+
+ #expect(expectedPrivateKey == String(bytes: privateKey.dataRepresentation), "Private key PEM data does not match the expected value.")
+ }
+
+ @Test("Public Key PEM Test")
+ func testPublicKeyPEM() {
+ let publicKeyString = """
+ -----BEGIN PUBLIC KEY-----
+ MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMA
+ cjHIrTDS6HEELgguOatmFBOp2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
+ -----END PUBLIC KEY-----
+ """
+
+ let privateKeyBytes = try! "15f01cf0e979ce9bd3b19e2db9f07ad4f476f5b3a749d5dcc47ee293ca5c873b".bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes, format: .uncompressed)
+ let publicKey = try! P256K.Signing.PublicKey(pemRepresentation: publicKeyString)
+
+ #expect(privateKey.publicKey.dataRepresentation == publicKey.dataRepresentation, "Public key PEM data representation does not match the expected value.")
+ }
+
+}
diff --git a/Tests/ZKPTests/ECDHTests.swift b/Tests/ZKPTests/ECDHTests.swift
new file mode 100644
index 00000000..aaa9a4b2
--- /dev/null
+++ b/Tests/ZKPTests/ECDHTests.swift
@@ -0,0 +1,77 @@
+//
+// ECDHTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Foundation
+import Testing
+
+struct ECDHTestSuite {
+
+ @Test("Test Key Agreement")
+ func testKeyAgreement() {
+ let privateString1 = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
+ let privateString2 = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+
+ let privateBytes1 = try! privateString1.bytes
+ let privateBytes2 = try! privateString2.bytes
+
+ let privateKey1 = try! P256K.KeyAgreement.PrivateKey(dataRepresentation: privateBytes1)
+ let privateKey2 = try! P256K.KeyAgreement.PrivateKey(dataRepresentation: privateBytes2)
+
+ let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey, format: .uncompressed)
+ let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: privateKey1.publicKey, format: .uncompressed)
+
+ #expect(sharedSecret1.bytes == sharedSecret2.bytes, "Shared secrets should be equal")
+ }
+
+ @Test("Test Key Agreement Public Key Tweak Addition")
+ func testKeyAgreementPublicKeyTweakAdd() {
+ let privateSign1 = try! P256K.Signing.PrivateKey()
+ let privateSign2 = try! P256K.Signing.PrivateKey()
+
+ let privateKey1 = try! P256K.KeyAgreement.PrivateKey(dataRepresentation: privateSign1.dataRepresentation)
+ let privateKey2 = try! P256K.KeyAgreement.PrivateKey(dataRepresentation: privateSign2.dataRepresentation)
+
+ let publicKey1 = try! P256K.KeyAgreement.PublicKey(dataRepresentation: privateKey1.publicKey.dataRepresentation)
+
+ let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey)
+ let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: publicKey1)
+
+ #expect(sharedSecret1.bytes == sharedSecret2.bytes, "Shared secrets should be equal")
+
+ let symmetricKey1 = SHA256.hash(data: sharedSecret1.bytes)
+ let symmetricKey2 = SHA256.hash(data: sharedSecret2.bytes)
+
+ let sharedSecretSign1 = try! P256K.Signing.PrivateKey(dataRepresentation: symmetricKey1.bytes)
+ let sharedSecretSign2 = try! P256K.Signing.PrivateKey(dataRepresentation: symmetricKey2.bytes)
+
+ let privateTweak1 = try! sharedSecretSign1.add(xonly: privateSign1.publicKey.xonly.bytes)
+ let publicTweak2 = try! sharedSecretSign2.publicKey.add(privateSign1.publicKey.xonly.bytes)
+
+ let schnorrPrivate = try! P256K.Schnorr.PrivateKey(dataRepresentation: sharedSecretSign2.dataRepresentation)
+ let xonlyTweak2 = try! schnorrPrivate.xonly.add(privateSign1.publicKey.xonly.bytes)
+
+ #expect(
+ sharedSecretSign2.publicKey.xonly.parity
+ ? privateTweak1.publicKey.dataRepresentation != publicTweak2.dataRepresentation
+ : privateTweak1.publicKey.dataRepresentation == publicTweak2.dataRepresentation,
+ "Tweak addition expectation mismatch based on parity"
+ )
+
+ #expect(privateTweak1.publicKey.xonly.bytes == xonlyTweak2.bytes, "Xonly tweaks do not match")
+ }
+
+}
+
diff --git a/Tests/ZKPTests/ECDSATests.swift b/Tests/ZKPTests/ECDSATests.swift
new file mode 100644
index 00000000..d393ff14
--- /dev/null
+++ b/Tests/ZKPTests/ECDSATests.swift
@@ -0,0 +1,120 @@
+//
+// ECDSATest.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Foundation
+import Testing
+
+struct ECDSATestSuite {
+
+ @Test("Signing test with expected signature verification")
+ func signingECDSA() {
+ let expectedDerSignature = "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A=="
+ let expectedSignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVg=="
+ let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let signature = try! privateKey.signature(for: messageData)
+
+ // Verify the signature matches the expected output
+ #expect(signature.dataRepresentation.base64EncodedString() == expectedSignature)
+ #expect(try! signature.derRepresentation.base64EncodedString() == expectedDerSignature)
+ }
+
+ @Test("Signature Verification Test")
+ func verifyingTest() {
+ let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let signature = try! privateKey.signature(for: messageData)
+
+ // Verify that the public key is valid for the generated signature
+ #expect(privateKey.publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)))
+ }
+
+ @Test("DER Signature Verification Test")
+ func verifyingDER() {
+ let expectedDerSignature = Data(
+ base64Encoded: "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A==",
+ options: .ignoreUnknownCharacters)!
+ let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let signature = try! P256K.Signing.ECDSASignature(derRepresentation: expectedDerSignature)
+
+ // Convert XCTAssertTrue to #expect
+ #expect(privateKey.publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)))
+ }
+
+ @Test("Verify invalid raw signature initialization throws correct error")
+ func testInvalidRawSignature() {
+ #expect(throws: secp256k1Error.incorrectParameterSize) {
+ _ = try P256K.Signing.ECDSASignature(dataRepresentation: Data())
+ }
+ }
+
+ @Test("Verify invalid DER signature initialization throws correct error")
+ func testInvalidDerSignature() {
+ #expect(throws: secp256k1Error.underlyingCryptoError) {
+ _ = try P256K.Signing.ECDSASignature(derRepresentation: Data())
+ }
+ }
+
+ @Test("Signing with PEM representation")
+ func testSigningPEM() {
+ let privateKeyString = """
+ -----BEGIN EC PRIVATE KEY-----
+ MHQCAQEEIBXwHPDpec6b07GeLbnwetT0dvWzp0nV3MR+4pPKXIc7oAcGBSuBBAAK
+ oUQDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMAcjHIrTDS6HEELgguOatmFBOp
+ 2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
+ -----END EC PRIVATE KEY-----
+ """
+
+ let expectedDerSignature = "MEQCIC8k5whKPsPg7XtWTInvhGL4iEU6lP6yPdpEXXZ2mOhFAiAZ3Po9tEDV8mQ8LDzwF0nhPmAn9VLYG8bkuY6PKruZNQ=="
+ let privateKey = try! P256K.Signing.PrivateKey(pemRepresentation: privateKeyString)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let signature = try! privateKey.signature(for: messageData)
+
+ // Verify the signature matches the expected output
+ #expect(try! signature.derRepresentation.base64EncodedString() == expectedDerSignature, "Signature DER representation mismatch")
+ }
+
+ @Test("Verifying with PEM representation")
+ func testVerifyingPEM() {
+ let publicKeyString = """
+ -----BEGIN PUBLIC KEY-----
+ MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMA
+ cjHIrTDS6HEELgguOatmFBOp2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
+ -----END PUBLIC KEY-----
+ """
+
+ let expectedSignature = "MEQCIEwVxXLE/mwaRzxLvz9VIcMtHaa/Wf1WRxiBJ6NEuWHeAiAQWf2oqqBqEtBABbmwsXqjCJFvsaPt8o+VaOthto1kWQ=="
+ let expectedDerSignature = Data(base64Encoded: expectedSignature, options: .ignoreUnknownCharacters)!
+
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+ let signature = try! P256K.Signing.ECDSASignature(derRepresentation: expectedDerSignature)
+ let publicKey = try! P256K.Signing.PublicKey(pemRepresentation: publicKeyString)
+
+ #expect(publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)), "Signature validation failed")
+ }
+
+}
diff --git a/Tests/zkpTests/zkpTests.swift b/Tests/ZKPTests/MusigTests.swift
similarity index 58%
rename from Tests/zkpTests/zkpTests.swift
rename to Tests/ZKPTests/MusigTests.swift
index e866effd..d615b037 100644
--- a/Tests/zkpTests/zkpTests.swift
+++ b/Tests/ZKPTests/MusigTests.swift
@@ -1,36 +1,54 @@
-import XCTest
-@testable import zkp
+//
+// MusigTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
-final class zkpTests: XCTestCase {
- func testMusig() throws {
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Foundation
+import Testing
+
+struct MuSigTestSuite {
+
+ @Test("MuSig Signing and Verification")
+ func testMusig() {
// Test MuSig aggregate
let privateKeys = [
- try secp256k1.Schnorr.PrivateKey(),
- try secp256k1.Schnorr.PrivateKey(),
- try secp256k1.Schnorr.PrivateKey()
+ try! P256K.Schnorr.PrivateKey(),
+ try! P256K.Schnorr.PrivateKey(),
+ try! P256K.Schnorr.PrivateKey()
]
-
+
let publicKeys = privateKeys.map(\.publicKey)
- let aggregate = try secp256k1.MuSig.aggregate(publicKeys)
+ let aggregate = try! P256K.MuSig.aggregate(publicKeys)
// Create a message to sign
let message = "Hello, MuSig!".data(using: .utf8)!
let messageHash = SHA256.hash(data: message)
// Generate nonces for each signer
- let firstNonce = try secp256k1.MuSig.Nonce.generate(
+ let firstNonce = try! P256K.MuSig.Nonce.generate(
secretKey: privateKeys[0],
publicKey: privateKeys[0].publicKey,
msg32: Array(messageHash)
)
- let secondNonce = try secp256k1.MuSig.Nonce.generate(
+ let secondNonce = try! P256K.MuSig.Nonce.generate(
secretKey: privateKeys[1],
publicKey: privateKeys[1].publicKey,
msg32: Array(messageHash)
)
- let thirdNonce = try secp256k1.MuSig.Nonce.generate(
+ let thirdNonce = try! P256K.MuSig.Nonce.generate(
secretKey: privateKeys[2],
publicKey: privateKeys[2].publicKey,
msg32: Array(messageHash)
@@ -40,10 +58,10 @@ final class zkpTests: XCTestCase {
let publicNonces = [firstNonce.pubnonce, secondNonce.pubnonce, thirdNonce.pubnonce]
// Aggregate public nonces
- let aggregateNonce = try secp256k1.MuSig.Nonce(aggregating: publicNonces)
+ let aggregateNonce = try! P256K.MuSig.Nonce(aggregating: publicNonces)
// Create partial signatures
- let firstPartialSignature = try privateKeys[0].partialSignature(
+ let firstPartialSignature = try! privateKeys[0].partialSignature(
for: messageHash,
pubnonce: firstNonce.pubnonce,
secureNonce: firstNonce.secnonce,
@@ -51,7 +69,7 @@ final class zkpTests: XCTestCase {
publicKeyAggregate: aggregate
)
- let secondPartialSignature = try privateKeys[1].partialSignature(
+ let secondPartialSignature = try! privateKeys[1].partialSignature(
for: messageHash,
pubnonce: secondNonce.pubnonce,
secureNonce: secondNonce.secnonce,
@@ -59,7 +77,7 @@ final class zkpTests: XCTestCase {
publicKeyAggregate: aggregate
)
- let thirdPartialSignature = try privateKeys[2].partialSignature(
+ let thirdPartialSignature = try! privateKeys[2].partialSignature(
for: messageHash,
pubnonce: thirdNonce.pubnonce,
secureNonce: thirdNonce.secnonce,
@@ -67,7 +85,7 @@ final class zkpTests: XCTestCase {
publicKeyAggregate: aggregate
)
- // Expected error when uncommented
+ // Uncomment to see expected error
// let forthPartialSignature = try privateKeys[1].partialSignature(
// for: messageHash,
// pubnonce: thirdNonce.pubnonce,
@@ -77,20 +95,9 @@ final class zkpTests: XCTestCase {
// )
// Aggregate partial signatures
- _ = try secp256k1.MuSig.aggregateSignatures([firstPartialSignature, secondPartialSignature, thirdPartialSignature])
+ _ = try! P256K.MuSig.aggregateSignatures([firstPartialSignature, secondPartialSignature, thirdPartialSignature])
// Verify the signature
- XCTAssertTrue(
- aggregate.isValidSignature(
- firstPartialSignature,
- publicKey: publicKeys.first!,
- nonce: publicNonces.first!,
- for: messageHash
- )
- )
+ #expect(aggregate.isValidSignature(firstPartialSignature, publicKey: publicKeys.first!, nonce: publicNonces.first!, for: messageHash), "MuSig signature verification failed.")
}
-
- static var allTests = [
- ("testMusig", testMusig)
- ]
}
diff --git a/Tests/ZKPTests/RecoveryTests.swift b/Tests/ZKPTests/RecoveryTests.swift
new file mode 100644
index 00000000..d5c4ca4d
--- /dev/null
+++ b/Tests/ZKPTests/RecoveryTests.swift
@@ -0,0 +1,63 @@
+//
+// RecoveryTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import XCTest
+import Testing
+
+struct RecoveryTestSuite {
+
+ @Test("Recovery signing test with expected recovery signature verification")
+ func recoverySigningTest() {
+ let expectedDerSignature = "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A=="
+ let expectedRecoverySignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE="
+ let expectedSignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVg=="
+ let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Recovery.PrivateKey(dataRepresentation: privateKeyBytes)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let recoverySignature = try! privateKey.signature(for: messageData)
+
+ // Verify the recovery signature matches the expected output
+ #expect(recoverySignature.dataRepresentation.base64EncodedString() == expectedRecoverySignature)
+
+ let signature = try! recoverySignature.normalize
+
+ // Verify the signature matches the expected output
+ #expect(signature.dataRepresentation.base64EncodedString() == expectedSignature)
+ #expect(try! signature.derRepresentation.base64EncodedString() == expectedDerSignature)
+ }
+
+ @Test("Public key recovery test")
+ func publicKeyRecoveryTest() {
+ let expectedRecoverySignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE="
+ let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Recovery.PrivateKey(dataRepresentation: privateKeyBytes)
+ let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
+
+ let recoverySignature = try! privateKey.signature(for: messageData)
+
+ // Verify the recovery signature matches the expected output
+ #expect(recoverySignature.dataRepresentation.base64EncodedString() == expectedRecoverySignature)
+
+ let publicKey = try! P256K.Recovery.PublicKey(messageData, signature: recoverySignature)
+
+ // Verify the recovered public key matches the expected public key
+ #expect(publicKey.dataRepresentation == privateKey.publicKey.dataRepresentation)
+ }
+
+}
diff --git a/Tests/ZKPTests/SHA256Tests.swift b/Tests/ZKPTests/SHA256Tests.swift
new file mode 100644
index 00000000..5a5b8b4a
--- /dev/null
+++ b/Tests/ZKPTests/SHA256Tests.swift
@@ -0,0 +1,43 @@
+//
+// SHA256Tests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Testing
+
+struct SHA256TestSuite {
+
+ @Test("SHA256 test")
+ func sha256Test() {
+ let expectedHashDigest = "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342"
+ let data = "For this sample, this 63-byte string will be used as input data".data(using: .utf8)!
+
+ let digest = SHA256.hash(data: data)
+
+ #expect(String(bytes: Array(digest)) == expectedHashDigest)
+ }
+
+ @Test("SHA256 hash digest consistency test")
+ func shaHashDigestTest() {
+ let expectedHash = try! "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342".bytes
+ let data = "For this sample, this 63-byte string will be used as input data".data(using: .utf8)!
+
+ let digest = SHA256.hash(data: data)
+
+ let constructedDigest = HashDigest(expectedHash)
+
+ // Verify the generated hash digest matches the manual constructed hash digest
+ #expect(String(bytes: Array(digest)) == String(bytes: Array(constructedDigest)))
+ }
+}
diff --git a/Tests/ZKPTests/SchnorrTests.swift b/Tests/ZKPTests/SchnorrTests.swift
new file mode 100644
index 00000000..de578153
--- /dev/null
+++ b/Tests/ZKPTests/SchnorrTests.swift
@@ -0,0 +1,90 @@
+//
+// SchnorrTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import XCTest
+import Testing
+
+struct SchnorrTestSuite {
+
+ @Test("Schnorr Signing Test")
+ func schnorrSigningTest() {
+ let expectedDerSignature = "6QeDH4CEjRBppTcbQCQQNkvfHF+DB7AITFXxzi3KghUl9mpKheqLceSCp084LSzl6+7o/bIXL0d99JANMQU2wA=="
+ let expectedSignature = "e907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca821525f66a4a85ea8b71e482a74f382d2ce5ebeee8fdb2172f477df4900d310536c0"
+ let expectedPrivateKey = "0000000000000000000000000000000000000000000000000000000000000003"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
+ var messageDigest = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
+ var auxRand = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
+
+ let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
+
+ // Verify the signature matches the expected output
+ #expect(expectedSignature == String(bytes: Array(signature.dataRepresentation)))
+ #expect(expectedDerSignature == signature.dataRepresentation.base64EncodedString())
+ }
+
+ @Test("Schnorr Verifying Pre-Test")
+ func schnorrVerifyingPreTest() {
+ let expectedPrivateKey = "4894b8087f428971b55ff96e16f7127340138bc84e7973821a224cad02055975"
+ let expectedSignature = "ad57c21d383ef8ac799adfd469a221c40ef9f09563a16682b9ab1edc46c33d6d6a1d719761d269e87ab971e0ffafc1618a4666a4f9aef4abddc3ea9fc0cd5b12"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let throwKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
+ let privateKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
+ var messageDigest = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!.bytes
+ var auxRand = try! "f50c8c99e39a82f125fa83186b5f2483f39fb0fb56269c755689313a177be6ea".bytes
+
+ let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
+
+ // Verify the signature matches the expected signature
+ #expect(String(bytes: signature.dataRepresentation.bytes) == expectedSignature)
+
+ // Verify the signature is valid
+ #expect(privateKey.xonly.isValid(signature, for: &messageDigest))
+
+ // Verify that an error is thrown for the strict signature case
+ #expect(throws: secp256k1Error.incorrectParameterSize) {
+ _ = try throwKey.signature(message: &messageDigest, auxiliaryRand: &auxRand, strict: true)
+ }
+ }
+
+ @Test("Schnorr Verifying Test")
+ func schnorrVerifyingTest() {
+ let expectedPrivateKey = "0000000000000000000000000000000000000000000000000000000000000003"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
+ var messageDigest = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
+ var auxRand = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
+
+ let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
+
+ // Test the verification of the signature output
+ #expect(privateKey.xonly.isValid(signature, for: &messageDigest))
+ }
+
+ @Test("Test Schnorr Negating")
+ func testSchnorrNegating() {
+ let privateBytes = try! "56baa476b36a5b1548279f5bf57b82db39e594aee7912cde30977b8e80e6edca".bytes
+ let negatedBytes = try! "a9455b894c95a4eab7d860a40a847d2380c94837c7b7735d8f3ae2fe4f4f5377".bytes
+
+ let privateKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateBytes)
+ let negatedKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: negatedBytes).negation
+
+ #expect(privateKey == negatedKey, "Private key should equal negated key")
+ #expect(privateKey.dataRepresentation == negatedKey.dataRepresentation, "Data representation of private key should equal negated key")
+ #expect(privateKey.xonly == negatedKey.xonly, "Xonly of private key should equal negated key")
+ #expect(privateKey.xonly.bytes == negatedKey.xonly.bytes, "Xonly bytes of private key should equal negated key")
+ }
+}
diff --git a/Tests/ZKPTests/TaprootTests.swift b/Tests/ZKPTests/TaprootTests.swift
new file mode 100644
index 00000000..7e63ebe4
--- /dev/null
+++ b/Tests/ZKPTests/TaprootTests.swift
@@ -0,0 +1,106 @@
+//
+// TaprootTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Foundation
+import Testing
+
+struct TaprootTestSuite {
+
+ @Test("Test Taproot Derivation")
+ func testTaprootDerivation() {
+ let privateKeyBytes = try! "41F41D69260DF4CF277826A9B65A3717E4EEDDBEEDF637F212CA096576479361".bytes
+ let privateKey = try! P256K.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
+ let internalKeyBytes = try! "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115".bytes
+ let internalKey = privateKey.xonly
+
+ #expect(internalKey.bytes == internalKeyBytes, "Internal key bytes should match expected")
+
+ let tweakHash = try! SHA256.taggedHash(
+ tag: "TapTweak".data(using: .utf8)!,
+ data: Data(internalKey.bytes)
+ )
+
+ let outputKeyBytes = try! "a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c".bytes
+ let outputKey = try! internalKey.add(tweakHash.bytes)
+
+ #expect(outputKey.bytes == outputKeyBytes, "Output key bytes should match expected")
+ }
+
+ @Test("Test Tapscript execution and hash verification")
+ func testTapscript() {
+ let OP_CHECKSEQUENCEVERIFY = Data([0xB2])
+ let OP_DROP = Data([0x75])
+ let OP_CHECKSIG = Data([0xAC])
+ let OP_SHA256 = Data([0xA8])
+ let OP_EQUALVERIFY = Data([0x88])
+
+ var value = UInt64(144)
+ let numberOfBytes = ((64 - value.leadingZeroBitCount) / 8) + 1
+ let array = withUnsafeBytes(of: &value) { Array($0).prefix(numberOfBytes) }
+
+ let aliceBytes = try! "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90".bytes
+ let alice = try! P256K.Signing.PrivateKey(dataRepresentation: aliceBytes)
+ let aliceScript = Data([UInt8(array.count)] + array) +
+ OP_CHECKSEQUENCEVERIFY +
+ OP_DROP +
+ Data([UInt8(alice.publicKey.xonly.bytes.count)] + alice.publicKey.xonly.bytes) +
+ OP_CHECKSIG
+ let aliceLeafHash = try! SHA256.taggedHash(
+ tag: "TapLeaf".data(using: .utf8)!,
+ data: Data([0xC0]) + aliceScript.compactSizePrefix
+ )
+
+ let aliceExpectedLeafHash = "c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9"
+
+ #expect(String(bytes: Array(aliceLeafHash).bytes) == aliceExpectedLeafHash, "Alice's leaf hash mismatch")
+
+ let bobBytes = try! "81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9".bytes
+ let bob = try! P256K.Signing.PrivateKey(dataRepresentation: bobBytes)
+ let preimageBytes = try! "6c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd5333".bytes
+ let bobScript = OP_SHA256 +
+ Data([UInt8(preimageBytes.count)] + preimageBytes.bytes) +
+ OP_EQUALVERIFY +
+ Data([UInt8(bob.publicKey.xonly.bytes.count)] + bob.publicKey.xonly.bytes) +
+ OP_CHECKSIG
+ let bobLeafHash = try! SHA256.taggedHash(
+ tag: "TapLeaf".data(using: .utf8)!,
+ data: Data([0xC0]) + bobScript.compactSizePrefix
+ )
+
+ let bobExpectedLeafHash = "632c8632b4f29c6291416e23135cf78ecb82e525788ea5ed6483e3c6ce943b42"
+
+ #expect(String(bytes: Array(bobLeafHash).bytes) == bobExpectedLeafHash, "Bob's leaf hash mismatch")
+
+ var leftHash, rightHash: Data
+ if aliceLeafHash < bobLeafHash {
+ leftHash = Data(aliceLeafHash)
+ rightHash = Data(bobLeafHash)
+ } else {
+ leftHash = Data(bobLeafHash)
+ rightHash = Data(aliceLeafHash)
+ }
+
+ let merkleRoot = try! SHA256.taggedHash(
+ tag: "TapBranch".data(using: .utf8)!,
+ data: leftHash + rightHash
+ )
+
+ let expectedMerkleRoot = "41646f8c1fe2a96ddad7f5471bc4fee7da98794ef8c45a4f4fc6a559d60c9f6b"
+
+ #expect(String(bytes: Array(merkleRoot).bytes) == expectedMerkleRoot, "Merkle root mismatch")
+ }
+
+}
diff --git a/Tests/ZKPTests/TweakTests.swift b/Tests/ZKPTests/TweakTests.swift
new file mode 100644
index 00000000..492fd37d
--- /dev/null
+++ b/Tests/ZKPTests/TweakTests.swift
@@ -0,0 +1,39 @@
+//
+// TweakTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Testing
+
+struct TweakTestSuite {
+
+ @Test("Verify private key tweak addition produces expected result")
+ func testPrivateKeyTweakAdd() {
+ let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
+ let expectedPublicKey = "023521df7b94248ffdf0d37f738a4792cc3932b6b1b89ef71cddde8251383b26e7"
+ let expectedTweakedPrivateKey = "5f0da318c6e02f653a789950e55756ade9f194e1ec228d7f368de1bd821322b6"
+ let privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ let tweak = SHA256.hash(data: expectedPrivateKey.data(using: .utf8)!)
+
+ // Tweak the private key
+ let tweakedPrivateKey = try! privateKey.add(xonly: Array(tweak))
+
+ // Verify the tweaked private key matches expected value
+ #expect(String(bytes: tweakedPrivateKey.dataRepresentation) == expectedTweakedPrivateKey)
+ // Verify original public key remains correct
+ #expect(expectedPublicKey == String(bytes: privateKey.publicKey.dataRepresentation))
+ }
+
+}
diff --git a/Tests/ZKPTests/UtilityTests.swift b/Tests/ZKPTests/UtilityTests.swift
new file mode 100644
index 00000000..3d0d305f
--- /dev/null
+++ b/Tests/ZKPTests/UtilityTests.swift
@@ -0,0 +1,66 @@
+//
+// UtilityTests.swift
+// 21-DOT-DEV/swift-secp256k1
+//
+// Copyright (c) 2025 GigaBitcoin LLC
+// Distributed under the MIT software license
+//
+// See the accompanying file LICENSE for information
+//
+
+#if canImport(ZKP)
+@testable import ZKP
+#else
+@testable import P256K
+#endif
+
+import Foundation
+import Testing
+
+struct UtilityTestSuite {
+
+ @Test("Verify keypair equality checks work correctly")
+ func testKeypairSafeCompare() {
+ let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
+ var privateKeyBytes = try! expectedPrivateKey.bytes
+ let privateKey0 = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+ let privateKey1 = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+
+ // Verify the keys match
+ #expect(privateKey0 == privateKey1)
+
+ let expectedFailingPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888dd"
+ privateKeyBytes = try! expectedFailingPrivateKey.bytes
+ let privateKey2 = try! P256K.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
+
+ #expect(privateKey0 != privateKey2)
+ }
+
+ @Test("Verify memory zeroization works correctly")
+ func testZeroization() {
+ var array: [UInt8] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+ memset_s(&array, array.capacity, 0, array.capacity)
+
+ let set0 = Set(array)
+
+ array = [UInt8](repeating: 1, count: Int.random(in: 10...100_000))
+
+ #expect(array.count > 9)
+
+ memset_s(&array, array.capacity, 0, array.capacity)
+
+ let set1 = Set(array)
+
+ #expect(set0.first == 0)
+ #expect(set0.count == 1)
+ #expect(set0 == set1)
+ }
+
+ @Test("Test Compact Size Prefix")
+ func testCompactSizePrefix() {
+ let bytes = try! "c15bf08d58a430f8c222bffaf9127249c5cdff70a2d68b2b45637eb662b6b88eb5c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9".bytes
+ let compactBytes = "41c15bf08d58a430f8c222bffaf9127249c5cdff70a2d68b2b45637eb662b6b88eb5c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9"
+ #expect(compactBytes == String(bytes: Array(Data(bytes).compactSizePrefix)), "Compact size prefix encoding is incorrect.")
+ }
+}
diff --git a/Tests/libsecp256k1zkpTests/BindingsTests.swift b/Tests/libsecp256k1zkpTests/BindingsTests.swift
new file mode 100644
index 00000000..c3585801
--- /dev/null
+++ b/Tests/libsecp256k1zkpTests/BindingsTests.swift
@@ -0,0 +1,215 @@
+//
+// BindingsTests.swift
+// swift-secp256k1
+//
+// Created by csjones on 2/9/25.
+//
+
+#if canImport(libsecp256k1_zkp)
+@testable import ZKP
+@testable import libsecp256k1_zkp
+#else
+@testable import P256K
+@testable import libsecp256k1
+#endif
+
+import Testing
+
+struct BindingsTestSuite {
+
+ /// Uncompressed Key pair test
+ @Test("Uncompressed Key pair creation bindings")
+ func uncompressedKeypairCreationBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ // Setup private and public key variables
+ var pubkeyLen = 65
+ var cPubkey = secp256k1_pubkey()
+ var publicKey = [UInt8](repeating: 0, count: pubkeyLen)
+
+ let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
+
+ // Verify the context and keys are setup correctly
+ #expect(secp256k1_context_randomize(context, privateKey) == 1, "Context randomization failed.")
+ #expect(secp256k1_ec_pubkey_create(context, &cPubkey, privateKey) == 1, "Public key creation failed.")
+ #expect(secp256k1_ec_pubkey_serialize(context, &publicKey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_UNCOMPRESSED)) == 1, "Public key serialization failed.")
+
+ let hexString = """
+ 04734B3511150A60FC8CAC329CD5FF804555728740F2F2E98BC4242135EF5D5E4E6C4918116B0866F50C46614F3015D8667FBFB058471D662A642B8EA2C9C78E8A
+ """
+
+ // Define the expected public key
+ let expectedPublicKey = try! hexString.bytes
+
+ // Verify the generated public key matches the expected public key
+ #expect(expectedPublicKey == publicKey, "Generated public key does not match expected public key.")
+ #expect(hexString.lowercased() == String(bytes: publicKey), "Generated public key string representation is incorrect.")
+ }
+
+ /// Compressed Key pair creation bindings
+ @Test("Compressed Key pair creation bindings")
+ func compressedKeypairCreationBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy 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! "B035FCFC6ABF660856C5F3A6F9AC51FCA897BB4E76AD9ACA3EFD40DA6B9C864B".bytes
+
+ // Verify the context and keys are setup correctly
+ #expect(secp256k1_context_randomize(context, privateKey) == 1, "Context randomization failed.")
+ #expect(secp256k1_ec_pubkey_create(context, &cPubkey, privateKey) == 1, "Public key creation failed.")
+ #expect(secp256k1_ec_pubkey_serialize(context, &publicKey, &pubkeyLen, &cPubkey, UInt32(SECP256K1_EC_COMPRESSED)) == 1, "Public key serialization failed.")
+
+ // Define the expected public key
+ let expectedPublicKey = try! "02EA724B70B48B61FB87E4310871A48C65BF38BF3FDFEFE73C2B90F8F32F9C1794".bytes
+
+ // Verify the generated public key matches the expected public key
+ #expect(expectedPublicKey == publicKey, "Generated public key does not match expected public key.")
+ }
+
+ /// ECDH Test
+ @Test("ECDH Binding Test")
+ func ecdhBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ var point = secp256k1_pubkey()
+ var res = [UInt8](repeating: 0, count: 32)
+ var s_one = [UInt8](repeating: 0, count: 32)
+
+ s_one[31] = 1
+
+ #expect(secp256k1_ec_pubkey_create(context, &point, s_one) == 1, "Public key creation failed.")
+ #expect(secp256k1_ecdh(context, &res, &point, s_one, nil, nil) == 1, "ECDH computation failed.")
+ }
+
+ /// Extra Keys Bindings Test
+ @Test("Extra Keys Bindings Test")
+ func extraKeysBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ var pubKey = secp256k1_pubkey()
+ var xOnlyPubKey = secp256k1_xonly_pubkey()
+ var pk_parity = Int32()
+
+ let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
+
+ #expect(secp256k1_ec_pubkey_create(context, &pubKey, privateKey) == 1, "Failed to create public key from private key.")
+ #expect(secp256k1_xonly_pubkey_from_pubkey(context, &xOnlyPubKey, &pk_parity, &pubKey) == 1, "Failed to convert public key to xonly format.")
+ }
+
+ /// Recovery Bindings Test
+ @Test("Recovery Bindings Test")
+ func recoveryBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ var pubKey = secp256k1_pubkey()
+ var recsig = secp256k1_ecdsa_recoverable_signature()
+ var message = [UInt8](repeating: 0, count: 32)
+
+ let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
+
+ #expect(secp256k1_ec_seckey_verify(context, privateKey) == 1, "Failed to verify private key.")
+ #expect(secp256k1_ec_pubkey_create(context, &pubKey, privateKey) == 1, "Failed to create public key from private key.")
+ #expect(secp256k1_ecdsa_sign_recoverable(context, &recsig, &message, privateKey, nil, nil) == 1, "Failed to sign message with private key.")
+ }
+
+ /// Schnorr Bindings Test
+ @Test("Schnorr Bindings Test")
+ func schnorrBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ var keypair = secp256k1_keypair()
+ var xpubKey = secp256k1_xonly_pubkey()
+ var xpubKeyBytes = [UInt8](repeating: 0, count: 32)
+
+ let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
+
+ #expect(secp256k1_keypair_create(context, &keypair, privateKey) == 1, "Failed to create keypair from private key.")
+ #expect(secp256k1_keypair_xonly_pub(context, &xpubKey, nil, &keypair) == 1, "Failed to get xonly public key from keypair.")
+ #expect(secp256k1_xonly_pubkey_serialize(context, &xpubKeyBytes, &xpubKey) == 1, "Failed to serialize xonly public key.")
+
+ let expectedXPubKey = "734b3511150a60fc8cac329cd5ff804555728740f2f2e98bc4242135ef5d5e4e"
+
+ #expect(String(bytes: xpubKeyBytes) == expectedXPubKey, "Generated xonly public key does not match expected xonly public key.")
+ }
+
+ /// Key Agreement Hash Function Test
+ @Test("Key Agreement Hash Function Test")
+ func keyAgreementHashFunction() {
+ let context = P256K.Context.rawRepresentation
+ let privateKey1 = try! P256K.KeyAgreement.PrivateKey()
+ let privateKey2 = try! P256K.KeyAgreement.PrivateKey()
+
+ var pub = secp256k1_pubkey()
+ let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey)
+ var sharedSecret2 = [UInt8](repeating: 0, count: 32)
+
+ #expect(secp256k1_ec_pubkey_parse(context, &pub, privateKey1.publicKey.bytes, privateKey1.publicKey.bytes.count) == 1, "Failed to parse public key.")
+ #expect(secp256k1_ecdh(context, &sharedSecret2, &pub, privateKey2.baseKey.key.bytes, nil, nil) == 1, "Failed to compute ECDH shared secret.")
+
+ let symmerticKey = SHA256.hash(data: sharedSecret1.bytes)
+
+ #expect(symmerticKey.bytes == sharedSecret2, "Shared secrets do not match.")
+ }
+
+ /// Pubkey Combine Bindings Test
+ @Test("Pubkey Combine Bindings Test")
+ func pubkeyCombineBindings() {
+ // Initialize context
+ let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_NONE))!
+
+ // Destroy context after execution
+ defer { secp256k1_context_destroy(context) }
+
+ // Setup private and public key variables
+ var pubKeyLen = 33
+ var cPubKey1 = secp256k1_pubkey()
+ var cPubKey2 = secp256k1_pubkey()
+
+ let publicKeyBytes1 = try! "021b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014".bytes
+ let publicKeyBytes2 = try! "0260303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752".bytes
+
+ // Verify the context and keys are setup correctly
+ #expect(secp256k1_ec_pubkey_parse(context, &cPubKey1, publicKeyBytes1, pubKeyLen) == 1, "Failed to parse the first public key.")
+ #expect(secp256k1_ec_pubkey_parse(context, &cPubKey2, publicKeyBytes2, pubKeyLen) == 1, "Failed to parse the second public key.")
+
+ let pubKeys: [UnsafePointer?] = [UnsafePointer(&cPubKey1), UnsafePointer(&cPubKey2)]
+ var combinedKey = secp256k1_pubkey()
+ var combinedKeyBytes = [UInt8](repeating: 0, count: pubKeyLen)
+
+ // Combine the two public keys
+ #expect(secp256k1_ec_pubkey_combine(context, &combinedKey, pubKeys, 2) == 1, "Failed to combine public keys.")
+ #expect(secp256k1_ec_pubkey_serialize(context, &combinedKeyBytes, &pubKeyLen, &combinedKey, P256K.Format.compressed.rawValue) == 1, "Failed to serialize the combined public key.")
+
+ // Define the expected combined key
+ let expectedCombinedKey = try! "03d6a3a9d62c7650fcac18f9ee68c7a004ebad71b7581b683062213ad9f37ddb28".bytes
+
+ #expect(combinedKeyBytes == expectedCombinedKey, "Combined public key does not match the expected value.")
+ }
+}
diff --git a/Tests/zkpTests/XCTestManifests.swift b/Tests/zkpTests/XCTestManifests.swift
deleted file mode 100644
index 459fa256..00000000
--- a/Tests/zkpTests/XCTestManifests.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-import XCTest
-
-#if !canImport(ObjectiveC) && canImport(secp256k1)
- public func allTests() -> [XCTestCaseEntry] {
- [
- testCase(secp256k1Tests.allTests)
- ]
- }
-
-#elseif !canImport(ObjectiveC) && canImport(zkp)
- public func allTests() -> [XCTestCaseEntry] {
- [
- testCase(secp256k1Tests.allTests),
- testCase(zkpTests.allTests)
- ]
- }
-#endif
diff --git a/Tests/zkpTests/secp256k1Tests.swift b/Tests/zkpTests/secp256k1Tests.swift
deleted file mode 100644
index 03391f6e..00000000
--- a/Tests/zkpTests/secp256k1Tests.swift
+++ /dev/null
@@ -1,854 +0,0 @@
-#if canImport(zkp)
- @testable import zkp
-#else
- @testable import secp256k1
-#endif
-
-import XCTest
-
-final class secp256k1Tests: XCTestCase, @unchecked Sendable {
- /// Uncompressed Key pair test
- func testUncompressedKeypairCreation() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- // Setup private and public key variables
- var pubkeyLen = 65
- var cPubkey = secp256k1_pubkey()
- var publicKey = [UInt8](repeating: 0, count: pubkeyLen)
-
- let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
-
- // 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! hexString.bytes
-
- // Verify the generated public key matches the expected public key
- XCTAssertEqual(expectedPublicKey, publicKey)
- XCTAssertEqual(hexString.lowercased(), String(bytes: publicKey))
- }
-
- /// Compressed Key pair test
- func testCompressedKeypairCreation() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy 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! "B035FCFC6ABF660856C5F3A6F9AC51FCA897BB4E76AD9ACA3EFD40DA6B9C864B".bytes
-
- // 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_COMPRESSED)), 1)
-
- // Define the expected public key
- let expectedPublicKey = try! "02EA724B70B48B61FB87E4310871A48C65BF38BF3FDFEFE73C2B90F8F32F9C1794".bytes
-
- // Verify the generated public key matches the expected public key
- XCTAssertEqual(expectedPublicKey, publicKey)
- }
-
- func testECDHBindings() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- var point = secp256k1_pubkey()
- var res = [UInt8](repeating: 0, count: 32)
- var s_one = [UInt8](repeating: 0, count: 32)
-
- s_one[31] = 1
-
- XCTAssertEqual(secp256k1_ec_pubkey_create(context, &point, s_one), 1)
- XCTAssertEqual(secp256k1_ecdh(context, &res, &point, s_one, nil, nil), 1)
- }
-
- func testExtraKeysBindings() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- var pubKey = secp256k1_pubkey()
- var xOnlyPubKey = secp256k1_xonly_pubkey()
- var pk_parity = Int32()
-
- let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
-
- XCTAssertEqual(secp256k1_ec_pubkey_create(context, &pubKey, privateKey), 1)
- XCTAssertEqual(secp256k1_xonly_pubkey_from_pubkey(context, &xOnlyPubKey, &pk_parity, &pubKey), 1)
- }
-
- func testRecoveryBindings() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- var pubKey = secp256k1_pubkey()
- var recsig = secp256k1_ecdsa_recoverable_signature()
- var message = [UInt8](repeating: 0, count: 32)
-
- let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
-
- XCTAssertEqual(secp256k1_ec_seckey_verify(context, privateKey), 1)
- XCTAssertEqual(secp256k1_ec_pubkey_create(context, &pubKey, privateKey), 1)
- XCTAssertEqual(secp256k1_ecdsa_sign_recoverable(context, &recsig, &message, privateKey, nil, nil), 1)
- }
-
- func testSchnorrBindings() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- var keypair = secp256k1_keypair()
- var xpubKey = secp256k1_xonly_pubkey()
- var xpubKeyBytes = [UInt8](repeating: 0, count: 32)
-
- let privateKey = try! "14E4A74438858920D8A35FB2D88677580B6A2EE9BE4E711AE34EC6B396D87B5C".bytes
-
- XCTAssertEqual(secp256k1_keypair_create(context, &keypair, privateKey), 1)
- XCTAssertEqual(secp256k1_keypair_xonly_pub(context, &xpubKey, nil, &keypair), 1)
- XCTAssertEqual(secp256k1_xonly_pubkey_serialize(context, &xpubKeyBytes, &xpubKey), 1)
-
- let expectedXPubKey = "734b3511150a60fc8cac329cd5ff804555728740f2f2e98bc4242135ef5d5e4e"
-
- XCTAssertEqual(String(bytes: xpubKeyBytes), expectedXPubKey)
- }
-
- /// Compressed Key pair test
- func testCompressedKeypairImplementationWithRaw() {
- let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
- let expectedPublicKey = "023521df7b94248ffdf0d37f738a4792cc3932b6b1b89ef71cddde8251383b26e7"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
-
- // Verify the keys matches the expected keys output
- XCTAssertEqual(expectedPrivateKey, String(bytes: privateKey.dataRepresentation))
- XCTAssertEqual(expectedPublicKey, String(bytes: privateKey.publicKey.dataRepresentation))
- }
-
- /// SHA256 test
- func testSha256() {
- let expectedHashDigest = "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342"
- let data = "For this sample, this 63-byte string will be used as input data".data(using: .utf8)!
-
- let digest = SHA256.hash(data: data)
-
- // Verify the hash digest matches the expected output
- XCTAssertEqual(expectedHashDigest, String(bytes: Array(digest)))
- }
-
- func testShaHashDigest() {
- let expectedHash = try! "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342".bytes
- let data = "For this sample, this 63-byte string will be used as input data".data(using: .utf8)!
-
- let digest = SHA256.hash(data: data)
-
- let constructedDigest = HashDigest(expectedHash)
-
- // Verify the generated hash digest matches the manual constructed hash digest
- XCTAssertEqual(String(bytes: Array(digest)), String(bytes: Array(constructedDigest)))
- }
-
- func testSigning() {
- let expectedDerSignature = "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A=="
- let expectedSignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVg=="
- let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let signature = try! privateKey.signature(for: messageData)
-
- // Verify the signature matches the expected output
- XCTAssertEqual(expectedSignature, signature.dataRepresentation.base64EncodedString())
- XCTAssertEqual(expectedDerSignature, try! signature.derRepresentation.base64EncodedString())
- }
-
- func testRecoverySigning() {
- let expectedDerSignature = "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A=="
- let expectedRecoverySignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE="
- let expectedSignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVg=="
- let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Recovery.PrivateKey(dataRepresentation: privateKeyBytes)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let recoverySignature = try! privateKey.signature(for: messageData)
-
- // Verify the recovery signature matches the expected output
- XCTAssertEqual(expectedRecoverySignature, recoverySignature.dataRepresentation.base64EncodedString())
-
- let signature = try! recoverySignature.normalize
-
- // Verify the signature matches the expected output
- XCTAssertEqual(expectedSignature, signature.dataRepresentation.base64EncodedString())
- XCTAssertEqual(expectedDerSignature, try! signature.derRepresentation.base64EncodedString())
- }
-
- func testPublicKeyRecovery() {
- let expectedRecoverySignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE="
- let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Recovery.PrivateKey(dataRepresentation: privateKeyBytes)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let recoverySignature = try! privateKey.signature(for: messageData)
-
- // Verify the recovery signature matches the expected output
- XCTAssertEqual(expectedRecoverySignature, recoverySignature.dataRepresentation.base64EncodedString())
-
- let publicKey = try! secp256k1.Recovery.PublicKey(messageData, signature: recoverySignature)
-
- // Verify the recovered public key matches the expected public key
- XCTAssertEqual(publicKey.dataRepresentation, privateKey.publicKey.dataRepresentation)
- }
-
- func testSchnorrSigning() {
- let expectedDerSignature = "6QeDH4CEjRBppTcbQCQQNkvfHF+DB7AITFXxzi3KghUl9mpKheqLceSCp084LSzl6+7o/bIXL0d99JANMQU2wA=="
- let expectedSignature = "e907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca821525f66a4a85ea8b71e482a74f382d2ce5ebeee8fdb2172f477df4900d310536c0"
- let expectedPrivateKey = "0000000000000000000000000000000000000000000000000000000000000003"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
- var messageDigest = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
-
- var auxRand = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
-
- let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
-
- // Verify the signature matches the expected output
- XCTAssertEqual(expectedSignature, String(bytes: Array(signature.dataRepresentation)))
- XCTAssertEqual(expectedDerSignature, signature.dataRepresentation.base64EncodedString())
- }
-
- func testVerifying() {
- let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let signature = try! privateKey.signature(for: messageData)
-
- // Test the verification of the signature output
- XCTAssertTrue(privateKey.publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)))
- }
-
- func testSchnorrVerifyingPre() {
- let expectedPrivateKey = "4894b8087f428971b55ff96e16f7127340138bc84e7973821a224cad02055975"
- let expectedSignature = "ad57c21d383ef8ac799adfd469a221c40ef9f09563a16682b9ab1edc46c33d6d6a1d719761d269e87ab971e0ffafc1618a4666a4f9aef4abddc3ea9fc0cd5b12"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let throwKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
- let privateKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
- var messageDigest = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!.bytes
- var auxRand = try! "f50c8c99e39a82f125fa83186b5f2483f39fb0fb56269c755689313a177be6ea".bytes
-
- let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
-
- // Test the verification of the signature output
- XCTAssertEqual(expectedSignature, String(bytes: signature.dataRepresentation.bytes))
- XCTAssertTrue(privateKey.xonly.isValid(signature, for: &messageDigest))
- XCTAssertThrowsError(try throwKey.signature(message: &messageDigest, auxiliaryRand: &auxRand, strict: true))
- }
-
- func testSchnorrVerifying() {
- let expectedPrivateKey = "0000000000000000000000000000000000000000000000000000000000000003"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
- var messageDigest = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
- var auxRand = try! "0000000000000000000000000000000000000000000000000000000000000000".bytes
-
- let signature = try! privateKey.signature(message: &messageDigest, auxiliaryRand: &auxRand)
-
- // Test the verification of the signature output
- XCTAssertTrue(privateKey.xonly.isValid(signature, for: &messageDigest))
- }
-
- func testVerifyingDER() {
- let expectedDerSignature = Data(base64Encoded: "MEQCIHS177uYACnX8HzD+hGbG5X/F4iHuRm2DvTylOCV4fmsAiBWbj0MDud/oVzRqL87JjZpCN+kLl8Egcc/GiOigWJg+A==", options: .ignoreUnknownCharacters)!
- let expectedPrivateKey = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let signature = try! secp256k1.Signing.ECDSASignature(derRepresentation: expectedDerSignature)
-
- // Test the verification of the signature output
- XCTAssertTrue(privateKey.publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)))
- }
-
- func testPrivateKey() {
- XCTAssertNoThrow(try secp256k1.Signing.PrivateKey())
- }
-
- func testCompressedPublicKey() {
- let privateKey = try! secp256k1.Signing.PrivateKey()
-
- XCTAssertEqual(privateKey.publicKey.format, .compressed)
- XCTAssertEqual(privateKey.publicKey.dataRepresentation.count, secp256k1.Format.compressed.length)
- }
-
- func testUncompressedPublicKey() {
- let privateKey = try! secp256k1.Signing.PrivateKey(format: .uncompressed)
-
- XCTAssertEqual(privateKey.publicKey.format, .uncompressed)
- XCTAssertEqual(privateKey.publicKey.dataRepresentation.count, secp256k1.Format.uncompressed.length)
- }
-
- func testUncompressedPublicKeyWithKey() {
- let privateBytes = try! "703d3b63e84421e59f9359f8b27c25365df9d85b6b1566e3168412fa599c12f4".bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateBytes, format: .uncompressed)
-
- XCTAssertEqual(privateKey.publicKey.format, .uncompressed)
- XCTAssertEqual(privateKey.publicKey.dataRepresentation.count, secp256k1.Format.uncompressed.length)
-
- let expectedPublicKeyString = """
- 04c9c68596824505dd6cd1993a16452b4b1a13bacde56f80e9049fd03850cce137c1fa4acb7bef7edcc04f4fa29e071ea17e34fa07fa5d87b5ebf6340df6558498
- """
-
- // Define the expected public key
- let expectedPublicKey = try! expectedPublicKeyString.bytes
-
- // Verify the generated public key matches the expected public key
- XCTAssertEqual(expectedPublicKey, privateKey.publicKey.bytes)
- XCTAssertEqual(expectedPublicKeyString, String(bytes: privateKey.publicKey.bytes))
- }
-
- func testInvalidRawSignature() {
- XCTAssertThrowsError(
- try secp256k1.Signing.ECDSASignature(dataRepresentation: Data()),
- "Thrown Error", { error in
- XCTAssertEqual(error as? secp256k1Error, secp256k1Error.incorrectParameterSize)
- }
- )
- }
-
- func testInvalidDerSignature() {
- XCTAssertThrowsError(
- try secp256k1.Signing.ECDSASignature(derRepresentation: Data()),
- "Thrown Error", { error in
- XCTAssertEqual(error as? secp256k1Error, secp256k1Error.underlyingCryptoError)
- }
- )
- }
-
- func testInvalidPrivateKeyBytes() {
- let expectedPrivateKey = "55f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
-
- XCTAssertThrowsError(try expectedPrivateKey.bytes)
- }
-
- func testInvalidPrivateKeyLength() {
- let expectedPrivateKey = "555f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
- let privateKeyBytes = try! expectedPrivateKey.bytes
-
- XCTAssertThrowsError(
- try secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes),
- "Thrown Error", { error in
- XCTAssertEqual(error as? secp256k1Error, secp256k1Error.incorrectKeySize)
- }
- )
- }
-
- func testKeypairSafeCompare() {
- let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
- var privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey0 = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
- let privateKey1 = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
-
- // Verify the keys match
- XCTAssertEqual(privateKey0, privateKey1)
-
- let expectedFailingPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888dd"
- privateKeyBytes = try! expectedFailingPrivateKey.bytes
- let privateKey2 = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
-
- XCTAssertNotEqual(privateKey0, privateKey2)
- }
-
- func testZeroization() {
- var array: [UInt8] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
-
- memset_s(&array, array.capacity, 0, array.capacity)
-
- let set0 = Set(array)
-
- array = [UInt8](repeating: 1, count: Int.random(in: 10...100_000))
-
- XCTAssertGreaterThan(array.count, 9)
-
- memset_s(&array, array.capacity, 0, array.capacity)
-
- let set1 = Set(array)
-
- XCTAssertEqual(set0.first, 0)
- XCTAssertEqual(set0.count, 1)
- XCTAssertEqual(set0, set1)
- }
-
- func testPrivateKeyTweakAdd() {
- let expectedPrivateKey = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
- let expectedPublicKey = "023521df7b94248ffdf0d37f738a4792cc3932b6b1b89ef71cddde8251383b26e7"
- let expectedTweakedPrivateKey = "5f0da318c6e02f653a789950e55756ade9f194e1ec228d7f368de1bd821322b6"
- let privateKeyBytes = try! expectedPrivateKey.bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes)
- let tweak = SHA256.hash(data: expectedPrivateKey.data(using: .utf8)!)
-
- // tweak the private key
- let tweakedPrivateKey = try! privateKey.add(xonly: Array(tweak))
-
- // Verify the keys matches the expected keys output
- XCTAssertEqual(String(bytes: tweakedPrivateKey.dataRepresentation), expectedTweakedPrivateKey)
- XCTAssertEqual(expectedPublicKey, String(bytes: privateKey.publicKey.dataRepresentation))
- }
-
- func testKeyAgreement() {
- let privateString1 = "7da12cc39bb4189ac72d34fc2225df5cf36aaacdcac7e5a43963299bc8d888ed"
- let privateString2 = "5f6d5afecc677d66fb3d41eee7a8ad8195659ceff588edaf416a9a17daf38fdd"
-
- let privateBytes1 = try! privateString1.bytes
- let privateBytes2 = try! privateString2.bytes
-
- let privateKey1 = try! secp256k1.KeyAgreement.PrivateKey(dataRepresentation: privateBytes1)
- let privateKey2 = try! secp256k1.KeyAgreement.PrivateKey(dataRepresentation: privateBytes2)
-
- let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey, format: .uncompressed)
- let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: privateKey1.publicKey, format: .uncompressed)
-
- XCTAssertEqual(sharedSecret1.bytes, sharedSecret2.bytes)
- }
-
- func testKeyAgreementHashFunction() {
- let context = secp256k1.Context.rawRepresentation
- let privateKey1 = try! secp256k1.KeyAgreement.PrivateKey()
- let privateKey2 = try! secp256k1.KeyAgreement.PrivateKey()
-
- var pub = secp256k1_pubkey()
- let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey)
- var sharedSecret2 = [UInt8](repeating: 0, count: 32)
-
- XCTAssertEqual(secp256k1_ec_pubkey_parse(context, &pub, privateKey1.publicKey.bytes, privateKey1.publicKey.bytes.count), 1)
- XCTAssertEqual(secp256k1_ecdh(context, &sharedSecret2, &pub, privateKey2.baseKey.key.bytes, nil, nil), 1)
-
- let symmerticKey = SHA256.hash(data: sharedSecret1.bytes)
-
- XCTAssertEqual(symmerticKey.bytes, sharedSecret2)
- }
-
- func testKeyAgreementPublicKeyTweakAdd() {
- let privateSign1 = try! secp256k1.Signing.PrivateKey()
- let privateSign2 = try! secp256k1.Signing.PrivateKey()
-
- let privateKey1 = try! secp256k1.KeyAgreement.PrivateKey(dataRepresentation: privateSign1.dataRepresentation)
- let privateKey2 = try! secp256k1.KeyAgreement.PrivateKey(dataRepresentation: privateSign2.dataRepresentation)
-
- let publicKey1 = try! secp256k1.KeyAgreement.PublicKey(dataRepresentation: privateKey1.publicKey.dataRepresentation)
-
- let sharedSecret1 = try! privateKey1.sharedSecretFromKeyAgreement(with: privateKey2.publicKey)
- let sharedSecret2 = try! privateKey2.sharedSecretFromKeyAgreement(with: publicKey1)
-
- XCTAssertEqual(sharedSecret1.bytes, sharedSecret2.bytes)
-
- let symmetricKey1 = SHA256.hash(data: sharedSecret1.bytes)
- let symmetricKey2 = SHA256.hash(data: sharedSecret2.bytes)
-
- let sharedSecretSign1 = try! secp256k1.Signing.PrivateKey(dataRepresentation: symmetricKey1.bytes)
- let sharedSecretSign2 = try! secp256k1.Signing.PrivateKey(dataRepresentation: symmetricKey2.bytes)
-
- let privateTweak1 = try! sharedSecretSign1.add(xonly: privateSign1.publicKey.xonly.bytes)
- let publicTweak2 = try! sharedSecretSign2.publicKey.add(privateSign1.publicKey.xonly.bytes)
-
- let schnorrPrivate = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: sharedSecretSign2.dataRepresentation)
- let xonlyTweak2 = try! schnorrPrivate.xonly.add(privateSign1.publicKey.xonly.bytes)
-
- if sharedSecretSign2.publicKey.xonly.parity {
- XCTAssertNotEqual(privateTweak1.publicKey.dataRepresentation, publicTweak2.dataRepresentation)
- } else {
- XCTAssertEqual(privateTweak1.publicKey.dataRepresentation, publicTweak2.dataRepresentation)
- }
-
- XCTAssertEqual(privateTweak1.publicKey.xonly.bytes, xonlyTweak2.bytes)
- }
-
- func testXonlyToPublicKey() {
- let privateKey = try! secp256k1.Signing.PrivateKey()
- let publicKey = secp256k1.Signing.PublicKey(xonlyKey: privateKey.publicKey.xonly)
-
- XCTAssertEqual(privateKey.publicKey.dataRepresentation, publicKey.dataRepresentation)
- }
-
- func testTapscript() {
- let OP_CHECKSEQUENCEVERIFY = Data([0xB2])
- let OP_DROP = Data([0x75])
- let OP_CHECKSIG = Data([0xAC])
- let OP_SHA256 = Data([0xA8])
- let OP_EQUALVERIFY = Data([0x88])
-
- var value = UInt64(144)
- let numberOfBytes = ((64 - value.leadingZeroBitCount) / 8) + 1
- let array = withUnsafeBytes(of: &value) { Array($0).prefix(numberOfBytes) }
-
- let aliceBytes = try! "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90".bytes
- let alice = try! secp256k1.Signing.PrivateKey(dataRepresentation: aliceBytes)
- let aliceScript = Data([UInt8(array.count)] + array) +
- OP_CHECKSEQUENCEVERIFY +
- OP_DROP +
- Data([UInt8(alice.publicKey.xonly.bytes.count)] + alice.publicKey.xonly.bytes) +
- OP_CHECKSIG
- let aliceLeafHash = try! SHA256.taggedHash(
- tag: "TapLeaf".data(using: .utf8)!,
- data: Data([0xC0]) + aliceScript.compactSizePrefix
- )
-
- let aliceExpectedLeafHash = "c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9"
-
- XCTAssertEqual(String(bytes: Array(aliceLeafHash).bytes), aliceExpectedLeafHash)
-
- let bobBytes = try! "81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9".bytes
- let bob = try! secp256k1.Signing.PrivateKey(dataRepresentation: bobBytes)
- let preimageBytes = try! "6c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd5333".bytes
- let bobScript = OP_SHA256 +
- Data([UInt8(preimageBytes.count)] + preimageBytes.bytes) +
- OP_EQUALVERIFY +
- Data([UInt8(bob.publicKey.xonly.bytes.count)] + bob.publicKey.xonly.bytes) +
- OP_CHECKSIG
- let bobLeafHash = try! SHA256.taggedHash(
- tag: "TapLeaf".data(using: .utf8)!,
- data: Data([0xC0]) + bobScript.compactSizePrefix
- )
-
- let bobExpectedLeafHash = "632c8632b4f29c6291416e23135cf78ecb82e525788ea5ed6483e3c6ce943b42"
-
- XCTAssertEqual(String(bytes: Array(bobLeafHash).bytes), bobExpectedLeafHash)
-
- var leftHash, rightHash: Data
- if aliceLeafHash < bobLeafHash {
- leftHash = Data(aliceLeafHash)
- rightHash = Data(bobLeafHash)
- } else {
- leftHash = Data(bobLeafHash)
- rightHash = Data(aliceLeafHash)
- }
-
- let merkleRoot = try! SHA256.taggedHash(
- tag: "TapBranch".data(using: .utf8)!,
- data: leftHash + rightHash
- )
-
- let expectedMerkleRoot = "41646f8c1fe2a96ddad7f5471bc4fee7da98794ef8c45a4f4fc6a559d60c9f6b"
-
- XCTAssertEqual(String(bytes: Array(merkleRoot).bytes), expectedMerkleRoot)
- }
-
- func testCompactSizePrefix() {
- let bytes = try! "c15bf08d58a430f8c222bffaf9127249c5cdff70a2d68b2b45637eb662b6b88eb5c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9".bytes
- let compactBytes = "41c15bf08d58a430f8c222bffaf9127249c5cdff70a2d68b2b45637eb662b6b88eb5c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9"
- XCTAssertEqual(compactBytes, String(bytes: Array(Data(bytes).compactSizePrefix)), "Compact size prefix encoding is incorrect.")
- }
-
- func testSchnorrNegating() {
- let privateBytes = try! "56baa476b36a5b1548279f5bf57b82db39e594aee7912cde30977b8e80e6edca".bytes
- let negatedBytes = try! "a9455b894c95a4eab7d860a40a847d2380c94837c7b7735d8f3ae2fe4f4f5377".bytes
-
- let privateKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateBytes)
- let negatedKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: negatedBytes).negation
-
- XCTAssertEqual(privateKey, negatedKey)
- XCTAssertEqual(privateKey.dataRepresentation, negatedKey.dataRepresentation)
- XCTAssertEqual(privateKey.xonly, negatedKey.xonly)
- XCTAssertEqual(privateKey.xonly.bytes, negatedKey.xonly.bytes)
- }
-
- func testTaprootDerivation() {
- let privateKeyBytes = try! "41F41D69260DF4CF277826A9B65A3717E4EEDDBEEDF637F212CA096576479361".bytes
- let privateKey = try! secp256k1.Schnorr.PrivateKey(dataRepresentation: privateKeyBytes)
- let internalKeyBytes = try! "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115".bytes
- let internalKey = privateKey.xonly
-
- XCTAssertEqual(internalKey.bytes, internalKeyBytes)
-
- let tweakHash = try! SHA256.taggedHash(
- tag: "TapTweak".data(using: .utf8)!,
- data: Data(internalKey.bytes)
- )
-
- let outputKeyBytes = try! "a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c".bytes
- let outputKey = try! internalKey.add(tweakHash.bytes)
-
- XCTAssertEqual(outputKey.bytes, outputKeyBytes)
- }
-
- func testPubkeyCombine() {
- let publicKeyBytes1 = try! "021b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014".bytes
- let publicKeyBytes2 = try! "0260303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752".bytes
-
- let publicKey1 = try! secp256k1.Signing.PublicKey(dataRepresentation: publicKeyBytes1, format: .compressed)
- let publicKey2 = try! secp256k1.Signing.PublicKey(dataRepresentation: publicKeyBytes2, format: .compressed)
-
- let combinedPublicKey = try! publicKey1.combine([publicKey2])
-
- // Define the expected combined key
- let expectedCombinedKey = try! "03d6a3a9d62c7650fcac18f9ee68c7a004ebad71b7581b683062213ad9f37ddb28".bytes
-
- XCTAssertEqual(combinedPublicKey.dataRepresentation.bytes, expectedCombinedKey)
- }
-
- func testPubkeyCombineBindings() {
- // Initialize context
- let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_NONE))!
-
- // Destroy context after execution
- defer { secp256k1_context_destroy(context) }
-
- // Setup private and public key variables
- var pubKeyLen = 33
- var cPubKey1 = secp256k1_pubkey()
- var cPubKey2 = secp256k1_pubkey()
-
- let publicKeyBytes1 = try! "021b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014".bytes
- let publicKeyBytes2 = try! "0260303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752".bytes
-
- // Verify the context and keys are setup correctly
- XCTAssertEqual(secp256k1_ec_pubkey_parse(context, &cPubKey1, publicKeyBytes1, pubKeyLen), 1)
- XCTAssertEqual(secp256k1_ec_pubkey_parse(context, &cPubKey2, publicKeyBytes2, pubKeyLen), 1)
-
- let pubKeys: [UnsafePointer?] = [UnsafePointer(&cPubKey1), UnsafePointer(&cPubKey2)]
- var combinedKey = secp256k1_pubkey()
- var combinedKeyBytes = [UInt8](repeating: 0, count: pubKeyLen)
-
- // Combine the two public keys
- XCTAssertEqual(secp256k1_ec_pubkey_combine(context, &combinedKey, pubKeys, 2), 1)
- XCTAssertEqual(secp256k1_ec_pubkey_serialize(context, &combinedKeyBytes, &pubKeyLen, &combinedKey, secp256k1.Format.compressed.rawValue), 1)
-
- // Define the expected combined key
- let expectedCombinedKey = try! "03d6a3a9d62c7650fcac18f9ee68c7a004ebad71b7581b683062213ad9f37ddb28".bytes
-
- XCTAssertEqual(combinedKeyBytes, expectedCombinedKey)
- }
-
- func testPrivateKeyPEM() {
- let privateKeyString = """
- -----BEGIN EC PRIVATE KEY-----
- MHQCAQEEIBXwHPDpec6b07GeLbnwetT0dvWzp0nV3MR+4pPKXIc7oAcGBSuBBAAK
- oUQDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMAcjHIrTDS6HEELgguOatmFBOp
- 2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
- -----END EC PRIVATE KEY-----
- """
-
- let privateKey = try! secp256k1.Signing.PrivateKey(pemRepresentation: privateKeyString)
- let expectedPrivateKey = "15f01cf0e979ce9bd3b19e2db9f07ad4f476f5b3a749d5dcc47ee293ca5c873b"
-
- // Verify the keys matches the expected keys output
- XCTAssertEqual(expectedPrivateKey, String(bytes: privateKey.dataRepresentation))
- }
-
- func testPublicKeyPEM() {
- let publicKeyString = """
- -----BEGIN PUBLIC KEY-----
- MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMA
- cjHIrTDS6HEELgguOatmFBOp2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
- -----END PUBLIC KEY-----
- """
-
- let privateKeyBytes = try! "15f01cf0e979ce9bd3b19e2db9f07ad4f476f5b3a749d5dcc47ee293ca5c873b".bytes
- let privateKey = try! secp256k1.Signing.PrivateKey(dataRepresentation: privateKeyBytes, format: .uncompressed)
- let publicKey = try! secp256k1.Signing.PublicKey(pemRepresentation: publicKeyString)
-
- // Verify the keys matches the expected keys output
- XCTAssertEqual(privateKey.publicKey.dataRepresentation, publicKey.dataRepresentation)
- }
-
- func testSigningPEM() {
- let privateKeyString = """
- -----BEGIN EC PRIVATE KEY-----
- MHQCAQEEIBXwHPDpec6b07GeLbnwetT0dvWzp0nV3MR+4pPKXIc7oAcGBSuBBAAK
- oUQDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMAcjHIrTDS6HEELgguOatmFBOp
- 2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
- -----END EC PRIVATE KEY-----
- """
-
- let expectedDerSignature = "MEQCIC8k5whKPsPg7XtWTInvhGL4iEU6lP6yPdpEXXZ2mOhFAiAZ3Po9tEDV8mQ8LDzwF0nhPmAn9VLYG8bkuY6PKruZNQ=="
- let privateKey = try! secp256k1.Signing.PrivateKey(pemRepresentation: privateKeyString)
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
-
- let signature = try! privateKey.signature(for: messageData)
-
- // Verify the signature matches the expected output
- XCTAssertEqual(expectedDerSignature, try! signature.derRepresentation.base64EncodedString())
- }
-
- func testVerifyingPEM() {
- let publicKeyString = """
- -----BEGIN PUBLIC KEY-----
- MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEt2uDn+2GqqYs/fmkBr5+rCQ3oiFSIJMA
- cjHIrTDS6HEELgguOatmFBOp2wU4P2TAl/0Ihiq+nMkrAIV69m2W8g==
- -----END PUBLIC KEY-----
- """
-
- let expectedSignature = "MEQCIEwVxXLE/mwaRzxLvz9VIcMtHaa/Wf1WRxiBJ6NEuWHeAiAQWf2oqqBqEtBABbmwsXqjCJFvsaPt8o+VaOthto1kWQ=="
- let expectedDerSignature = Data(base64Encoded: expectedSignature, options: .ignoreUnknownCharacters)!
-
- let messageData = "We're all Satoshi Nakamoto and a bit of Harold Thomas Finney II.".data(using: .utf8)!
- let signature = try! secp256k1.Signing.ECDSASignature(derRepresentation: expectedDerSignature)
- let publicKey = try! secp256k1.Signing.PublicKey(pemRepresentation: publicKeyString)
-
- XCTAssertTrue(publicKey.isValidSignature(signature, for: SHA256.hash(data: messageData)))
- }
-
- func testMusig() throws {
- // Test MuSig aggregate
- let privateKeys = [
- try secp256k1.Schnorr.PrivateKey(),
- try secp256k1.Schnorr.PrivateKey(),
- try secp256k1.Schnorr.PrivateKey()
- ]
-
- let publicKeys = privateKeys.map(\.publicKey)
- let aggregate = try secp256k1.MuSig.aggregate(publicKeys)
-
- // Create a message to sign
- let message = "Hello, MuSig!".data(using: .utf8)!
- let messageHash = SHA256.hash(data: message)
-
- // Generate nonces for each signer
- let firstNonce = try secp256k1.MuSig.Nonce.generate(
- secretKey: privateKeys[0],
- publicKey: privateKeys[0].publicKey,
- msg32: Array(messageHash)
- )
-
- let secondNonce = try secp256k1.MuSig.Nonce.generate(
- secretKey: privateKeys[1],
- publicKey: privateKeys[1].publicKey,
- msg32: Array(messageHash)
- )
-
- let thirdNonce = try secp256k1.MuSig.Nonce.generate(
- secretKey: privateKeys[2],
- publicKey: privateKeys[2].publicKey,
- msg32: Array(messageHash)
- )
-
- // Extract public nonces
- let publicNonces = [firstNonce.pubnonce, secondNonce.pubnonce, thirdNonce.pubnonce]
-
- // Aggregate public nonces
- let aggregateNonce = try secp256k1.MuSig.Nonce(aggregating: publicNonces)
-
- // Create partial signatures
- let firstPartialSignature = try privateKeys[0].partialSignature(
- for: messageHash,
- pubnonce: firstNonce.pubnonce,
- secureNonce: firstNonce.secnonce,
- publicNonceAggregate: aggregateNonce,
- publicKeyAggregate: aggregate
- )
-
- let secondPartialSignature = try privateKeys[1].partialSignature(
- for: messageHash,
- pubnonce: secondNonce.pubnonce,
- secureNonce: secondNonce.secnonce,
- publicNonceAggregate: aggregateNonce,
- publicKeyAggregate: aggregate
- )
-
- let thirdPartialSignature = try privateKeys[2].partialSignature(
- for: messageHash,
- pubnonce: thirdNonce.pubnonce,
- secureNonce: thirdNonce.secnonce,
- publicNonceAggregate: aggregateNonce,
- publicKeyAggregate: aggregate
- )
-
- // Expected error when uncommented
-// let forthPartialSignature = try privateKeys[1].partialSignature(
-// for: messageHash,
-// pubnonce: thirdNonce.pubnonce,
-// secureNonce: thirdNonce.secnonce,
-// publicNonceAggregate: aggregateNonce,
-// publicKeyAggregate: aggregate
-// )
-
- // Aggregate partial signatures
- _ = try secp256k1.MuSig.aggregateSignatures([firstPartialSignature, secondPartialSignature, thirdPartialSignature])
-
- // Verify the signature
- XCTAssertTrue(
- aggregate.isValidSignature(
- firstPartialSignature,
- publicKey: publicKeys.first!,
- nonce: publicNonces.first!,
- for: messageHash
- )
- )
- }
-
- static let allTests = [
- ("testUncompressedKeypairCreation", testUncompressedKeypairCreation),
- ("testCompressedKeypairCreation", testCompressedKeypairCreation),
- ("testECDHBindings", testECDHBindings),
- ("testExtraKeysBindings", testExtraKeysBindings),
- ("testRecoveryBindings", testRecoveryBindings),
- ("testSchnorrBindings", testSchnorrBindings),
- ("testCompressedKeypairImplementationWithRaw", testCompressedKeypairImplementationWithRaw),
- ("testSha256", testSha256),
- ("testShaHashDigest", testShaHashDigest),
- ("testRecoverySigning", testRecoverySigning),
- ("testPublicKeyRecovery", testPublicKeyRecovery),
- ("testSigning", testSigning),
- ("testSchnorrSigning", testSchnorrSigning),
- ("testVerifying", testVerifying),
- ("testSchnorrVerifyingPre", testSchnorrVerifyingPre),
- ("testSchnorrVerifying", testSchnorrVerifying),
- ("testVerifyingDER", testVerifyingDER),
- ("testPrivateKey", testPrivateKey),
- ("testCompressedPublicKey", testCompressedPublicKey),
- ("testUncompressedPublicKey", testUncompressedPublicKey),
- ("testUncompressedPublicKeyWithKey", testUncompressedPublicKeyWithKey),
- ("testInvalidRawSignature", testInvalidRawSignature),
- ("testInvalidDerSignature", testInvalidDerSignature),
- ("testInvalidPrivateKeyBytes", testInvalidPrivateKeyBytes),
- ("testInvalidPrivateKeyLength", testInvalidPrivateKeyLength),
- ("testKeypairSafeCompare", testKeypairSafeCompare),
- ("testZeroization", testZeroization),
- ("testPrivateKeyTweakAdd", testPrivateKeyTweakAdd),
- ("testKeyAgreement", testKeyAgreement),
- ("testKeyAgreementHashFunction", testKeyAgreementHashFunction),
- ("testKeyAgreementPublicKeyTweakAdd", testKeyAgreementPublicKeyTweakAdd),
- ("testXonlyToPublicKey", testXonlyToPublicKey),
- ("testTapscript", testTapscript),
- ("testCompactSizePrefix", testCompactSizePrefix),
- ("testSchnorrNegating", testSchnorrNegating),
- ("testTaprootDerivation", testTaprootDerivation),
- ("testPubkeyCombine", testPubkeyCombine),
- ("testPubkeyCombineBindings", testPubkeyCombineBindings),
- ("testPrivateKeyPEM", testPrivateKeyPEM),
- ("testPublicKeyPEM", testPublicKeyPEM),
- ("testSigningPEM", testSigningPEM),
- ("testVerifyingPEM", testVerifyingPEM),
- ("testMusig", testMusig)
- ]
-}
diff --git a/bitrise.yml b/bitrise.yml
index f8065075..06482e86 100644
--- a/bitrise.yml
+++ b/bitrise.yml
@@ -4,34 +4,34 @@ default_step_lib_source: 'https://github.com/bitrise-io/bitrise-steplib.git'
project_type: other
meta:
bitrise.io:
- stack: osx-xcode-16.0.x
- machine_type_id: g2-m1.4core
+ stack: osx-xcode-16.2.x
+ machine_type_id: g2.mac.medium
trigger_map:
- push_branch: main
- pipeline: PIPELINE-SECP256K1-ZKP
+ pipeline: PIPELINE-P256K-ZKP
- pull_request_source_branch: '*'
- pipeline: PIPELINE-SECP256K1-ZKP
+ pipeline: PIPELINE-P256K-ZKP
pipelines:
- PIPELINE-SECP256K1-ZKP:
+ PIPELINE-P256K-ZKP:
stages:
- CLONE: {}
- - SECP256K1: {}
+ - P256K: {}
- ZKP: {}
stages:
CLONE:
workflows:
- - SECP256K1-SWIFT: {}
- SECP256K1:
+ - SWIFT-SECP256K1: {}
+ P256K:
workflows:
- - BUILD-SECP256K1: {}
+ - BUILD-P256K: {}
ZKP:
workflows:
- BUILD-ZKP: {}
workflows:
- SECP256K1-SWIFT:
+ SWIFT-SECP256K1:
steps:
- git-clone:
- title: CLONE SECP256K1.SWIFT
+ title: CLONE SWIFT-SECP256K1
timeout: 60
- script:
title: CHECK LINKS
@@ -46,7 +46,12 @@ workflows:
# It uses the find command to follow symbolic links and checks if they are
# broken with the test command. If a broken symbolic link is found, the
# script fails with a non-zero status code.
- find . -type d -name .build -prune -o -type l ! -exec test -e {} \; -print | grep -q . && exit 1 || exit 0
+ broken_links=$(find . -type d -name .build -prune -o -type l ! -exec test -e {} \; -print)
+ if [ -n "$broken_links" ]; then
+ echo "Broken symbolic links found:"
+ echo "$broken_links"
+ exit 1
+ fi
- deploy-to-bitrise-io:
inputs:
- pipeline_intermediate_files: "$BITRISE_SOURCE_DIR:BITRISE_SOURCE_DIR"
@@ -64,22 +69,130 @@ workflows:
set -ex
swift test
- BUILD-SECP256K1:
+ BUILD-P256K:
before_run:
- PULL-PACKAGE-FILES
steps:
- script:
- title: BUILD SECP256K1
- timeout: 180
+ title: BUILD & TEST P256K
+ timeout: 360
+ inputs:
+ - content: |-
+ #!/usr/bin/env bash
+ # fail if any commands fails; debug log
+ set -ex
+
+ # Swift Package Manager commands with Tuist operations for CI/CD pipeline:
+
+ # 1. Generate Xcode project:
+ # The command generates an Xcode project using Tuist for the project configuration located in the 'Projects/' directory.
+ swift package --disable-sandbox tuist generate -p Projects/ --no-open && \
+
+ # 2. Build iOS target:
+ # Builds the 'P256K' target for the iOS platform using the Tuist project configuration from 'Projects/'.
+ swift package --disable-sandbox tuist build P256K -p Projects/ --platform ios && \
+
+ # 3. Run iOS tests:
+ # Executes tests for 'XCFramework-Workspace' on the iOS platform using the Tuist setup from 'Projects/'.
+ swift package --disable-sandbox tuist test XCFramework-Workspace -p Projects/ --platform ios
+ - script:
+ title: ARCHIVE & CREATE XCFRAMEWORK
+ timeout: 720
inputs:
- content: |-
#!/usr/bin/env bash
# fail if any commands fails; debug log
set -ex
- swift test --package-path Exhaustive/Package
+ # Define workspace and scheme
+ WORKSPACE='Projects/XCFramework.xcworkspace'
+ SCHEME='P256K'
+ CONFIGURATION='Release'
+ ARCHIVE_DIR='Archives'
+
+ # Platforms to archive
+ PLATFORMS=(
+ "iOS"
+ "iOS Simulator"
+ "macOS"
+ "tvOS"
+ "tvOS Simulator"
+ "watchOS"
+ "watchOS Simulator"
+ # "visionOS"
+ )
+
+ # Loop over platforms and archive for each one
+ for PLATFORM in "${PLATFORMS[@]}"; do
+ echo "Archiving for $PLATFORM..."
+
+ # Run xcodebuild archive for each platform
+ xcodebuild archive \
+ -workspace "$WORKSPACE" \
+ -scheme "$SCHEME" \
+ -configuration "$CONFIGURATION" \
+ -destination "generic/platform=$PLATFORM" \
+ -archivePath "$ARCHIVE_DIR/P256K-$PLATFORM.xcarchive"| xcbeautify
+
+ # Check if archive command was successful
+ if [ $? -eq 0 ]; then
+ echo "$PLATFORM archive created successfully."
+ else
+ echo "Failed to archive for $PLATFORM. Exiting."
+ exit 1
+ fi
+ done
+
+ echo "All archives completed successfully."
+
+ # Create an XCFramework to support multiple platforms and architectures
+ # Each -archive parameter specifies a path to a .xcarchive built for a different platform
+ # -framework specifies the framework within those archives to include in the XCFramework
+ # The -output parameter specifies the name and location of the XCFramework to be created
+ xcodebuild -create-xcframework \
+ -archive "Archives/P256K-iOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-iOS Simulator.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-macOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-tvOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-tvOS Simulator.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-watchOS.xcarchive" -framework P256K.framework \
+ -archive "Archives/P256K-watchOS Simulator.xcarchive" -framework P256K.framework \
+ -output P256K.xcframework
+ - deploy-to-bitrise-io:
+ inputs:
+ - deploy_path: "$BITRISE_SOURCE_DIR/P256K.xcframework"
+ - is_compress: true
+ - script:
+ title: TEST XCFRAMEWORK
+ timeout: 360
+ inputs:
+ - content: |-
+ #!/usr/bin/env bash
+ # fail if any commands fails; debug log
+ set -ex
+
+ # Comment out the existing target for "P256K" in the Package.swift file.
+ sed -i '' '/\.target(name: "P256K", dependencies: \["libsecp256k1"\]),/s/^/\/\//g' Package.swift
+
+ # Add the new target for "P256K" in the Package.swift file.
+ sed -i '' '/\.target(name: "P256K", dependencies: \["libsecp256k1"\]),/a\
+ .binaryTarget(\
+ name: "P256K",\
+ path: "./P256K.xcframework"\
+ ),\
+ ' Package.swift
+
+ # Update the ZKPTests target to XCFrameworkTests and use the binary target for "P256K" in the manifest file.
+ sed -i '' \
+ -e 's/\.testTarget(name: "libsecp256k1zkpTests", dependencies: \["ZKP", "libsecp256k1_zkp"\]),/\/\/ .testTarget(name: "libsecp256k1zkpTests", dependencies: ["ZKP", "libsecp256k1_zkp"]),/' \
+ -e 's/\.testTarget(name: "ZKPTests", dependencies: \["ZKP"\])/\.testTarget(name: "XCFrameworkTests", dependencies: \["P256K"\])/' \
+ Package.swift
+
+ # Run swift tests after modifying the Package.swift, allowing verification
+ # of the setup with the newly integrated XCFramework.
+ swift test
PULL-PACKAGE-FILES:
steps:
- pull-intermediate-files:
inputs:
- - artifact_sources: CLONE.SECP256K1-SWIFT
+ - artifact_sources: CLONE.SWIFT-SECP256K1