Skip to content

Commit

Permalink
add secp256k1 uncompress function + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmcl committed Jun 1, 2023
1 parent cda79d3 commit 7c3536b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
21 changes: 20 additions & 1 deletion Sources/KukaiCryptoSwift/KeyPair.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public struct KeyPair {



// MARK: - Private Helpers
// MARK: - Helpers

/// Helper method to take a secp256k1 private key (for a regualr keypair) and use it to create a public key for the same curve
public static func secp256k1PublicKey(fromPrivateKeyBytes pkBytes: [UInt8]) -> PublicKey? {
Expand All @@ -156,4 +156,23 @@ public struct KeyPair {

return PublicKey(publicKeyBytes, signingCurve: .secp256k1)
}

/// Helper method to uncompress a secp256k1 public key
public static func secp256k1PublicKey_uncompressed(fromBytes: [UInt8]) -> [UInt8] {
var publicKey = secp256k1_pubkey()
var outputLength = 65
var outputBytes = [UInt8](repeating: 0, count: outputLength)

guard let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN)),
secp256k1_ec_pubkey_parse(context, &publicKey, fromBytes, fromBytes.count) != 0,
secp256k1_ec_pubkey_serialize(context, &outputBytes, &outputLength, &publicKey, UInt32(SECP256K1_EC_UNCOMPRESSED)) != 0 else {
return []
}

defer {
secp256k1_context_destroy(context)
}

return outputBytes
}
}
22 changes: 22 additions & 0 deletions Tests/KukaiCryptoSwiftTests/KeyPairTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,26 @@ final class KeyPairTests: XCTestCase {
XCTAssert(EllipticalCurve.fromAddress("tZ1abc123") == .ed25519)
XCTAssert(EllipticalCurve.fromAddress("tZ2abc123") == .secp256k1)
}

func testUncompress() throws {
let mnemonic = try Mnemonic(seedPhrase: "gym exact clown can answer hope sample mirror knife twenty powder super imitate lion churn almost shed chalk dust civil gadget pyramid helmet trade")
let keyPair1 = KeyPair.regular(fromMnemonic: mnemonic, passphrase: "", andSigningCurve: .secp256k1)

let uncompressed = KeyPair.secp256k1PublicKey_uncompressed(fromBytes: keyPair1?.publicKey.bytes ?? [])
let data = Data(bytes: uncompressed, count: uncompressed.count)
let dataString = data.hexString

XCTAssert(dataString.count == 130, dataString.count.description)
XCTAssert(dataString == "047b6d7bf2cbb376149211eacab517359cb035b0f0c36f57f7fe923a2453c7a8f1a594260c94501bc7ad63324b42638f768840948d1f1cadf9cb6d1ce456b7c8dc", dataString)


let keyPair2 = KeyPair.regular(fromMnemonic: mnemonic, passphrase: "", andSigningCurve: .ed25519)

let uncompressed2 = KeyPair.secp256k1PublicKey_uncompressed(fromBytes: keyPair2?.publicKey.bytes ?? [])
let data2 = Data(bytes: uncompressed2, count: uncompressed2.count)
let dataString2 = data2.hexString

XCTAssert(dataString2.count == 0, dataString2.count.description)
XCTAssert(dataString2 == "", dataString2)
}
}

0 comments on commit 7c3536b

Please sign in to comment.