@@ -43,7 +43,7 @@ public enum BIP39Language {
43
43
return " "
44
44
}
45
45
}
46
-
46
+
47
47
init ? ( language: String ) {
48
48
switch language {
49
49
case " english " :
@@ -78,49 +78,49 @@ public class BIP39 {
78
78
guard let entropy = entropyOf ( size: bitsOfEntropy) else { throw AbstractKeystoreError . noEntropyError }
79
79
return generateMnemonicsFromEntropy ( entropy: entropy, language: language)
80
80
}
81
-
81
+
82
82
static public func generateMnemonics( entropy: Int , language: BIP39Language = . english) -> [ String ] ? {
83
83
guard let entropy = entropyOf ( size: entropy) else { return nil }
84
84
return generateMnemonicsFrom ( entropy: entropy, language: language)
85
85
}
86
-
86
+
87
87
static private func entropyOf( size: Int ) -> Data ? {
88
88
guard size >= 128 && size <= 256 && size. isMultiple ( of: 32 ) else {
89
89
return nil
90
90
}
91
-
91
+
92
92
return Data . randomBytes ( length: size/ 8 )
93
93
}
94
-
94
+
95
95
static func bitarray( from data: Data ) -> String {
96
96
data. map {
97
97
let binary = String ( $0, radix: 2 )
98
98
let padding = String ( repeating: " 0 " , count: 8 - binary. count)
99
99
return padding + binary
100
100
} . joined ( )
101
101
}
102
-
102
+
103
103
static func generateChecksum( entropyBytes inputData: Data , checksumLength: Int ) -> String ? {
104
104
guard let checksumData = inputData. sha256 ( ) . bitsInRange ( 0 , checksumLength) else {
105
105
return nil
106
106
}
107
107
let checksum = String ( checksumData, radix: 2 ) . leftPadding ( toLength: checksumLength, withPad: " 0 " )
108
108
return checksum
109
109
}
110
-
110
+
111
111
static public func generateMnemonicsFromEntropy( entropy: Data , language: BIP39Language = . english) -> String ? {
112
112
guard entropy. count >= 16 , entropy. count & 4 == 0 else { return nil }
113
113
let separator = language. separator
114
114
let wordList = generateMnemonicsFrom ( entropy: entropy)
115
115
return wordList. joined ( separator: separator)
116
116
}
117
-
118
- static public func generateMnemonicsFrom( entropy: Data , language: BIP39Language = . english) -> [ String ] {
117
+
118
+ static public func generateMnemonicsFrom( entropy: Data , language: BIP39Language = . english) -> [ String ] {
119
119
let entropyBitSize = entropy. count * 8
120
120
let checksum_length = entropyBitSize / 32
121
-
121
+
122
122
var entropy_bits = bitarray ( from: entropy)
123
-
123
+
124
124
guard let checksumTest = generateChecksum ( entropyBytes: entropy, checksumLength: checksum_length) else {
125
125
return [ ]
126
126
}
@@ -134,12 +134,12 @@ public class BIP39 {
134
134
language. words [ index]
135
135
}
136
136
}
137
-
137
+
138
138
static public func mnemonicsToEntropy( _ mnemonics: String , language: BIP39Language = . english) -> Data ? {
139
139
let wordList = mnemonics. components ( separatedBy: language. separator)
140
140
return mnemonicsToEntropy ( wordList, language: language)
141
141
}
142
-
142
+
143
143
static public func mnemonicsToEntropy( _ mnemonics: [ String ] , language: BIP39Language = . english) -> Data ? {
144
144
guard mnemonics. count >= 12 && mnemonics. count. isMultiple ( of: 3 ) && mnemonics. count <= 24 else { return nil }
145
145
var bitString = " "
@@ -165,27 +165,27 @@ public class BIP39 {
165
165
}
166
166
return entropy
167
167
}
168
-
168
+
169
169
static public func seedFromMmemonics( _ mnemonics: [ String ] , password: String = " " , language: BIP39Language = . english) -> Data ? {
170
170
let wordList = mnemonics. joined ( separator: language. separator)
171
171
return seedFromMmemonics ( wordList, password: password, language: language)
172
172
}
173
-
173
+
174
174
static public func seedFromMmemonics( _ mnemonics: String , password: String = " " , language: BIP39Language = . english) -> Data ? {
175
175
if mnemonicsToEntropy ( mnemonics, language: language) == nil {
176
176
return nil
177
177
}
178
178
return dataFrom ( mnemonics: mnemonics, password: password)
179
179
}
180
-
180
+
181
181
static private func dataFrom( mnemonics: String , password: String ) -> Data ? {
182
182
guard let mnemData = mnemonics. decomposedStringWithCompatibilityMapping. data ( using: . utf8) else { return nil }
183
183
let salt = " mnemonic " + password
184
184
guard let saltData = salt. decomposedStringWithCompatibilityMapping. data ( using: . utf8) else { return nil }
185
185
guard let seedArray = try ? PKCS5 . PBKDF2 ( password: mnemData. bytes, salt: saltData. bytes, iterations: 2048 , keyLength: 64 , variant: HMAC . Variant. sha2 ( . sha512) ) . calculate ( ) else { return nil }
186
186
return Data ( seedArray)
187
187
}
188
-
188
+
189
189
static public func seedFromEntropy( _ entropy: Data , password: String = " " , language: BIP39Language = . english) -> Data ? {
190
190
guard let mnemonics = generateMnemonicsFromEntropy ( entropy: entropy, language: language) else {
191
191
return nil
0 commit comments