Skip to content

Commit 621ea9c

Browse files
author
Alex Vlasov
committed
fix addition of multiple public keys
1 parent b7f438c commit 621ea9c

File tree

2 files changed

+38
-29
lines changed

2 files changed

+38
-29
lines changed

web3swift/Convenience/Classes/LibSecp256k1Extension.swift

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,44 +53,44 @@ extension SECP256K1 {
5353
static func combineSerializedPublicKeys(keys: [Data], outputCompressed: Bool = false) -> Data? {
5454
let numToCombine = keys.count
5555
guard numToCombine >= 1 else { return nil}
56-
var publicKeys = [UnsafePointer<secp256k1_pubkey>?]()
57-
var result:Int32
58-
for i in 0..<numToCombine {
59-
var publicKey = secp256k1_pubkey()
56+
var storage = ContiguousArray<secp256k1_pubkey>()
57+
let arrayOfPointers = UnsafeMutablePointer< UnsafePointer<secp256k1_pubkey>? >.allocate(capacity: numToCombine)
58+
defer {
59+
arrayOfPointers.deinitialize(count: numToCombine)
60+
arrayOfPointers.deallocate()
61+
}
62+
for i in 0 ..< numToCombine {
6063
let key = keys[i]
61-
let keyLen = key.count
62-
result = key.withUnsafeBytes { (publicKeyPointer:UnsafePointer<UInt8>) -> Int32 in
63-
let res = secp256k1_ec_pubkey_parse(context!, UnsafeMutablePointer<secp256k1_pubkey>(&publicKey), publicKeyPointer, keyLen)
64-
return res
65-
}
66-
if result == 0 {
67-
return nil
64+
guard let pubkey = SECP256K1.parsePublicKey(serializedKey: key) else {return nil}
65+
storage.append(pubkey)
66+
}
67+
for i in 0 ..< numToCombine {
68+
withUnsafePointer(to: &storage[i]) { (ptr) -> Void in
69+
arrayOfPointers.advanced(by: i).pointee = ptr
6870
}
69-
let pointer = UnsafePointer<secp256k1_pubkey>(UnsafeMutablePointer<secp256k1_pubkey>(&publicKey))
70-
publicKeys.append(pointer)
7171
}
72-
72+
let immutablePointer = UnsafePointer(arrayOfPointers)
7373
var publicKey: secp256k1_pubkey = secp256k1_pubkey()
74-
let arrayPointer = UnsafePointer(publicKeys)
75-
result = secp256k1_ec_pubkey_combine(context!, UnsafeMutablePointer<secp256k1_pubkey>(&publicKey), arrayPointer, numToCombine)
74+
75+
// let bufferPointer = UnsafeBufferPointer(start: immutablePointer, count: numToCombine)
76+
// for (index, value) in bufferPointer.enumerated() {
77+
// print("pointer value \(index): \(value!)")
78+
// let val = value?.pointee
79+
// print("value \(index): \(val!)")
80+
// }
81+
//
82+
let result = withUnsafeMutablePointer(to: &publicKey) { (pubKeyPtr: UnsafeMutablePointer<secp256k1_pubkey>) -> Int32 in
83+
let res = secp256k1_ec_pubkey_combine(context!, pubKeyPtr, immutablePointer, numToCombine)
84+
return res
85+
}
7686
if result == 0 {
7787
return nil
7888
}
79-
80-
var keyLength = outputCompressed ? 33 : 65
81-
var serializedPubkey = Data(repeating: 0x00, count: keyLength)
82-
83-
result = serializedPubkey.withUnsafeMutableBytes { (serializedPubkeyPointer:UnsafeMutablePointer<UInt8>) -> Int32 in
84-
let res = secp256k1_ec_pubkey_serialize(context!,
85-
serializedPubkeyPointer,
86-
UnsafeMutablePointer<Int>(&keyLength),
87-
UnsafeMutablePointer<secp256k1_pubkey>(&publicKey),
88-
UInt32(outputCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED))
89-
return res
90-
}
91-
return Data(serializedPubkey)
89+
let serializedKey = SECP256K1.serializePublicKey(publicKey: &publicKey, compressed: outputCompressed)
90+
return serializedKey
9291
}
9392

93+
9494
static func recoverPublicKey(hash: Data, recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> secp256k1_pubkey? {
9595
guard hash.count == 32 else {return nil}
9696
var publicKey: secp256k1_pubkey = secp256k1_pubkey()

web3swiftTests/web3swiftTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ class web3swiftTests: XCTestCase {
8888
XCTAssert(first4bits == 0x0f)
8989
}
9090

91+
func testCombiningPublicKeys() {
92+
let priv1 = Data.randomBytes(length: 32)!
93+
let pub1 = Web3.Utils.privateToPublic(priv1, compressed: true)!
94+
let priv2 = Data.randomBytes(length: 32)!
95+
let pub2 = Web3.Utils.privateToPublic(priv2, compressed: true)!
96+
let combined = SECP256K1.combineSerializedPublicKeys(keys: [pub1, pub2], outputCompressed: true)
97+
XCTAssert(combined != nil)
98+
}
99+
91100
func testBIP39 () {
92101
var entropy = Data.fromHex("00000000000000000000000000000000")!
93102
var phrase = BIP39.generateMnemonicsFromEntropy(entropy: entropy)

0 commit comments

Comments
 (0)