Skip to content

Commit

Permalink
Merge pull request #852 from JeneaVranceanu/fix/bip39-wrong-language-…
Browse files Browse the repository at this point in the history
…used

fix: BIP39 use given language to generate mnemonics;
  • Loading branch information
yaroslavyaroslav authored Apr 1, 2024
2 parents 34cf1e8 + d99c0f6 commit 58c7d08
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Sources/Web3Core/KeystoreManager/BIP39.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import Foundation
import CryptoSwift

public enum BIP39Language {
public enum BIP39Language: CaseIterable {
case english
case chinese_simplified
case chinese_traditional
Expand Down Expand Up @@ -36,7 +36,12 @@ public enum BIP39Language {
return spanishWords
}
}

public var separator: String {
return String(separatorCharacter)
}

public var separatorCharacter: Character {
switch self {
case .japanese:
return "\u{3000}"
Expand Down Expand Up @@ -124,7 +129,7 @@ public class BIP39 {
public static func generateMnemonicsFromEntropy(entropy: Data, language: BIP39Language = .english) -> String? {
guard entropy.count >= 16, entropy.count & 4 == 0 else { return nil }
let separator = language.separator
let wordList = generateMnemonicsFrom(entropy: entropy)
let wordList = generateMnemonicsFrom(entropy: entropy, language: language)
return wordList.joined(separator: separator)
}

Expand Down
30 changes: 30 additions & 0 deletions Tests/web3swiftTests/localTests/BIP39Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ final class BIP39Tests: XCTestCase {
XCTAssert(keystore1?.addresses?.first == keystore2?.addresses?.first)
}

/// It's expected for the entropy bits count to be [128, 256] and (bits mod 32) must return 0.
func testWrongBitsOfEntropyMustThrow() throws {
XCTAssertThrowsError(try BIP39.generateMnemonics(entropy: 127))
XCTAssertThrowsError(try BIP39.generateMnemonics(entropy: 255))
Expand All @@ -166,4 +167,33 @@ final class BIP39Tests: XCTestCase {
XCTAssertFalse(try BIP39.generateMnemonics(entropy: 256).isEmpty)
}

func testBip39CorrectWordsCount() throws {
XCTAssertEqual(try BIP39.generateMnemonics(entropy: 128).count, 12)
XCTAssertEqual(try BIP39.generateMnemonics(entropy: 160).count, 15)
XCTAssertEqual(try BIP39.generateMnemonics(entropy: 192).count, 18)
XCTAssertEqual(try BIP39.generateMnemonics(entropy: 224).count, 21)
XCTAssertEqual(try BIP39.generateMnemonics(entropy: 256).count, 24)
}

func testAllLanguageMnemonics() throws {
for language in BIP39Language.allCases {
let mnemonicPhrase = try BIP39.generateMnemonics(entropy: 128, language: language)
for word in mnemonicPhrase {
guard language.words.contains(word) else {
XCTFail("Given word is not contained in the list of words of selected language available for mnemonics generation: \(word); \(language)")
return
}
}
}
}

func testBip39MnemonicSeparatorUse() throws {
for language in BIP39Language.allCases {
guard let mnemonicPhrase = try BIP39.generateMnemonics(bitsOfEntropy: 128, language: language) else {
XCTFail("Failed to generate BIP39 mnemonics phrase with 128 bits of entropy using language: \(language)")
return
}
XCTAssertEqual(mnemonicPhrase.split(whereSeparator: { $0 == language.separatorCharacter }).count, 12)
}
}
}

0 comments on commit 58c7d08

Please sign in to comment.