Skip to content

Commit

Permalink
Merge pull request #55 from torusresearch/alpha
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
ieow authored Aug 28, 2023
2 parents 35720bc + 6bf1c74 commit c3b8fee
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 183 deletions.
94 changes: 2 additions & 92 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,8 @@
"repositoryURL": "https://github.com/torusresearch/fetch-node-details-swift.git",
"state": {
"branch": null,
"revision": "c7b4e5a65eb737c029acb2d1aff84854a618384d",
"version": "5.0.0-alpha"
}
},
{
"package": "GenericJSON",
"repositoryURL": "https://github.com/iwill/generic-json-swift",
"state": {
"branch": null,
"revision": "0a06575f4038b504e78ac330913d920f1630f510",
"version": "2.0.2"
"revision": "68459eb481c382bfbbe28345b8eb25b3897c7447",
"version": "5.0.0"
}
},
{
Expand All @@ -64,24 +55,6 @@
"version": "0.12.2"
}
},
{
"package": "swift-atomics",
"repositoryURL": "https://github.com/apple/swift-atomics.git",
"state": {
"branch": null,
"revision": "6c89474e62719ddcc1e9614989fff2f68208fe10",
"version": "1.1.0"
}
},
{
"package": "swift-collections",
"repositoryURL": "https://github.com/apple/swift-collections.git",
"state": {
"branch": null,
"revision": "937e904258d22af6e447a0b72c0bc67583ef64a2",
"version": "1.0.4"
}
},
{
"package": "swift-crypto",
"repositoryURL": "https://github.com/apple/swift-crypto.git",
Expand All @@ -90,69 +63,6 @@
"revision": "60f13f60c4d093691934dc6cfdf5f508ada1f894",
"version": "2.6.0"
}
},
{
"package": "swift-log",
"repositoryURL": "https://github.com/apple/swift-log.git",
"state": {
"branch": null,
"revision": "32e8d724467f8fe623624570367e3d50c5638e46",
"version": "1.5.2"
}
},
{
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio.git",
"state": {
"branch": null,
"revision": "cf281631ff10ec6111f2761052aa81896a83a007",
"version": "2.58.0"
}
},
{
"package": "swift-nio-extras",
"repositoryURL": "https://github.com/apple/swift-nio-extras.git",
"state": {
"branch": null,
"revision": "0e0d0aab665ff1a0659ce75ac003081f2b1c8997",
"version": "1.19.0"
}
},
{
"package": "swift-nio-ssl",
"repositoryURL": "https://github.com/apple/swift-nio-ssl.git",
"state": {
"branch": null,
"revision": "e866a626e105042a6a72a870c88b4c531ba05f83",
"version": "2.24.0"
}
},
{
"package": "swift-nio-transport-services",
"repositoryURL": "https://github.com/apple/swift-nio-transport-services.git",
"state": {
"branch": null,
"revision": "5fd1458c245d5741b3c8ebe55489f590c6ca8f15",
"version": "1.18.0"
}
},
{
"package": "web3.swift",
"repositoryURL": "https://github.com/argentlabs/web3.swift",
"state": {
"branch": null,
"revision": "8ca33e700ed8de6137a0e1471017aa3b3c8de0db",
"version": "1.6.0"
}
},
{
"package": "websocket-kit",
"repositoryURL": "https://github.com/vapor/websocket-kit.git",
"state": {
"branch": null,
"revision": "53fe0639a98903858d0196b699720decb42aee7b",
"version": "2.14.0"
}
}
]
},
Expand Down
11 changes: 5 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
import PackageDescription
let package = Package(
name: "TorusUtils",
platforms: [
.iOS(.v13), .macOS(.v10_15)
],
platforms: [.iOS(.v13), .macOS(.v10_15)],
products: [
.library(
name: "TorusUtils",
targets: ["TorusUtils"])
],
dependencies: [
.package(name:"FetchNodeDetails", url: "https://github.com/torusresearch/fetch-node-details-swift.git", .exact("5.0.0-alpha")),
.package(name:"secp256k1", url: "https://github.com/GigaBitcoin/secp256k1.swift.git", from: "0.12.2"),
.package(name:"FetchNodeDetails", url: "https://github.com/torusresearch/fetch-node-details-swift.git", from: "5.0.0"),
.package(name:"CryptoSwift", url: "https://github.com/krzyzanowskim/CryptoSwift.git",from: "1.5.1"),
.package(name:"jwt-kit", url: "https://github.com/vapor/jwt-kit.git", from: "4.0.0"),
.package(
Expand All @@ -25,10 +24,10 @@ let package = Package(
targets: [
.target(
name: "TorusUtils",
dependencies: ["FetchNodeDetails", "CryptoSwift", "AnyCodable"]),
dependencies: ["FetchNodeDetails", "CryptoSwift", "AnyCodable", "secp256k1"]),
.testTarget(
name: "TorusUtilsTests",
dependencies: ["TorusUtils", "CryptoSwift", .product(name: "JWTKit", package: "jwt-kit"), "FetchNodeDetails"]
dependencies: ["TorusUtils", .product(name: "JWTKit", package: "jwt-kit")]
)
],
swiftLanguageVersions: [.v5]
Expand Down
1 change: 0 additions & 1 deletion Sources/TorusUtils/Convenience/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//

import Foundation
import web3

extension String {
var fullRange: Range<Index> {
Expand Down
10 changes: 10 additions & 0 deletions Sources/TorusUtils/Extensions/HelperExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import Foundation
import BigInt

// Necessary for decryption

Expand Down Expand Up @@ -36,3 +37,12 @@ extension Data {
}
}


extension BigUInt {
init?(hex: String) {
guard let result = BigUInt(hex, radix: 16) else{
return nil
}
self = result
}
}
94 changes: 50 additions & 44 deletions Sources/TorusUtils/Extensions/TorusUtils+extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,21 @@ extension TorusUtils {

internal func generateParams(message: String, privateKey: String) throws -> MetadataParams {
do {
guard let privKeyData = Data(hex: privateKey),
let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString().padLeft(padChar: "0", count: 128)

let privKeyData = Data(hex: privateKey)
// this pubkey is not being padded in backend as well on web, so do not pad here.
guard let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString()
else {
throw TorusUtilError.runtime("invalid priv key")
}

let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16)
let setData: MetadataParams.SetData = .init(data: message, timestamp: timeStamp)
let encodedData = try JSONEncoder().encode(setData)
guard let sigData = SECP256K1.signForRecovery(hash: encodedData.web3.keccak256, privateKey: privKeyData).serializedSignature else {

// let hash = encodedData.web3.keccak256
let hash = keccak256Data(encodedData)
guard let sigData = SECP256K1.signForRecovery(hash: hash, privateKey: privKeyData).serializedSignature else {
throw TorusUtilError.runtime("sign for recovery hash failed")
}
var pubKeyX = String(publicKey.prefix(64))
Expand Down Expand Up @@ -508,61 +513,70 @@ extension TorusUtils {
var pubKeyNonceResult: PubNonce?
var typeOfUser: UserType = .v1

var modifiedPubKey = "04" + oauthPubKeyX.addLeading0sForLength64() + oauthPubKeyY.addLeading0sForLength64()

var finalPubKey = "04" + oauthPubKeyX.addLeading0sForLength64() + oauthPubKeyY.addLeading0sForLength64()
if verifierParams.extended_verifier_id != nil {
typeOfUser = .v2
// For TSS key, no need to add pub nonce
modifiedPubKey = String(modifiedPubKey.suffix(128))
finalPubKey = String(finalPubKey.suffix(128))
} else if case .legacy(_) = self.network {
if (self.enableOneKey) {
// get nonce
let nonceResult = try await getOrSetNonce(x: oauthPubKeyX, y: oauthPubKeyY, privateKey: oAuthKey)
metadataNonce = BigInt(hex: nonceResult.nonce ?? "0") ?? BigInt(0)
let pubNonceX = nonceResult.pubNonce?.x
let pubNonceY = nonceResult.pubNonce?.y
// BigInt( Data(hex: nonceResult.nonce ?? "0"))
metadataNonce = BigInt( nonceResult.nonce ?? "0", radix: 16)!
let usertype = nonceResult.typeOfUser
if usertype == "v2" {

if (usertype == "v2") {
let pubNonceX = nonceResult.pubNonce?.x
let pubNonceY = nonceResult.pubNonce?.y
typeOfUser = .v2
let pubkey2 = "04" + pubNonceX!.addLeading0sForLength64() + pubNonceY!.addLeading0sForLength64()
let combined = combinePublicKeys(keys: [modifiedPubKey, pubkey2], compressed: false)
modifiedPubKey = combined
let combined = combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false)
finalPubKey = combined
pubKeyNonceResult = .init(x: pubNonceX!, y: pubNonceY!)
} else {
typeOfUser = .v1
// for imported keys in legacy networks
metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oauthPubKeyX, "pub_key_Y": oauthPubKeyY]))
let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16)!) + BigInt(metadataNonce)).modulus(modulusValue)
finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
}
} else {
typeOfUser = .v1
// for imported keys in legacy networks
metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oauthPubKeyX, "pub_key_Y": oauthPubKeyY]))
let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16)!) + BigInt(metadataNonce)).modulus(modulusValue)
modifiedPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
}
} else {
typeOfUser = .v2

let pubNonceX = thresholdNonceData!.pubNonce!.x
let pubNonceY = thresholdNonceData!.pubNonce!.y
let pubkey2 = "04" + pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64()
let combined = combinePublicKeys(keys: [modifiedPubKey, pubkey2], compressed: false)
modifiedPubKey = combined
let combined = combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false)
finalPubKey = combined
pubKeyNonceResult = .init(x: pubNonceX, y: pubNonceY)
}



let (finalPubX , finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: modifiedPubKey)
let (oAuthKeyX, oAuthKeyY) = try getPublicKeyPointFromPubkeyString(pubKey: oAuthPubKey!)
let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY)

// deriving address from pub key coz pubkey is always available
// but finalPrivKey won't be available for v2 user upgraded to 2/n
let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)

var finalPrivKey = ""

if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) {
let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16) ?? BigInt(0)) + metadataNonce).modulus(modulusValue)
finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()

}

let (finalPubX , finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey)
// deriving address from pub key coz pubkey is always available
// but finalPrivKey won't be available for v2 user upgraded to 2/n
let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)

var isUpgraded: Bool?

Expand All @@ -576,8 +590,8 @@ extension TorusUtils {
return TorusKey(
finalKeyData: .init(
evmAddress: finalEvmAddress,
X: finalPubX,
Y: finalPubY,
X: finalPubX.addLeading0sForLength64(),
Y: finalPubY.addLeading0sForLength64(),
privKey: finalPrivKey
),
oAuthKeyData: .init(
Expand Down Expand Up @@ -723,7 +737,7 @@ extension TorusUtils {


public func encryptData(privkeyHex: String, _ dataToEncrypt: String) throws -> String {
guard let pubKey = SECP256K1.privateToPublic(privateKey: privkeyHex.hexa.data)?.web3.hexString.web3.noHexPrefix else {
guard let pubKey = SECP256K1.privateToPublic(privateKey: privkeyHex.hexa.data)?.toHexString() else {
throw TorusUtilError.runtime("Invalid private key hex")
}
let encParams = try encrypt(publicKey: pubKey, msg: dataToEncrypt, opts: nil)
Expand Down Expand Up @@ -843,8 +857,8 @@ extension TorusUtils {
do {
let data = try lagrangeInterpolation(shares: sharesToInterpolate)
// Split key in 2 parts, X and Y

guard let finalPrivateKey = data.web3.hexData, let publicKey = SECP256K1.privateToPublic(privateKey: finalPrivateKey)?.subdata(in: 1 ..< 65) else {
let finalPrivateKey = Data(hex: data)
guard let publicKey = SECP256K1.privateToPublic(privateKey: finalPrivateKey)?.subdata(in: 1 ..< 65) else {
throw TorusUtilError.decodingFailed("\(data)")
}
let paddedPubKey = publicKey.toHexString().padLeft(padChar: "0", count: 128)
Expand Down Expand Up @@ -1353,9 +1367,8 @@ extension TorusUtils {
internal func generateNonceMetadataParams(message: String, privateKey: BigInt, nonce: BigInt?) throws -> NonceMetadataParams {
do {


guard let privKeyData = Data(hex: String(privateKey, radix: 16).addLeading0sForLength64()),
let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString().padLeft(padChar: "0", count: 128)
let privKeyData = Data(hex: privateKey.serialize().hexString.addLeading0sForLength64() )
guard let publicKey = SECP256K1.privateToPublic(privateKey: privKeyData)?.subdata(in: 1 ..< 65).toHexString().padLeft(padChar: "0", count: 128)
else {
throw TorusUtilError.runtime("invalid priv key")
}
Expand All @@ -1366,26 +1379,20 @@ extension TorusUtils {
setData.data = String(nonce!, radix: 16).addLeading0sForLength64()
}
let encodedData = try JSONEncoder().encode(setData)
guard let sigData = SECP256K1.signForRecovery(hash: encodedData.web3.keccak256, privateKey: privKeyData).serializedSignature else {
// let hash = encodedData.web3.keccak256
let hash = keccak256Data(encodedData)
guard let sigData = SECP256K1.signForRecovery(hash: hash, privateKey: privKeyData).serializedSignature else {
throw TorusUtilError.runtime("sign for recovery hash failed")
}
var pubKeyX = String(publicKey.prefix(64))
var pubKeyY = String(publicKey.suffix(64))
let pubKeyX = String(publicKey.prefix(64))
let pubKeyY = String(publicKey.suffix(64))

return .init(pub_key_X: pubKeyX, pub_key_Y: pubKeyY, setData: setData, signature: sigData.base64EncodedString())
} catch let error {
throw error
}
}

internal func publicKeyToAddress(key: Data) -> Data {
return key.web3.keccak256.suffix(20)
}

internal func publicKeyToAddress(key: String) -> String {
return key.web3.keccak256fromHex.suffix(20).toHexString().toChecksumAddress()
}

internal func getPublicKeyPointFromPubkeyString( pubKey: String) throws -> (String, String) {
let publicKeyHashData = Data.fromHex(pubKey.strip04Prefix())
guard publicKeyHashData?.count == 64 else {
Expand Down Expand Up @@ -1420,9 +1427,7 @@ extension TorusUtils {
let (oAuthX, oAuthY) = (pubKeyX.addLeading0sForLength64(), pubKeyY.addLeading0sForLength64())
if enableOneKey {
nonceResult = try await getOrSetNonce(x: pubKeyX, y: pubKeyY, privateKey: nil, getOnly: !isNewKey)
pubNonce = nonceResult?.pubNonce
nonce = BigUInt(nonceResult?.nonce ?? "0") ?? 0

typeOfUser = .init(rawValue: nonceResult?.typeOfUser ?? ".v1") ?? .v1
if typeOfUser == .v1 {
finalPubKey = "04" + pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()
Expand All @@ -1435,6 +1440,7 @@ extension TorusUtils {
finalPubKey = String(finalPubKey.suffix(128))
}
} else if typeOfUser == .v2 {
pubNonce = nonceResult?.pubNonce
if nonceResult?.upgraded ?? false {
finalPubKey = "04" + pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()
} else {
Expand Down Expand Up @@ -1481,13 +1487,13 @@ extension TorusUtils {
result = TorusPublicKey(
finalKeyData: .init(
evmAddress: finalAddress,
X: finalX,
Y: finalY
X: finalX.addLeading0sForLength64(),
Y: finalY.addLeading0sForLength64()
),
oAuthKeyData: .init(
evmAddress: oAuthAddress,
X: oAuthX,
Y: oAuthY
X: oAuthX.addLeading0sForLength64(),
Y: oAuthY.addLeading0sForLength64()
),
metadata: .init(
pubNonce: pubNonce,
Expand Down
Loading

0 comments on commit c3b8fee

Please sign in to comment.