Adding MnemonicKit sources to XCode.

This commit is contained in:
keefertaylor 2018-10-28 18:36:03 +00:00
parent b9aea2d689
commit 176d9ae9f8
7 changed files with 241 additions and 0 deletions

View File

@ -12,6 +12,10 @@
778602B42186370E0036843F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 778602B22186370E0036843F /* Main.storyboard */; };
778602B62186370F0036843F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 778602B52186370F0036843F /* Assets.xcassets */; };
778602B92186370F0036843F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 778602B72186370F0036843F /* LaunchScreen.storyboard */; };
778602C6218638FB0036843F /* String+MnemonicData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778602C2218638FB0036843F /* String+MnemonicData.swift */; };
778602C7218638FB0036843F /* CKMnemonic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778602C3218638FB0036843F /* CKMnemonic.swift */; };
778602C8218638FB0036843F /* Data+CKBitArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778602C4218638FB0036843F /* Data+CKBitArray.swift */; };
778602C9218638FB0036843F /* Language in Resources */ = {isa = PBXBuildFile; fileRef = 778602C5218638FB0036843F /* Language */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -22,6 +26,10 @@
778602B52186370F0036843F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
778602B82186370F0036843F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
778602BA2186370F0036843F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
778602C2218638FB0036843F /* String+MnemonicData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+MnemonicData.swift"; sourceTree = "<group>"; };
778602C3218638FB0036843F /* CKMnemonic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CKMnemonic.swift; sourceTree = "<group>"; };
778602C4218638FB0036843F /* Data+CKBitArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+CKBitArray.swift"; sourceTree = "<group>"; };
778602C5218638FB0036843F /* Language */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Language; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -54,6 +62,7 @@
778602AD2186370E0036843F /* Sources */ = {
isa = PBXGroup;
children = (
778602C1218638BF0036843F /* MnemonicKit */,
778602C0218637FB0036843F /* App */,
);
path = Sources;
@ -72,6 +81,17 @@
path = App;
sourceTree = "<group>";
};
778602C1218638BF0036843F /* MnemonicKit */ = {
isa = PBXGroup;
children = (
778602C3218638FB0036843F /* CKMnemonic.swift */,
778602C4218638FB0036843F /* Data+CKBitArray.swift */,
778602C5218638FB0036843F /* Language */,
778602C2218638FB0036843F /* String+MnemonicData.swift */,
);
path = MnemonicKit;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -130,6 +150,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
778602C9218638FB0036843F /* Language in Resources */,
778602B92186370F0036843F /* LaunchScreen.storyboard in Resources */,
778602B62186370F0036843F /* Assets.xcassets in Resources */,
778602B42186370E0036843F /* Main.storyboard in Resources */,
@ -143,8 +164,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
778602C8218638FB0036843F /* Data+CKBitArray.swift in Sources */,
778602B12186370E0036843F /* ViewController.swift in Sources */,
778602AF2186370E0036843F /* AppDelegate.swift in Sources */,
778602C6218638FB0036843F /* String+MnemonicData.swift in Sources */,
778602C7218638FB0036843F /* CKMnemonic.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,122 @@
//
// CKMnemonic.swift
// Pods
//
// Created by on 2017/7/24.
//
//
import Foundation
import CryptoSwift
import Security
public enum CKMnemonicLanguageType {
case english
case chinese
func words() -> [String] {
switch self {
case .english:
return String.englishMnemonics
case .chinese:
return String.chineseMnemonics
}
}
}
enum CKMnemonicError: Error
{
case invalidStrength
case unableToGetRandomData
case unableToCreateSeedData
}
public class CKMnemonic: NSObject {
public static func mnemonicString(from hexString: String, language: CKMnemonicLanguageType) throws -> String {
let seedData = hexString.ck_mnemonicData()
// print("\(hexString.characters.count)\t\(seedData.count)")
let hashData = seedData.sha256()
// print(hashData.toHexString())
let checkSum = hashData.ck_toBitArray()
// print(checkSum)
var seedBits = seedData.ck_toBitArray()
for i in 0..<seedBits.count / 32 {
seedBits.append(checkSum[i])
}
let words = language.words()
let mnemonicCount = seedBits.count / 11
var mnemonic = [String]()
for i in 0..<mnemonicCount {
let length = 11
let startIndex = i * length
let subArray = seedBits[startIndex..<startIndex + length]
let subString = subArray.joined(separator: "")
// print(subString)
let index = Int(strtoul(subString, nil, 2))
mnemonic.append(words[index])
}
return mnemonic.joined(separator: " ")
}
public static func deterministicSeedString(from mnemonic: String, passphrase: String = "", language: CKMnemonicLanguageType) throws -> String {
func normalized(string: String) -> Data? {
guard let data = string.data(using: .utf8, allowLossyConversion: true) else {
return nil
}
guard let dataString = String(data: data, encoding: .utf8) else {
return nil
}
guard let normalizedData = dataString.data(using: .utf8, allowLossyConversion: false) else {
return nil
}
return normalizedData
}
guard let normalizedData = normalized(string: mnemonic) else {
return ""
}
guard let saltData = normalized(string: "mnemonic" + passphrase) else {
return ""
}
let password = normalizedData.bytes
let salt = saltData.bytes
do {
let bytes = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 2048, variant: .sha512).calculate()
return bytes.toHexString()
} catch {
// print(error)
throw error
}
}
public static func generateMnemonic(strength: Int, language: CKMnemonicLanguageType) throws -> String {
guard strength % 32 == 0 else {
throw CKMnemonicError.invalidStrength
}
let count = strength / 8
let bytes = Array<UInt8>(repeating: 0, count: count)
let status = SecRandomCopyBytes(kSecRandomDefault, count, UnsafeMutablePointer<UInt8>(mutating: bytes))
// print(status)
if status != -1 {
let data = Data(bytes: bytes)
let hexString = data.toHexString()
// print(hexString)
return try mnemonicString(from: hexString, language: language)
}
throw CKMnemonicError.unableToGetRandomData
}
}

View File

@ -0,0 +1,39 @@
//
// Data+CKBitArray.swift
// CKMnemonic
//
// Created by on 2017/7/25.
// Copyright © 2017 askcoin. All rights reserved.
//
import Foundation
import CryptoSwift
public extension UInt8 {
public func ck_bits() -> [String] {
let totalBitsCount = MemoryLayout<UInt8>.size * 8
var bitsArray = [String](repeating: "0", count: totalBitsCount)
for j in 0 ..< totalBitsCount {
let bitVal: UInt8 = 1 << UInt8(totalBitsCount - 1 - j)
let check = self & bitVal
if (check != 0) {
bitsArray[j] = "1"
}
}
return bitsArray
}
}
public extension Data {
public func ck_toBitArray() -> [String] {
var toReturn = [String]()
for num: UInt8 in bytes {
toReturn.append(contentsOf: num.ck_bits())
}
return toReturn
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,32 @@
//
// String+MnemonicData.swift
// CKMnemonic
//
// Created by on 2017/7/25.
// Copyright © 2017 askcoin. All rights reserved.
//
import Foundation
public extension String
{
public func ck_mnemonicData() -> Data {
let length = characters.count
let dataLength = length / 2
var dataToReturn = Data(capacity: dataLength)
var index = 0
var chars = ""
for char in characters {
chars += String(char)
if index % 2 == 1 {
let i: UInt8 = UInt8(strtoul(chars, nil, 16))
dataToReturn.append(i)
chars = ""
}
index += 1
}
return dataToReturn
}
}