Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Fix BIP 32 derivation in release build (with optimization) #65

Merged
merged 2 commits into from
Apr 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 29 additions & 29 deletions web3swift/Convenience/Classes/LibSecp256k1Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,44 +53,44 @@ extension SECP256K1 {
static func combineSerializedPublicKeys(keys: [Data], outputCompressed: Bool = false) -> Data? {
let numToCombine = keys.count
guard numToCombine >= 1 else { return nil}
var publicKeys = [UnsafePointer<secp256k1_pubkey>?]()
var result:Int32
for i in 0..<numToCombine {
var publicKey = secp256k1_pubkey()
var storage = ContiguousArray<secp256k1_pubkey>()
let arrayOfPointers = UnsafeMutablePointer< UnsafePointer<secp256k1_pubkey>? >.allocate(capacity: numToCombine)
defer {
arrayOfPointers.deinitialize(count: numToCombine)
arrayOfPointers.deallocate()
}
for i in 0 ..< numToCombine {
let key = keys[i]
let keyLen = key.count
result = key.withUnsafeBytes { (publicKeyPointer:UnsafePointer<UInt8>) -> Int32 in
let res = secp256k1_ec_pubkey_parse(context!, UnsafeMutablePointer<secp256k1_pubkey>(&publicKey), publicKeyPointer, keyLen)
return res
}
if result == 0 {
return nil
guard let pubkey = SECP256K1.parsePublicKey(serializedKey: key) else {return nil}
storage.append(pubkey)
}
for i in 0 ..< numToCombine {
withUnsafePointer(to: &storage[i]) { (ptr) -> Void in
arrayOfPointers.advanced(by: i).pointee = ptr
}
let pointer = UnsafePointer<secp256k1_pubkey>(UnsafeMutablePointer<secp256k1_pubkey>(&publicKey))
publicKeys.append(pointer)
}

let immutablePointer = UnsafePointer(arrayOfPointers)
var publicKey: secp256k1_pubkey = secp256k1_pubkey()
let arrayPointer = UnsafePointer(publicKeys)
result = secp256k1_ec_pubkey_combine(context!, UnsafeMutablePointer<secp256k1_pubkey>(&publicKey), arrayPointer, numToCombine)

// let bufferPointer = UnsafeBufferPointer(start: immutablePointer, count: numToCombine)
// for (index, value) in bufferPointer.enumerated() {
// print("pointer value \(index): \(value!)")
// let val = value?.pointee
// print("value \(index): \(val!)")
// }
//
let result = withUnsafeMutablePointer(to: &publicKey) { (pubKeyPtr: UnsafeMutablePointer<secp256k1_pubkey>) -> Int32 in
let res = secp256k1_ec_pubkey_combine(context!, pubKeyPtr, immutablePointer, numToCombine)
return res
}
if result == 0 {
return nil
}

var keyLength = outputCompressed ? 33 : 65
var serializedPubkey = Data(repeating: 0x00, count: keyLength)

result = serializedPubkey.withUnsafeMutableBytes { (serializedPubkeyPointer:UnsafeMutablePointer<UInt8>) -> Int32 in
let res = secp256k1_ec_pubkey_serialize(context!,
serializedPubkeyPointer,
UnsafeMutablePointer<Int>(&keyLength),
UnsafeMutablePointer<secp256k1_pubkey>(&publicKey),
UInt32(outputCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED))
return res
}
return Data(serializedPubkey)
let serializedKey = SECP256K1.serializePublicKey(publicKey: &publicKey, compressed: outputCompressed)
return serializedKey
}


static func recoverPublicKey(hash: Data, recoverableSignature: inout secp256k1_ecdsa_recoverable_signature) -> secp256k1_pubkey? {
guard hash.count == 32 else {return nil}
var publicKey: secp256k1_pubkey = secp256k1_pubkey()
Expand Down
29 changes: 29 additions & 0 deletions web3swiftTests/web3swiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ class web3swiftTests: XCTestCase {
XCTAssert(first4bits == 0x0f)
}

func testCombiningPublicKeys() {
let priv1 = Data.randomBytes(length: 32)!
let pub1 = Web3.Utils.privateToPublic(priv1, compressed: true)!
let priv2 = Data.randomBytes(length: 32)!
let pub2 = Web3.Utils.privateToPublic(priv2, compressed: true)!
let combined = SECP256K1.combineSerializedPublicKeys(keys: [pub1, pub2], outputCompressed: true)
XCTAssert(combined != nil)
}

func testBIP39 () {
var entropy = Data.fromHex("00000000000000000000000000000000")!
var phrase = BIP39.generateMnemonicsFromEntropy(entropy: entropy)
Expand Down Expand Up @@ -1991,6 +2000,26 @@ class web3swiftTests: XCTestCase {
}
}

func testPersonalSignature() {
let web3 = Web3.InfuraRinkebyWeb3()
let tempKeystore = try! EthereumKeystoreV3(password: "")
let keystoreManager = KeystoreManager([tempKeystore!])
web3.addKeystoreManager(keystoreManager)
let message = "Hello World"
let expectedAddress = keystoreManager.addresses![0]
print(expectedAddress)
let signRes = web3.personal.signPersonalMessage(message: message.data(using: .utf8)!, from: expectedAddress, password: "")
guard case .success(let signature) = signRes else {return XCTFail()}
let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: signature)!
print("V = " + String(unmarshalledSignature.v))
print("R = " + Data(unmarshalledSignature.r).toHexString())
print("S = " + Data(unmarshalledSignature.s).toHexString())
print("Personal hash = " + Web3.Utils.hashPersonalMessage(message.data(using: .utf8)!)!.toHexString())
let recoveredSigner = web3.personal.ecrecover(personalMessage: message.data(using: .utf8)!, signature: signature)
guard case .success(let signer) = recoveredSigner else {return XCTFail()}
XCTAssert(expectedAddress == signer, "Failed to sign personal message")
}

func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
Expand Down