Skip to content

Commit 5f58cb5

Browse files
authored
Merge pull request #20 from tonkeeper/feature/is-multi-account-mnemonic-method
Add method to detect multi-account mnemonic
2 parents aae2414 + 9424efb commit 5f58cb5

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

Source/TonSwift/Mnemonic/Mnemonic.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,22 @@ public enum Mnemonic {
117117

118118
return seed[0] == 0
119119
}
120+
121+
public static func isMultiAccountSeed(mnemonicArray: [String]) -> Bool {
122+
let entropy = hmacSha512(phrase: "TON Keychain", password: mnemonicArray.joined(separator: " "))
123+
124+
// There is a collision propability with TON mnemonics
125+
if (isBasicSeed(entropy: mnemonicToEntropy(mnemonicArray: mnemonicArray, password: ""))) {
126+
return false
127+
}
128+
129+
let salt = "TON Keychain Version"
130+
let saltData = Data(salt.utf8)
131+
let seed = pbkdf2Sha512(phrase: entropy, salt: saltData, iterations: 1, keyLength: 64)
132+
133+
return seed[0] == 0
134+
}
135+
120136

121137
public static func isPasswordSeed(entropy: Data) -> Bool {
122138
let salt = "TON fast seed version"

Tests/TonSwiftTests/Mnemonic/MnemonicTest.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,19 @@ final class MnemonicTest: XCTestCase {
1919
XCTAssertEqual(keyPair.publicKey.hexString, "34eb4b67d64f74d989ce2bc2e3dfddb7ed4cb0eec92f29fbecd05b1eabab0254")
2020
XCTAssertEqual(keyPair.privateKey.hexString, "c893fc0b676782a5c157ad8fddb389f75caba6eea1c198d8075a8a43afce70a934eb4b67d64f74d989ce2bc2e3dfddb7ed4cb0eec92f29fbecd05b1eabab0254")
2121
}
22+
2223

24+
func testIsMultiAccountSeedMnemonic() throws {
25+
let collisionMnemonic = "cluster notice abandon frost gospel boring element situate click mix vague replace imitate garment useful crater resource dose tenant theme foam ancient phrase slight".components(separatedBy: " ")
26+
27+
XCTAssertFalse(Mnemonic.isMultiAccountSeed(mnemonicArray: collisionMnemonic))
28+
29+
let multiAccountMnemonic = "execute peanut please demise thumb mango argue cloud reopen upset also dentist panic elite roast security pyramid extra boil execute lazy pledge notice check".components(separatedBy: " ")
30+
31+
XCTAssertTrue(Mnemonic.isMultiAccountSeed(mnemonicArray: multiAccountMnemonic))
32+
33+
let tonMnemonic = "item supply cover volcano satisfy window custom cupboard license dance record tissue gadget rural health blossom useless useless hungry brush grief stock reflect morning".components(separatedBy: " ")
34+
35+
XCTAssertFalse(Mnemonic.isMultiAccountSeed(mnemonicArray: tonMnemonic))
36+
}
2337
}

0 commit comments

Comments
 (0)