|
| 1 | +// |
| 2 | +// BIP39Tests.swift |
| 3 | +// |
| 4 | +// |
| 5 | +// Created by Daniel Bell on 11/26/22. |
| 6 | +// |
| 7 | + |
| 8 | +import XCTest |
| 9 | +@testable import Core |
| 10 | +@testable import web3swift |
| 11 | + |
| 12 | +final class BIP39Tests: XCTestCase { |
| 13 | + |
| 14 | + func testBIP39 () throws { |
| 15 | + var entropy = Data.fromHex("00000000000000000000000000000000")! |
| 16 | + var phrase = BIP39.generateMnemonicsFromEntropy(entropy: entropy) |
| 17 | + XCTAssert( phrase == "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") |
| 18 | + var seed = BIP39.seedFromMmemonics(phrase!, password: "TREZOR") |
| 19 | + XCTAssert(seed?.toHexString() == "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04") |
| 20 | + entropy = Data.fromHex("68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c")! |
| 21 | + phrase = BIP39.generateMnemonicsFromEntropy(entropy: entropy) |
| 22 | + XCTAssert( phrase == "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length") |
| 23 | + seed = BIP39.seedFromMmemonics(phrase!, password: "TREZOR") |
| 24 | + XCTAssert(seed?.toHexString() == "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440") |
| 25 | + } |
| 26 | + |
| 27 | + func testBIP39SeedAndMnemConversions() throws { |
| 28 | + let seed = Data.randomBytes(length: 32)! |
| 29 | + let mnemonics = BIP39.generateMnemonicsFromEntropy(entropy: seed) |
| 30 | + let recoveredSeed = BIP39.mnemonicsToEntropy(mnemonics!, language: .english) |
| 31 | + XCTAssert(seed == recoveredSeed) |
| 32 | + } |
| 33 | + |
| 34 | +// https://github.com/trezor/python-mnemonic/blob/master/vectors.json |
| 35 | + func testBIP39MnemonicIsMultipleOfThree() { |
| 36 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L95 |
| 37 | + let mnemonic_12 = "scheme spot photo card baby mountain device kick cradle pact join borrow" |
| 38 | + let entropy_12 = BIP39.mnemonicsToEntropy(mnemonic_12, language: .english) |
| 39 | + XCTAssertEqual(entropy_12!.toHexString(), "c0ba5a8e914111210f2bd131f3d5e08d") |
| 40 | + |
| 41 | + let mnemonic_15 = "foster muscle start pluck when army tool surprise essay monitor impulse hello segment garage twenty" |
| 42 | + let entropy_15 = BIP39.mnemonicsToEntropy(mnemonic_15, language: .english) |
| 43 | + XCTAssertEqual(entropy_15!.toHexString(), "5c123352d35fa218392ed34d31e1c8b56c32befa") |
| 44 | + |
| 45 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L101 |
| 46 | + let mnemonic_18 = "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave" |
| 47 | + let entropy_18 = BIP39.mnemonicsToEntropy(mnemonic_18, language: .english) |
| 48 | + XCTAssertEqual(entropy_18!.toHexString(), "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3") |
| 49 | + |
| 50 | + let mnemonic_21 = "weird change toe upper damp panel unaware long noise resource grant prevent file live travel price cry danger fix manage base" |
| 51 | + let entropy_21 = BIP39.mnemonicsToEntropy(mnemonic_21, language: .english) |
| 52 | + XCTAssertEqual(entropy_21!.toHexString(), "f924c78e7783733f3b1c1e95d6f196d525630579e5533526ed604371") |
| 53 | + |
| 54 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L107 |
| 55 | + let mnemonic_24 = "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside" |
| 56 | + let entropy_24 = BIP39.mnemonicsToEntropy(mnemonic_24, language: .english) |
| 57 | + XCTAssertEqual(entropy_24!.toHexString(), "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863") |
| 58 | + |
| 59 | + // Invalid mnemonics |
| 60 | + |
| 61 | + let mnemonic_9 = "initial repeat scout eye october lucky rabbit enact unfair" |
| 62 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_9, language: .english)) |
| 63 | + |
| 64 | + let mnemonic_16 = "success drip spoon lunar effort unfold clinic seminar custom protect orchard correct pledge cousin slab visa" |
| 65 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_16, language: .english)) |
| 66 | + |
| 67 | + let mnemonic_27 = "clock venue style demise net float differ click object poet afraid october hurry organ faint inject cart trade test immense gentle speak almost rude success drip spoon" |
| 68 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_27, language: .english)) |
| 69 | + } |
| 70 | + |
| 71 | + func testNewBIP32keystore() throws { |
| 72 | + let mnemonic = try BIP39.generateMnemonics(bitsOfEntropy: 256)! |
| 73 | + let keystore = try BIP32Keystore(mnemonics: mnemonic, password: "", mnemonicsPassword: "") |
| 74 | + XCTAssert(keystore != nil) |
| 75 | + } |
| 76 | + |
| 77 | + func testSameAddressesFromTheSameMnemonics() throws { |
| 78 | + let mnemonic = try BIP39.generateMnemonics(bitsOfEntropy: 256)! |
| 79 | + let keystore1 = try BIP32Keystore(mnemonics: mnemonic, password: "", mnemonicsPassword: "") |
| 80 | + let keystore2 = try BIP32Keystore(mnemonics: mnemonic, password: "", mnemonicsPassword: "") |
| 81 | + XCTAssert(keystore1?.addresses?.first == keystore2?.addresses?.first) |
| 82 | + } |
| 83 | + //==================================================================== |
| 84 | + func testBIP39Array () throws { |
| 85 | + var entropy = Data.fromHex("00000000000000000000000000000000")! |
| 86 | + var phrase = BIP39.generateMnemonicsFrom(entropy: entropy) |
| 87 | + XCTAssert( phrase == ["abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "abandon", "about"]) |
| 88 | + var seed = BIP39.seedFromMmemonics(phrase, password: "TREZOR") |
| 89 | + XCTAssert(seed?.toHexString() == "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04") |
| 90 | + entropy = Data.fromHex("68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c")! |
| 91 | + phrase = BIP39.generateMnemonicsFrom(entropy: entropy) |
| 92 | + XCTAssert( phrase == ["hamster", "diagram", "private", "dutch", "cause", "delay", "private", "meat", "slide", "toddler", "razor", "book", "happy", "fancy", "gospel", "tennis", "maple", "dilemma", "loan", "word", "shrug", "inflict", "delay", "length"]) |
| 93 | + seed = BIP39.seedFromMmemonics(phrase, password: "TREZOR") |
| 94 | + XCTAssert(seed?.toHexString() == "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440") |
| 95 | + } |
| 96 | + |
| 97 | + func testBIP39SeedAndMnemConversionsArray() throws { |
| 98 | + let seed = Data.randomBytes(length: 32)! |
| 99 | + let mnemonics = BIP39.generateMnemonicsFrom(entropy: seed) |
| 100 | + let recoveredSeed = BIP39.mnemonicsToEntropy(mnemonics, language: .english) |
| 101 | + XCTAssert(seed == recoveredSeed) |
| 102 | + } |
| 103 | + |
| 104 | +// https://github.com/trezor/python-mnemonic/blob/master/vectors.json |
| 105 | + func testBIP39MnemonicIsMultipleOfThreeArray() { |
| 106 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L95 |
| 107 | + let mnemonic_12 = ["scheme", "spot", "photo", "card", "baby", "mountain", "device", "kick", "cradle", "pact", "join", "borrow"] |
| 108 | + let entropy_12 = BIP39.mnemonicsToEntropy(mnemonic_12, language: .english) |
| 109 | + XCTAssertEqual(entropy_12!.toHexString(), "c0ba5a8e914111210f2bd131f3d5e08d") |
| 110 | + |
| 111 | + let mnemonic_15 = ["foster", "muscle", "start", "pluck", "when", "army", "tool", "surprise", "essay", "monitor", "impulse", "hello", "segment", "garage", "twenty"] |
| 112 | + let entropy_15 = BIP39.mnemonicsToEntropy(mnemonic_15, language: .english) |
| 113 | + XCTAssertEqual(entropy_15!.toHexString(), "5c123352d35fa218392ed34d31e1c8b56c32befa") |
| 114 | + |
| 115 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L101 |
| 116 | + let mnemonic_18 = ["horn", "tenant", "knee", "talent", "sponsor", "spell", "gate", "clip", "pulse", "soap", "slush", "warm", "silver", "nephew", "swap", "uncle", "crack", "brave"] |
| 117 | + let entropy_18 = BIP39.mnemonicsToEntropy(mnemonic_18, language: .english) |
| 118 | + XCTAssertEqual(entropy_18!.toHexString(), "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3") |
| 119 | + |
| 120 | + let mnemonic_21 = ["weird", "change", "toe", "upper", "damp", "panel", "unaware", "long", "noise", "resource", "grant", "prevent", "file", "live", "travel", "price", "cry", "danger", "fix", "manage", "base"] |
| 121 | + let entropy_21 = BIP39.mnemonicsToEntropy(mnemonic_21, language: .english) |
| 122 | + XCTAssertEqual(entropy_21!.toHexString(), "f924c78e7783733f3b1c1e95d6f196d525630579e5533526ed604371") |
| 123 | + |
| 124 | + // https://github.com/trezor/python-mnemonic/blob/master/vectors.json#L107 |
| 125 | + let mnemonic_24 = ["panda", "eyebrow", "bullet", "gorilla", "call", "smoke", "muffin", "taste", "mesh", "discover", "soft", "ostrich", "alcohol", "speed", "nation", "flash", "devote", "level", "hobby", "quick", "inner", "drive", "ghost", "inside"] |
| 126 | + let entropy_24 = BIP39.mnemonicsToEntropy(mnemonic_24, language: .english) |
| 127 | + XCTAssertEqual(entropy_24!.toHexString(), "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863") |
| 128 | + |
| 129 | + // Invalid mnemonics |
| 130 | + |
| 131 | + let mnemonic_9 = ["initial", "repeat", "scout", "eye", "october", "lucky", "rabbit", "enact", "unfair"] |
| 132 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_9, language: .english)) |
| 133 | + |
| 134 | + let mnemonic_16 = ["success", "drip", "spoon", "lunar", "effort", "unfold", "clinic", "seminar", "custom", "protect", "orchard", "correct", "pledge", "cousin", "slab", "visa"] |
| 135 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_16, language: .english)) |
| 136 | + |
| 137 | + let mnemonic_27 = ["clock", "venue", "style", "demise", "net", "float", "differ", "click", "object", "poet", "afraid", "october", "hurry", "organ", "faint", "inject", "cart", "trade", "test", "immense", "gentle", "speak", "almost", "rude", "success", "drip", "spoon"] |
| 138 | + XCTAssertNil(BIP39.mnemonicsToEntropy(mnemonic_27, language: .english)) |
| 139 | + } |
| 140 | + |
| 141 | + func testNewBIP32keystoreArray() throws { |
| 142 | + let mnemonic = BIP39.generateMnemonics(entropy: 256)! |
| 143 | + let keystore = try BIP32Keystore(mnemonicsPhrase: mnemonic, password: "", mnemonicsPassword: "") |
| 144 | + XCTAssert(keystore != nil) |
| 145 | + } |
| 146 | + |
| 147 | + func testSameAddressesFromTheSameMnemonicsArray() throws { |
| 148 | + let mnemonic = BIP39.generateMnemonics(entropy: 256)! |
| 149 | + let keystore1 = try BIP32Keystore(mnemonicsPhrase: mnemonic, password: "", mnemonicsPassword: "") |
| 150 | + let keystore2 = try BIP32Keystore(mnemonicsPhrase: mnemonic, password: "", mnemonicsPassword: "") |
| 151 | + XCTAssert(keystore1?.addresses?.first == keystore2?.addresses?.first) |
| 152 | + } |
| 153 | + |
| 154 | +} |
0 commit comments