diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb795d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+**/xcuserdata/*
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..fc88f37
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vendor"]
+ path = vendor
+ url = git@github.com:libtom/libtommath.git
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Headers/module.modulemap b/Headers/module.modulemap
new file mode 100644
index 0000000..a6295d7
--- /dev/null
+++ b/Headers/module.modulemap
@@ -0,0 +1,4 @@
+module TomMath [extern_c] {
+ header "tommath.h"
+ export *
+}
diff --git a/Headers/tommath.h b/Headers/tommath.h
new file mode 100644
index 0000000..330b6e9
--- /dev/null
+++ b/Headers/tommath.h
@@ -0,0 +1 @@
+#include "../vendor/tommath.h"
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..582494f
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,41 @@
+// swift-tools-version:5.0
+import PackageDescription
+
+let package = Package(
+ name: "TomMath",
+ platforms: [
+ .macOS(.v10_10), .iOS(.v9), .tvOS(.v9)
+ ],
+ products: [
+ .library(
+ name: "TomMath",
+ targets: [ "TomMath" ])
+ ],
+ dependencies: [],
+ targets: [
+ .target(name: "TomMath",
+ path: ".",
+ exclude: [
+ "vendor/demo",
+ "vendor/doc",
+ "vendor/etc",
+ "vendor/logs",
+ "vendor/mtest",
+ "vendor/Package.swift",
+ ],
+ sources: [
+ "vendor"
+ ],
+ publicHeadersPath: "Headers",
+ cSettings: [
+ .unsafeFlags(["-flto=thin"]) // for Dead Code Elimination
+ ]),
+ .testTarget(name: "TomMathTests",
+ dependencies: [
+ "TomMath"
+ ],
+ path: "Tests")
+ ],
+ cLanguageStandard: .gnu11,
+ cxxLanguageStandard: .gnucxx14
+)
diff --git a/Tests/TomMathTests.swift b/Tests/TomMathTests.swift
new file mode 100644
index 0000000..3b1bb60
--- /dev/null
+++ b/Tests/TomMathTests.swift
@@ -0,0 +1,95 @@
+import XCTest
+import TomMath
+
+/* ---> Basic Manipulations <--- */
+
+extension mp_int {
+ var isZero: Bool { used == 0 }
+ var isNeg: Bool { sign == MP_NEG }
+ var isEven: Bool { used == 0 || (dp[0] & 1) == 0 }
+ var isOdd: Bool { !isEven }
+}
+
+func mp_get_u32(_ a: UnsafePointer) -> UInt32 {
+ return UInt32(bitPattern: mp_get_i32(a))
+}
+
+class TomMathTests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testTrivialStuff() throws {
+ var a = mp_int()
+ var b = mp_int()
+ var c = mp_int()
+ var d = mp_int()
+
+ XCTAssertEqual(mp_init(&a), MP_OKAY)
+ XCTAssertEqual(mp_init(&b), MP_OKAY)
+ XCTAssertEqual(mp_init(&c), MP_OKAY)
+ XCTAssertEqual(mp_init(&d), MP_OKAY)
+
+ defer {
+ mp_clear(&a)
+ mp_clear(&b)
+ mp_clear(&c)
+ mp_clear(&d)
+ }
+
+ XCTAssert(mp_error_to_string(MP_OKAY) != nil)
+
+ /* a: 0->5 */
+ mp_set(&a, 5)
+ /* a: 5-> b: -5 */
+ XCTAssertEqual(mp_neg(&a, &b), MP_OKAY)
+ XCTAssertEqual(mp_cmp(&a, &b), MP_GT)
+ XCTAssertEqual(mp_cmp(&b, &a), MP_LT)
+ XCTAssertTrue(b.isNeg)
+ /* a: 5-> a: -5 */
+ var t = a // Fix compiler error: Overlapping accesses to 'a', but modification requires exclusive access; consider copying to a local variable
+ XCTAssertEqual(mp_neg(&t, &a), MP_OKAY)
+ XCTAssertEqual(mp_cmp(&b, &a), MP_EQ)
+ XCTAssertTrue(a.isNeg)
+ /* a: -5-> b: 5 */
+ XCTAssertEqual(mp_abs(&a, &b), MP_OKAY)
+ XCTAssertTrue(!b.isNeg)
+ /* a: -5-> b: -4 */
+ XCTAssertEqual(mp_add_d(&a, 1, &b), MP_OKAY)
+ XCTAssertTrue(b.isNeg)
+ XCTAssertEqual(mp_get_i32(&b), -4)
+ XCTAssertEqual(mp_get_u32(&b), UInt32(bitPattern: -4))
+ XCTAssertEqual(mp_get_mag_u32(&b), 4)
+ /* a: -5-> b: 1 */
+ XCTAssertEqual(mp_add_d(&a, 6, &b), MP_OKAY)
+ XCTAssertEqual(mp_get_u32(&b), 1)
+ /* a: -5-> a: 1 */
+ t = a
+ XCTAssertEqual(mp_add_d(&t, 6, &a), MP_OKAY)
+ XCTAssertEqual(mp_get_u32(&a), 1)
+ mp_zero(&a);
+ /* a: 0-> a: 6 */
+ t = a
+ XCTAssertEqual(mp_add_d(&t, 6, &a), MP_OKAY)
+ XCTAssertEqual(mp_get_u32(&a), 6)
+
+ mp_set(&a, 42)
+ mp_set(&b, 1)
+ t = b
+ XCTAssertEqual(mp_neg(&t, &b), MP_OKAY)
+ mp_set(&c, 1)
+ XCTAssertEqual(mp_exptmod(&a, &b, &c, &d), MP_OKAY)
+
+ mp_set(&c, 7)
+ /* same here */
+ XCTAssertTrue(mp_exptmod(&a, &b, &c, &d) != MP_OKAY)
+
+ XCTAssertTrue(a.isEven != a.isOdd)
+ }
+}
+
diff --git a/vendor b/vendor
new file mode 160000
index 0000000..f6507b7
--- /dev/null
+++ b/vendor
@@ -0,0 +1 @@
+Subproject commit f6507b7a1bef22965dd7a0e17bd010cd16704463