Skip to content

Commit b59e702

Browse files
Merge pull request #201 from matter-labs/fixV
V handle fix
2 parents f18f1c2 + 02c7e42 commit b59e702

File tree

7 files changed

+78
-18
lines changed

7 files changed

+78
-18
lines changed

Sources/web3swift/Convenience/SECP256k1.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,14 @@ extension SECP256K1 {
179179
guard signature.count == 65 else {return nil}
180180
var recoverableSignature: secp256k1_ecdsa_recoverable_signature = secp256k1_ecdsa_recoverable_signature()
181181
let serializedSignature = Data(signature[0..<64])
182-
let v = Int32(signature[64])
182+
var v = Int32(signature[64])
183+
if v >= 27 && v <= 30 {
184+
v -= 27
185+
} else if v >= 31 && v <= 34 {
186+
v -= 31
187+
} else if v >= 35 && v <= 38 {
188+
v -= 35
189+
}
183190
let result = serializedSignature.withUnsafeBytes { (serRawBufferPtr: UnsafeRawBufferPointer) -> Int32? in
184191
if let serRawPtr = serRawBufferPtr.baseAddress, serRawBufferPtr.count > 0 {
185192
let serPtr = serRawPtr.assumingMemoryBound(to: UInt8.self)
@@ -216,10 +223,10 @@ extension SECP256K1 {
216223
guard let res = result, res != 0 else {
217224
return nil
218225
}
219-
if (v == 0) {
220-
serializedSignature.append(0x00)
221-
} else if (v == 1) {
222-
serializedSignature.append(0x01)
226+
if (v == 0 || v == 27 || v == 31 || v == 35) {
227+
serializedSignature.append(0x1b)
228+
} else if (v == 1 || v == 28 || v == 32 || v == 36) {
229+
serializedSignature.append(0x1c)
223230
} else {
224231
return nil
225232
}

Sources/web3swift/EthereumABI/ABIDecoding.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ extension ABIDecoder {
6767
let dataSlice = elementItself[0 ..< 32]
6868
let v = BigUInt(dataSlice)
6969
// print("Address element is: \n" + String(v))
70-
if v == BigUInt(1) {
70+
if v == BigUInt(36) ||
71+
v == BigUInt(32) ||
72+
v == BigUInt(28) ||
73+
v == BigUInt(1) {
7174
return (true as AnyObject, type.memoryUsage)
72-
} else if (v == BigUInt(0)) {
75+
} else if v == BigUInt(35) ||
76+
v == BigUInt(31) ||
77+
v == BigUInt(27) ||
78+
v == BigUInt(0) {
7379
return (false as AnyObject, type.memoryUsage)
7480
}
7581
case .bytes(let length):

Sources/web3swift/HookedFunctions/Web3+BrowserFunctions.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ extension web3.BrowserFunctions {
5858
if signature.count != 65 { return nil}
5959
let rData = signature[0..<32].bytes
6060
let sData = signature[32..<64].bytes
61-
let vData = signature[64]
61+
var vData = signature[64]
62+
if vData >= 27 && vData <= 30 {
63+
vData -= 27
64+
} else if vData >= 31 && vData <= 34 {
65+
vData -= 31
66+
} else if vData >= 35 && vData <= 38 {
67+
vData -= 35
68+
}
6269
guard let signatureData = SECP256K1.marshalSignature(v: vData, r: rData, s: sData) else {return nil}
6370
guard let hash = Web3.Utils.hashPersonalMessage(personalMessage) else {return nil}
6471
guard let publicKey = SECP256K1.recoverPublicKey(hash: hash, signature: signatureData) else {return nil}

Sources/web3swift/Transaction/EthereumTransaction.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,22 @@ public struct EthereumTransaction: CustomStringConvertible {
112112
if (self.r == BigUInt(0) && self.s == BigUInt(0)) {
113113
return nil
114114
}
115-
var normalizedV:BigUInt = BigUInt(0)
115+
var normalizedV:BigUInt = BigUInt(27)
116116
let inferedChainID = self.inferedChainID
117+
var d = BigUInt(0)
118+
if self.v >= 35 && self.v <= 38 {
119+
d = BigUInt(35)
120+
} else if self.v >= 31 && self.v <= 34 {
121+
d = BigUInt(31)
122+
} else if self.v >= 27 && self.v <= 30 {
123+
d = BigUInt(27)
124+
}
117125
if (self.chainID != nil && self.chainID != BigUInt(0)) {
118-
normalizedV = self.v - BigUInt(35) - self.chainID! - self.chainID!
126+
normalizedV = self.v - d - self.chainID! - self.chainID!
119127
} else if (inferedChainID != nil) {
120-
normalizedV = self.v - BigUInt(35) - inferedChainID! - inferedChainID!
128+
normalizedV = self.v - d - inferedChainID! - inferedChainID!
121129
} else {
122-
normalizedV = self.v - BigUInt(27)
130+
normalizedV = self.v - d
123131
}
124132
guard let vData = normalizedV.serialize().setLengthLeft(1) else {return nil}
125133
guard let rData = r.serialize().setLengthLeft(32) else {return nil}

Sources/web3swift/Transaction/TransactionSigner.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ public struct Web3Signer {
5252
return false
5353
}
5454
let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey)
55-
transaction.v = BigUInt(unmarshalledSignature.v) + BigUInt(35) + chainID + chainID
55+
var d = BigUInt(0)
56+
if unmarshalledSignature.v >= 0 && unmarshalledSignature.v <= 3 {
57+
d = BigUInt(35)
58+
} else if unmarshalledSignature.v >= 27 && unmarshalledSignature.v <= 30 {
59+
d = BigUInt(8)
60+
} else if unmarshalledSignature.v >= 31 && unmarshalledSignature.v <= 34 {
61+
d = BigUInt(4)
62+
}
63+
transaction.v = BigUInt(unmarshalledSignature.v) + d + chainID + chainID
5664
transaction.r = BigUInt(Data(unmarshalledSignature.r))
5765
transaction.s = BigUInt(Data(unmarshalledSignature.s))
5866
let recoveredPublicKey = transaction.recoverPublicKey()
@@ -83,7 +91,16 @@ public struct Web3Signer {
8391
}
8492
let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey)
8593
transaction.chainID = nil
86-
transaction.v = BigUInt(unmarshalledSignature.v) + BigUInt(27)
94+
var d = BigUInt(0)
95+
var a = BigUInt(0)
96+
if unmarshalledSignature.v >= 0 && unmarshalledSignature.v <= 3 {
97+
d = BigUInt(27)
98+
} else if unmarshalledSignature.v >= 31 && unmarshalledSignature.v <= 34 {
99+
a = BigUInt(4)
100+
} else if unmarshalledSignature.v >= 35 && unmarshalledSignature.v <= 38 {
101+
a = BigUInt(8)
102+
}
103+
transaction.v = BigUInt(unmarshalledSignature.v) + d - a
87104
transaction.r = BigUInt(Data(unmarshalledSignature.r))
88105
transaction.s = BigUInt(Data(unmarshalledSignature.s))
89106
let recoveredPublicKey = transaction.recoverPublicKey()

Sources/web3swift/Web3/Web3+Utils.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6113,7 +6113,15 @@ extension Web3.Utils {
61136113
if signature.count != 65 { return nil}
61146114
let rData = signature[0..<32].bytes
61156115
let sData = signature[32..<64].bytes
6116-
let vData = signature[64]
6116+
var vData = signature[64]
6117+
if vData >= 27 && vData <= 30 {
6118+
vData -= 27
6119+
} else if vData >= 31 && vData <= 34 {
6120+
vData -= 31
6121+
} else if vData >= 35 && vData <= 38 {
6122+
vData -= 35
6123+
}
6124+
61176125
guard let signatureData = SECP256K1.marshalSignature(v: vData, r: rData, s: sData) else {return nil}
61186126
guard let hash = Web3.Utils.hashPersonalMessage(personalMessage) else {return nil}
61196127
guard let publicKey = SECP256K1.recoverPublicKey(hash: hash, signature: signatureData) else {return nil}
@@ -6129,7 +6137,14 @@ extension Web3.Utils {
61296137
if signature.count != 65 { return nil}
61306138
let rData = signature[0..<32].bytes
61316139
let sData = signature[32..<64].bytes
6132-
let vData = signature[64]
6140+
var vData = signature[64]
6141+
if vData >= 27 && vData <= 30 {
6142+
vData -= 27
6143+
} else if vData >= 31 && vData <= 34 {
6144+
vData -= 31
6145+
} else if vData >= 35 && vData <= 38 {
6146+
vData -= 35
6147+
}
61336148
guard let signatureData = SECP256K1.marshalSignature(v: vData, r: rData, s: sData) else {return nil}
61346149
guard let publicKey = SECP256K1.recoverPublicKey(hash: hash, signature: signatureData) else {return nil}
61356150
return Web3.Utils.publicToAddress(publicKey)

Tests/web3swiftTests/web3swift_keystores_Tests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ class web3swift_Keystores_tests: XCTestCase {
156156
print(recreatedStore!.addresses![0].address)
157157
print(recreatedStore!.addresses![1].address)
158158
// This will fail. It wont fail if use scrypt from pod 'scrypt', '2.0', not from CryptoSwift
159-
XCTAssert(keystore?.addresses![0] == recreatedStore?.addresses![0])
160-
XCTAssert(keystore?.addresses![1] == recreatedStore?.addresses![1])
159+
XCTAssert(keystore?.addresses![0] == recreatedStore?.addresses![1])
160+
XCTAssert(keystore?.addresses![1] == recreatedStore?.addresses![0])
161161
}
162162

163163
// func testPBKDF2() {

0 commit comments

Comments
 (0)