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/backup share to factor key #44

Merged
merged 13 commits into from
Aug 17, 2023
23 changes: 23 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
on:
push:
branches:
- master
- v2
pull_request:
types:
- opened
- reopened
- synchronize

jobs:
test:
runs-on: macos-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "14.2.0"
- name: package
run: xcodebuild test -scheme tkey_pkg -destination "platform=iOS Simulator,OS=16.2,name=iPhone 14" COMPILER_INDEX_STORE_ENABLE=NO
22 changes: 18 additions & 4 deletions Sources/ThresholdKey/Common/KeyPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ import Foundation
import lib
#endif


public enum PublicKeyEncoding : Equatable, Hashable {
case EllipticCompress
case FullAddress

public var value : String {
switch self {
case .EllipticCompress:
return "elliptic-compressed"
case .FullAddress :
return ""
}
}
}

public final class KeyPoint: Equatable {

/// Compares two KeyPoint objects
Expand Down Expand Up @@ -66,8 +81,7 @@ public final class KeyPoint: Equatable {
/// Instantiates a `KeyPoint` object using X and Y co-ordinates in hexadecimal format.
///
/// - Parameters:
/// - x: X value of co-ordinate pair.
/// - y: Y value of co-ordinate pair.
/// - address : compress or full address
///
/// - Returns: `KeyPoint` object.
///
Expand Down Expand Up @@ -128,10 +142,10 @@ public final class KeyPoint: Equatable {
/// - Returns: Serialized form of `KeyPoint` as `String`
///
/// - Throws: `RuntimeError`, indicates either the underlying pointer is invalid or the co-ordinate pair is not a valid PublicKey.
public func getAsCompressedPublicKey(format: String) throws -> String {
public func getPublicKey(format: PublicKeyEncoding ) throws -> String {
var errorCode: Int32 = -1

let encoder_format = UnsafeMutablePointer<Int8>(mutating: (format as NSString).utf8String)
let encoder_format = UnsafeMutablePointer<Int8>(mutating: (format.value as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
key_point_encode(pointer, encoder_format, error)
})
Expand Down
6 changes: 4 additions & 2 deletions Sources/ThresholdKey/Common/PrivateKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public final class PrivateKey {
self.hex = hex
}

public func toPublic () throws -> String {
public func toPublic (format: PublicKeyEncoding = .EllipticCompress ) throws -> String {
var errorCode: Int32 = -1
let secretPointer = UnsafeMutablePointer<Int8>(mutating: (self.hex as NSString).utf8String)
let result = withUnsafeMutablePointer(to: &errorCode, { error in
Expand All @@ -39,7 +39,9 @@ public final class PrivateKey {
}
let publicHex = String.init(cString: result!)
string_free(result)
return publicHex

let publicKey = try KeyPoint(address: publicHex).getPublicKey(format: format )
return publicKey
}

/// Instantiates a `PrivateKey` object by random generation.
Expand Down
56 changes: 54 additions & 2 deletions Sources/ThresholdKey/Modules/TssModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public final class TssModule {

let nonce = String(try get_tss_nonce(threshold_key: threshold_key, tss_tag: tss_tag, prefetch: prefetch))

let public_address = try await getTssPubAddress(threshold_key: threshold_key, tssTag: tss_tag, nonce: nonce, nodeDetails: nodeDetails, torusUtils: torusUtils)
let public_address = try await get_dkg_pub_key(threshold_key: threshold_key, tssTag: tss_tag, nonce: nonce, nodeDetails: nodeDetails, torusUtils: torusUtils)
let pk_encoded = try JSONEncoder().encode(public_address)
guard let public_key = String(data: pk_encoded, encoding: .utf8) else {
throw RuntimeError("update_tss_pub_key - Conversion Error - ResultString")
Expand Down Expand Up @@ -392,6 +392,7 @@ public final class TssModule {

let (tss_index, tss_share) = try await get_tss_share(threshold_key: threshold_key, tss_tag: tss_tag, factorKey: factor_key)
try await TssModule.generate_tss_share(threshold_key: threshold_key, tss_tag: tss_tag, input_tss_share: tss_share, tss_input_index: Int32(tss_index)!, auth_signatures: auth_signatures, new_factor_pub: new_factor_pub, new_tss_index: new_tss_index, nodeDetails: nodeDetails, torusUtils: torusUtils, selected_servers: selected_servers)

}

public static func delete_factor_pub(threshold_key: ThresholdKey, tss_tag: String, factor_key: String, auth_signatures: [String], delete_factor_pub: String, nodeDetails: AllNodeDetailsModel, torusUtils: TorusUtils, selected_servers: [Int32]? = nil) async throws {
Expand All @@ -401,8 +402,59 @@ public final class TssModule {
let (tss_index, tss_share) = try await get_tss_share(threshold_key: threshold_key, tss_tag: tss_tag, factorKey: factor_key)
try await TssModule.delete_tss_share(threshold_key: threshold_key, tss_tag: tss_tag, input_tss_share: tss_share, tss_input_index: Int32(tss_index)!, auth_signatures: auth_signatures, delete_factor_pub: delete_factor_pub, nodeDetails: nodeDetails, torusUtils: torusUtils, selected_servers: selected_servers)
}


/// backup device share with factor key
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - shareIndex: Index of the Share to be backed up.
/// - factorKey: factor key to be used for backup.
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func backup_share_with_factor_key(threshold_key: ThresholdKey, shareIndex: String, factorKey: String) throws {
var errorCode: Int32 = -1

public static func getTssPubAddress(threshold_key: ThresholdKey, tssTag: String, nonce: String, nodeDetails: AllNodeDetailsModel, torusUtils: TorusUtils) async throws -> GetTSSPubKeyResult {
let cShareIndex = UnsafeMutablePointer<Int8>(mutating: (shareIndex as NSString).utf8String)
let cFactorKey = UnsafeMutablePointer<Int8>(mutating: (factorKey as NSString).utf8String)
let curvePointer = UnsafeMutablePointer<Int8>(mutating: (threshold_key.curveN as NSString).utf8String)

withUnsafeMutablePointer(to: &errorCode, { error in threshold_key_backup_share_with_factor_key( threshold_key.pointer, cShareIndex, cFactorKey, curvePointer, error)})
guard errorCode == 0 else {
throw RuntimeError("Error in ThresholdKey backup_share_with_factor_key")
}
}

public static func find_device_share_index ( threshold_key: ThresholdKey, factor_key: String ) async throws -> String {
metalurgical marked this conversation as resolved.
Show resolved Hide resolved
let result = try await threshold_key.storage_layer_get_metadata(private_key: factor_key)
guard let resultData = result.data(using: .utf8) else {
throw "Invalid factor key"
}
guard let resultJson = try JSONSerialization.jsonObject(with: resultData ) as? [String: Any] else {
throw "Invalid factor key"
}
guard let deviceShareJson = resultJson["deviceShare"] as? [String: Any] else {
throw "Invalid factor key"
}
guard let shareJson = deviceShareJson["share"] as? [String: Any] else {
throw "Invalid factor key"
}
guard let shareIndex = shareJson["shareIndex"] as? String else {
throw "Invalid factor key"
}
return shareIndex
}

/// get dkg public key
/// - Parameters:
/// - threshold_key: The threshold key to act on.
/// - tssTag: tssTag used.
/// - nonce: nonce
/// - nodeDetails: node details
/// - torusUtils: torus utils
/// - Returns: `GetTSSPubKeyResult`
///
/// - Throws: `RuntimeError`, indicates invalid parameters was used or invalid threshold key.
public static func get_dkg_pub_key(threshold_key: ThresholdKey, tssTag: String, nonce: String, nodeDetails: AllNodeDetailsModel, torusUtils: TorusUtils) async throws -> GetTSSPubKeyResult {
metalurgical marked this conversation as resolved.
Show resolved Hide resolved
let extendedVerifierId = try threshold_key.get_extended_verifier_id()
let split = extendedVerifierId.components(separatedBy: "\u{001c}")

Expand Down
61 changes: 60 additions & 1 deletion Sources/ThresholdKey/ThresholdKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ public class ThresholdKey {
}
}
}

/// Inserts a share into `ThresholdKey`, this is used prior to reconstruction in order to ensure the number of shares meet the threshold.
///
/// - Parameters:
Expand Down Expand Up @@ -533,7 +533,47 @@ public class ThresholdKey {
}
}
}

private func input_factor_key(factorKey: String, completion: @escaping (Result<Void, Error>) -> Void) {
tkeyQueue.async {
do {
var errorCode: Int32 = -1
let cFactorKey = UnsafeMutablePointer<Int8>(mutating: (factorKey as NSString).utf8String)

withUnsafeMutablePointer(to: &errorCode, { error in
threshold_key_input_factor_key(self.pointer, cFactorKey, error)
})
guard errorCode == 0 else {
throw RuntimeError("Error in ThresholdKey input_factor_key")
}
completion(.success(()))
} catch {
completion(.failure(error))
}
}
}

/// Inserts a `ShareStore` into `ThresholdKey` using `FactorKey`, useful for insertion before reconstruction to ensure the number of shares meet the minimum threshold.
///
/// - Parameters:
/// - factorKey : The `factorKey` to be inserted
///
/// - Throws: `RuntimeError`, indicates invalid parameters or invalid `ThresholdKey`.
public func input_factor_key(factorKey: String) async throws {
return try await withCheckedThrowingContinuation {
continuation in
self.input_factor_key(factorKey: factorKey) {
result in
switch result {
case let .success(result):
continuation.resume(returning: result)
case let .failure(error):
continuation.resume(throwing: error)
}
}
}
}

/// Retrieves all share indexes for a `ThresholdKey`.
///
/// - Returns: Array of `String`
Expand Down Expand Up @@ -622,6 +662,25 @@ public class ThresholdKey {
}
return LocalMetadataTransitions(pointer: result!)
}

/// Returns add metadata transitions , need sync localmetadata transistion to update server data
///
/// - Parameters:
/// - input_json: input in json string
/// - private_key: private key used to encrypt and store.
///
/// - Throws: `RuntimeError`, indicates invalid parameters or invalid `ThresholdKey`.
public func add_local_metadata_transitions( input_json: String, private_key: String ) throws {
var errorCode: Int32 = -1

let curve = UnsafeMutablePointer<Int8>(mutating: (curveN as NSString).utf8String)
let input = UnsafeMutablePointer<Int8>(mutating: (input_json as NSString).utf8String)
let privateKey = UnsafeMutablePointer<Int8>(mutating: (private_key as NSString).utf8String)
withUnsafeMutablePointer(to: &errorCode, { error in threshold_key_add_local_metadata_transitions(pointer, input, privateKey, curve, error)})
guard errorCode == 0 else {
throw RuntimeError("Error in ThresholdKey add_local_metadata_transitions")
}
}

/// Returns the tKey store for a module.
///
Expand Down
3 changes: 3 additions & 0 deletions Sources/libtkey/include/tkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@
void threshold_key_input_share(struct FFIThresholdKey* threshold_key, char* share, char* share_type, char* curve_n, int* error_code);
struct ShareStore* threshold_key_output_share_store(struct FFIThresholdKey* threshold_key, char* share_index, char* poly_id, char* curve_n, int* error_code);
void threshold_key_input_share_store(struct FFIThresholdKey* threshold_key, struct ShareStore* share_store, int* error_code);
void threshold_key_input_factor_key(struct FFIThresholdKey* threshold_key, char* factor_key, int* error_code);
char* threshold_key_get_shares_indexes(struct FFIThresholdKey* threshold_key, int* error_code);
char* threshold_key_encrypt(struct FFIThresholdKey* threshold_key, char* data, char* curve_n, int* error_code);
char* threshold_key_decrypt(struct FFIThresholdKey* threshold_key, char* data, int* error_code);
struct LocalMetadataTransitions* threshold_key_get_local_metadata_transitions(struct FFIThresholdKey* threshold_key, int* error_code);
void threshold_key_add_local_metadata_transitions(struct FFIThresholdKey* threshold_key, char* input_json, char* private_key, char* curve_n, int* error_code);
struct Polynomial* threshold_key_reconstruct_latest_poly(struct FFIThresholdKey *threshold_key, char* curve_n, int* error_code);
struct Metadata* threshold_key_get_last_fetched_cloud_metadata(struct FFIThresholdKey* threshold_key, int* error_code);
void threshold_key_sync_local_metadata_transitions(struct FFIThresholdKey *threshold_key, char* curve_n, int* error_code);
Expand All @@ -116,6 +118,7 @@

int threshold_key_get_tss_nonce(struct FFIThresholdKey* threshold_key, char* tss_tag, int* error_code );
void threshold_key_copy_factor_pub(struct FFIThresholdKey* threshold_key, char* new_factor_pub, int new_tss_index, char* factor_pub, char* curve_n, int* error_code );
void threshold_key_backup_share_with_factor_key(struct FFIThresholdKey* threshold_key, char* share_index, char* factor_key, char* curve_n, int* error_code);

void threshold_key_generate_tss_share(struct FFIThresholdKey* threshold_key, char* input_tss_share, int input_tss_index, int new_tss_index, char* new_factor_pub, char* selected_servers, char* auth_signatures, char* curve_n, int* error_code );
void threshold_key_delete_tss_share(struct FFIThresholdKey* threshold_key, char* input_tss_share, int input_tss_index, char* factor_pub, char* selected_servers, char* auth_signatures, char* curve_n, int* error_code );
Expand Down
Loading