Skip to content

Commit

Permalink
feat: add sha3
Browse files Browse the repository at this point in the history
includes fix for encryption
  • Loading branch information
metalurgical committed Apr 16, 2024
1 parent 7dad3bf commit aaa984e
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 34 deletions.
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")
}
}

0 comments on commit aaa984e

Please sign in to comment.