Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sha3 #7

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ let package = Package(
.library(
name: "curveSecp256k1",
targets: ["curveSecp256k1"]),

.library(
name: "encryption_aes_cbc_sha512",
targets: ["encryption_aes_cbc_sha512"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All @@ -36,16 +32,10 @@ let package = Package(
.target(
name: "curveSecp256k1",
dependencies: ["curvelib"],
path: "Sources/curvelib/secp256k1"
path: "Sources/curvelib"
),
.target(
name: "encryption_aes_cbc_sha512",
dependencies: ["curvelib", "curveSecp256k1"],
path: "Sources/curvelib/encryption"
),

.testTarget(
name: "curvelibTests",
dependencies: ["curveSecp256k1", "encryption_aes_cbc_sha512"]),
dependencies: ["curveSecp256k1"]),
]
)
10 changes: 5 additions & 5 deletions Sources/curve_secp256k1/curve_secp256k1.xcframework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@
<key>BinaryPath</key>
<string>libsecp256k1_rs.a</string>
<key>LibraryIdentifier</key>
<string>macos-arm64_x86_64</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libsecp256k1_rs.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>libsecp256k1_rs.a</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>macos-arm64_x86_64</string>
<key>LibraryPath</key>
<string>libsecp256k1_rs.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<string>macos</string>
</dict>
<dict>
<key>BinaryPath</key>
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion Sources/curve_secp256k1/include/curve_secp256k1.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ char *curve_secp256k1_encrypted_message_get_mac(struct EncryptedMessage *message
char *curve_secp256k1_encrypted_message_get_iv(struct EncryptedMessage *message,int* error_code);
void curve_secp256k1_encrypted_message_free(struct EncryptedMessage *message);
struct EncryptedMessage *curve_secp256k1_aes_cbc_hmac_encrypt(struct PublicKey *public_key, char *plain_text, int *error_code);
char *curve_secp256k1_aes_cbc_hmac_decrypt(struct SecretKey* secret_key, struct EncryptedMessage* encrypted, int* error_code );
char *curve_secp256k1_aes_cbc_hmac_decrypt(struct SecretKey* secret_key, struct EncryptedMessage* encrypted, bool skip_mac_check, int* error_code );

char *curve_sha3_keccak256(char *hex_data, int *error_code);

#ifdef __cplusplus
} // extern "C"
Expand Down
28 changes: 28 additions & 0 deletions Sources/curvelib/Extensions/Data+extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation

public extension Data {
var hexString: String {
return map { String(format: "%02x", $0) }.joined()
}

init?(hexString: String) {
// Ensure the string has an even number of characters
guard hexString.count % 2 == 0 else { return nil }

var data = Data(capacity: hexString.count / 2)

// Convert each pair of characters to a byte and append to data
var index = hexString.startIndex
while index < hexString.endIndex {
let nextIndex = hexString.index(index, offsetBy: 2)
if let byte = UInt8(hexString[index..<nextIndex], radix: 16) {
data.append(byte)
} else {
return nil // Invalid hexadecimal character
}
index = nextIndex
}

self = data
}
}
1 change: 0 additions & 1 deletion Sources/curvelib/encryption/EncryptedMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Foundation
#if canImport(curvelib)
import curvelib
#endif
import curveSecp256k1

public final class EncryptedMessage {
private(set) var pointer: OpaquePointer?
Expand Down
26 changes: 15 additions & 11 deletions Sources/curvelib/encryption/Encryption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,39 @@ import Foundation
#if canImport(curvelib)
import curvelib
#endif
import curveSecp256k1

public final class Encryption {
public static func encrypt(pk: PublicKey, plainText: String) throws -> EncryptedMessage {
public static func encrypt(pk: PublicKey, plainText: Data) throws -> EncryptedMessage {
var errorCode: Int32 = -1
let stringPtr = UnsafeMutablePointer<Int8>(mutating: (plainText as NSString).utf8String)
let stringPtr = UnsafeMutablePointer<Int8>(mutating: (plainText.hexString as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
curve_secp256k1_aes_cbc_hmac_encrypt(pk.pointer, stringPtr, error)
})

guard errorCode == 0 else {
throw CurveError(code: errorCode)
}

return EncryptedMessage(ptr: result!)
}
public static func decrypt(sk: SecretKey, encrypted: EncryptedMessage) throws -> String {

public static func decrypt(sk: SecretKey, encrypted: EncryptedMessage, skipMacCheck: Bool = false) throws -> Data {
var errorCode: Int32 = -1
let result = withUnsafeMutablePointer(to: &errorCode, { error in
curve_secp256k1_aes_cbc_hmac_decrypt(sk.pointer, encrypted.pointer, error)
curve_secp256k1_aes_cbc_hmac_decrypt(sk.pointer, encrypted.pointer, skipMacCheck, error)
})

guard errorCode == 0 else {
throw CurveError(code: errorCode)
}

let value = String(cString: result!)
curve_secp256k1_string_free(result)
return value

guard let result = Data(hexString: value) else {
throw CurveError(code: 3)
}

return result
}
}
2 changes: 1 addition & 1 deletion Sources/curvelib/secp256k1/CurveError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct CurveError: Error, LocalizedError {
case unknownStatusCode
}

private(set) var type: ErrorType
private(set) public var type: ErrorType

public init(code: Int32) {
switch code {
Expand Down
33 changes: 33 additions & 0 deletions Sources/curvelib/sha3/Keccak.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Foundation

#if canImport(curvelib)
import curvelib
#endif

public func keccak256 ( data : Data ) throws -> Data {
var errorCode: Int32 = -1
let hexPtr = UnsafeMutablePointer<Int8>(mutating: (data.hexString as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
curve_sha3_keccak256(hexPtr, error)
})
guard errorCode == 0 else {
throw CurveError(code: errorCode)
}
let value = String(cString: result!)
curve_secp256k1_string_free(result)

guard let hex_data = Data(hexString: value) else {
throw CurveError(code: 3)
}
return hex_data
}

public enum Variants {
case KECCAK256
}

public extension Data {
func sha3( varient : Variants ) throws -> Data {
return try keccak256(data: self)
}
}
38 changes: 35 additions & 3 deletions Tests/curvelibTests/curvelibTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import XCTest
@testable import curveSecp256k1
@testable import encryption_aes_cbc_sha512

final class curvelibTests: XCTestCase {
func testSecretKey() throws {
Expand Down Expand Up @@ -57,13 +56,46 @@ final class curvelibTests: XCTestCase {
let sk = SecretKey()
let pk = try sk.toPublic()
let plainText = "this is testing data";
let encrypted = try Encryption.encrypt(pk: pk, plainText: plainText)
let encrypted = try Encryption.encrypt(pk: pk, plainText: plainText.data(using: .utf8)!)
let cipherText = try encrypted.chipherText()
let ephemeralPk = try encrypted.ephemeralPublicKey()
let iv = try encrypted.iv()
let mac = try encrypted.mac()
let components = try EncryptedMessage(cipherText: cipherText, ephemeralPublicKey: ephemeralPk, iv: iv, mac: mac)
let decrypted = try Encryption.decrypt(sk: sk, encrypted: components)
XCTAssertEqual(plainText, decrypted)
XCTAssertEqual(plainText.data(using: .utf8)!, decrypted)
}

func testEncryptionSkipMacCheck() throws {
let sk = SecretKey()
let pk = try sk.toPublic()
let plainText = "this is testing data";
let encrypted = try Encryption.encrypt(pk: pk, plainText: plainText.data(using: .utf8)!)
let cipherText = try encrypted.chipherText()
let ephemeralPk = try encrypted.ephemeralPublicKey()
let iv = try encrypted.iv()
let components = try EncryptedMessage(cipherText: cipherText, ephemeralPublicKey: ephemeralPk, iv: iv, mac: "")
let decrypted = try Encryption.decrypt(sk: sk, encrypted: components, skipMacCheck: true)

XCTAssertThrowsError(try Encryption.decrypt(sk: sk, encrypted: components, skipMacCheck: false))
XCTAssertEqual(plainText.data(using: .utf8)!, decrypted)
}

func testEncryptionNonUTF8() throws {
let sk = try SecretKey(hex: "8db351704caeb01a7c7ae4860f40fb46b932e4a5ecb6283cc8481126127bf67f")

let ephemeralPk = try PublicKey(hex: "0422472e27b6231cd657388711591ef86c1037207a72e063acf91c34f39a839ef259875d02b2f9348d890207f7f6e8e68e6f6983231aca2439d4faede4d1ea2920")

let components = try EncryptedMessage(cipherText: "c3a8d319f0f2b1cd5a453dc24ae76746b1039363fba4ddb065ba67ab4fd0583e8e01f327875a968b0274d05da1d3bfe2", ephemeralPublicKey: ephemeralPk, iv: "ee03ea6170dd9a43b1a7d6f52af0d7af", mac: "ef15d00f9a5ec3c8a8a2cb0724a624fc3b21db9e25ccc3318f83fbe06d8dd18d")
let decrypted = try Encryption.decrypt(sk: sk, encrypted: components, skipMacCheck: false)

print(decrypted)
}

func testkeccak256() throws {
let data = "hello world!"
let hash = try keccak256(data: data.data(using: .utf8)!)
print(hash.hexString)
XCTAssert(hash.hexString == "57caa176af1ac0433c5df30e8dabcd2ec1af1e92a26eced5f719b88458777cd6")
}
}
Loading