@@ -147,9 +147,51 @@ public enum Mnemonic {
147147 }
148148
149149 public static func isValidBip39Mnemonic( mnemonicArray: [ String ] ) -> Bool {
150- guard !mnemonicArray. isEmpty else { return false }
151- guard mnemonicArray. allSatisfy ( { words. contains ( $0) } ) else { return false }
152- return mnemonicArray. count % 3 == 0
150+ let mnemonic = normalizeMnemonic ( src: mnemonicArray)
151+
152+ guard !mnemonic. isEmpty,
153+ mnemonic. allSatisfy ( { words. contains ( $0) } ) ,
154+ mnemonic. count % 3 == 0 ,
155+ ( 12 ... 24 ) . contains ( mnemonic. count)
156+ else {
157+ return false
158+ }
159+
160+ var bits = " "
161+ for word in mnemonic {
162+ guard let idx = words. firstIndex ( of: word) else { return false }
163+ let bin = String ( idx, radix: 2 )
164+ bits += String ( repeating: " 0 " , count: 11 - bin. count) + bin
165+ }
166+
167+ let entLength = mnemonic. count * 11 * 32 / 33
168+ let checksumLen = entLength / 32
169+
170+ let entBits = bits. prefix ( entLength)
171+ let csBits = bits. suffix ( checksumLen)
172+
173+ var entropyBytes : [ UInt8 ] = [ ]
174+ var i = entBits. startIndex
175+ while i < entBits. endIndex {
176+ let next = entBits. index ( i, offsetBy: 8 )
177+ let byteStr = String ( entBits [ i..< next] )
178+ guard let byte = UInt8 ( byteStr, radix: 2 ) else { return false }
179+ entropyBytes. append ( byte)
180+ i = next
181+ }
182+
183+ let hashData = Data ( entropyBytes) . sha256 ( )
184+
185+ let hashBits =
186+ hashData
187+ . map { byte -> String in
188+ let bin = String ( byte, radix: 2 )
189+ return String ( repeating: " 0 " , count: 8 - bin. count) + bin
190+ }
191+ . joined ( )
192+ . prefix ( checksumLen)
193+
194+ return csBits == hashBits
153195 }
154196
155197 public static func bip39MnemonicToSeed( mnemonicArray: [ String ] , password: String = " " ) -> Data {
0 commit comments