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

Commit

Permalink
Merge pull request #65 from BANKEX/develop
Browse files Browse the repository at this point in the history
Fix BIP 32 derivation in release build (with optimization)
  • Loading branch information
shamatar authored Apr 18, 2018
2 parents 6d840cb + 621ea9c commit 6e0f62b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 29 deletions.
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

0 comments on commit 6e0f62b

Please sign in to comment.