Skip to content

Commit

Permalink
Merge pull request #16 from keefertaylor/swift5
Browse files Browse the repository at this point in the history
MnemonicKit Maintainence
  • Loading branch information
keefertaylor authored Apr 25, 2019
2 parents 58c5c80 + eb943e0 commit 117c483
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 64 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
osx_image: xcode10
osx_image: xcode10.2
language: swift
cache:
directories:
Expand All @@ -17,7 +17,7 @@ after_deploy:
- pod trunk push --skip-import-validation --skip-tests --allow-warnings
script:
- set -o pipefail && xcodebuild test -scheme MnemonicKit -destination 'platform=iOS
Simulator,name=iPhone XS,OS=12.0' ONLY_ACTIVE_ARCH=YES | xcpretty
Simulator,name=iPhone XS,OS=12.2' ONLY_ACTIVE_ARCH=YES | xcpretty
after_success:
- slather
- bash <(curl -s https://codecov.io/bash)
Expand Down
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "krzyzanowskim/CryptoSwift" "0.13.1"
github "krzyzanowskim/CryptoSwift" "0.14.0"
4 changes: 2 additions & 2 deletions MnemonicKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "MnemonicKit"
s.version = "1.3.4"
s.version = "1.3.5"
s.summary = "MnemonicKit provides a Swift implementation of BIP39"
s.description = <<-DESC
MnemonicKit provides a Swift implementation of BIP39.
Expand All @@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.homepage = "https://github.com/keefertaylor/MnemonicKit"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Keefer Taylor" => "[email protected]" }
s.source = { :git => "https://github.com/keefertaylor/MnemonicKit.git", :tag => "1.3.4" }
s.source = { :git => "https://github.com/keefertaylor/MnemonicKit.git", :tag => "1.3.5" }
s.source_files = "MnemonicKit/**/*.swift",
s.swift_version = "4.2"
s.ios.deployment_target = "8.0"
Expand Down
11 changes: 6 additions & 5 deletions MnemonicKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,11 @@
TargetAttributes = {
77FE006721BDA092009C3CD1 = {
CreatedOnToolsVersion = 10.1;
LastSwiftMigration = 1020;
};
F8A8C55921CD4C86005684A3 = {
CreatedOnToolsVersion = 10.1;
LastSwiftMigration = 1010;
LastSwiftMigration = 1020;
};
};
};
Expand Down Expand Up @@ -452,7 +453,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.keefertaylor.MnemonicKit.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
Expand All @@ -475,7 +476,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.keefertaylor.MnemonicKit.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
Expand Down Expand Up @@ -510,7 +511,7 @@
SKIP_INSTALL = YES;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand Down Expand Up @@ -546,7 +547,7 @@
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift.h";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand Down
4 changes: 2 additions & 2 deletions MnemonicKit/Data+BitArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import CryptoSwift
import Foundation

public extension UInt8 {
public func mnemonicBits() -> [String] {
func mnemonicBits() -> [String] {
let totalBitsCount = MemoryLayout<UInt8>.size * 8

var bitsArray = [String](repeating: "0", count: totalBitsCount)
Expand All @@ -22,7 +22,7 @@ public extension UInt8 {
}

public extension Data {
public func toBitArray() -> [String] {
func toBitArray() -> [String] {
var toReturn = [String]()
for num: UInt8 in bytes {
toReturn.append(contentsOf: num.mnemonicBits())
Expand Down
2 changes: 1 addition & 1 deletion MnemonicKit/Language/Chinese.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Foundation

extension String {
static let chineseMnemonics = [
static let chineseMnemonics: [String] = [
"",
"",
"",
Expand Down
2 changes: 1 addition & 1 deletion MnemonicKit/Language/English.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Foundation

extension String {
static let englishMnemonics = [
static let englishMnemonics: [String] = [
"abandon",
"ability",
"able",
Expand Down
55 changes: 22 additions & 33 deletions MnemonicKit/Mnemonic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ public enum MnemonicLanguageType {
}
}

public class Mnemonic {
/**
* Generate a mnemonic from the given hex string in the given language.
*
* Parameter hexString: The hex string to generate a mnemonic from.
* Parameter language: The language to use. Default is english.
*/
public enum Mnemonic {
/// Generate a mnemonic from the given hex string in the given language.
///
/// - Parameters:
/// - hexString: The hex string to generate a mnemonic from.
/// - language: The language to use. Default is english.
public static func mnemonicString(from hexString: String, language: MnemonicLanguageType = .english) -> String? {
let seedData = hexString.mnemonicData()
let hashData = seedData.sha256()
Expand All @@ -51,15 +50,16 @@ public class Mnemonic {
return mnemonic.joined(separator: " ")
}

/**
* Generate a deterministic seed string from the given inputs.
*
* Parameter mnemonic: The mnemonic to use.
* Parameter passphrase: An optional passphrase. Default is the empty string.
* Parameter language: The language to use. Default is english.
*/
/// Generate a deterministic seed string from the given inputs.
///
/// - Parameters:
/// - mnemonic: The mnemonic to use.
/// - iterations: The iterations to perform in the PBKDF2 algorithm. Default is 2048.
/// - passphrase: An optional passphrase. Default is the empty string.
/// - language: The language to use. Default is english.
public static func deterministicSeedString(
from mnemonic: String,
iterations: Int = 2_048,
passphrase: String = "",
language _: MnemonicLanguageType = .english
) -> String? {
Expand All @@ -72,19 +72,18 @@ public class Mnemonic {
let saltBytes = saltData.bytes
do {
let bytes =
try PKCS5.PBKDF2(password: passwordBytes, salt: saltBytes, iterations: 2_048, variant: .sha512).calculate()
try PKCS5.PBKDF2(password: passwordBytes, salt: saltBytes, iterations: iterations, variant: .sha512).calculate()
return bytes.toHexString()
} catch {
return nil
}
}

/**
* Generate a mnemonic of the given strength and given language.
*
* Parameter strength: The strength to use. This must be a multiple of 32.
* Parameter language: The language to use. Default is english.
*/
/// Generate a mnemonic of the given strength and given language.
///
/// - Parameters:
/// - strength: The strength to use. This must be a multiple of 32.
/// - language: The language to use. Default is english.
public static func generateMnemonic(strength: Int, language: MnemonicLanguageType = .english)
-> String? {
guard strength % 32 == 0 else {
Expand All @@ -102,9 +101,7 @@ public class Mnemonic {
return mnemonicString(from: hexString, language: language)
}

/**
* Validate that the given string is a valid mnemonic.
*/
/// Validate that the given string is a valid mnemonic.
public static func validate(mnemonic: String) -> Bool {
let normalizedMnemonic = mnemonic.lowercased().trimmingCharacters(in: .whitespacesAndNewlines)
let mnemonicComponents = normalizedMnemonic.components(separatedBy: " ")
Expand Down Expand Up @@ -133,9 +130,7 @@ public class Mnemonic {
}
}

/**
* Change a string into data.
*/
/// Change a string into data.
private static func normalized(string: String) -> Data? {
guard let data = string.data(using: .utf8, allowLossyConversion: true),
let dataString = String(data: data, encoding: .utf8),
Expand All @@ -144,10 +139,4 @@ public class Mnemonic {
}
return normalizedData
}

/** Please do not instantiate this static utility class. */
@available(*, unavailable)
public init() {
fatalError()
}
}
2 changes: 1 addition & 1 deletion MnemonicKit/String+MnemonicData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Foundation

public extension String {
public func mnemonicData() -> Data {
func mnemonicData() -> Data {
let length = self.count
let dataLength = length / 2
var dataToReturn = Data(capacity: dataLength)
Expand Down
28 changes: 12 additions & 16 deletions Tests/MnemonicKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ class MnemonicTests: XCTestCase {
/// Passphrase
private let passphrase = "TREZOR"

/**
* Test that MnemonicKit can generate mnemonic strings from hex representations.
*/
/// Test that MnemonicKit can generate mnemonic strings from hex representations.
func testGenerateMnemonicFromHex() {
guard let vectors = MnemonicTests.dictionaryFromTestInputFile(),
let testCases = vectors[englishTestCases] as? [[String]] else {
Expand All @@ -34,9 +32,7 @@ class MnemonicTests: XCTestCase {
}
}

/**
* Test that MnemonicKit can generate deterministic seed strings strings without a passphrase.
*/
/// Test that MnemonicKit can generate deterministic seed strings strings without a passphrase.
func testGenerateDeterministicSeedStringWithPassphrase() {
guard let vectors = MnemonicTests.dictionaryFromTestInputFile(),
let testCases = vectors[englishTestCases] as? [[String]] else {
Expand Down Expand Up @@ -72,19 +68,19 @@ class MnemonicTests: XCTestCase {
}
}

/** Test mnemonic generation in english. */
/// Test mnemonic generation in english.
public func testGenerateMnemonic() {
let mnemonic = Mnemonic.generateMnemonic(strength: 32)
XCTAssertNotNil(mnemonic)
}

/** Prove that functions work in chinese as well. */
/// Prove that functions work in chinese as well.
public func testGenerateMnemonicChinese() {
let chineseMnemonic = Mnemonic.generateMnemonic(strength: 32, language: .chinese)
XCTAssertNotNil(chineseMnemonic)
}

/** Test input strengths for mnemonic generation. */
/// Test input strengths for mnemonic generation.
public func testMnemonicGenerationStrength() {
let mnemonic32 = Mnemonic.generateMnemonic(strength: 32)
let mnemonic64 = Mnemonic.generateMnemonic(strength: 32)
Expand All @@ -95,7 +91,7 @@ class MnemonicTests: XCTestCase {
XCTAssertNotNil(mnemonic16)
}

/** Test valid chinese and english mnemonics are determined to be valid. */
/// Test valid chinese and english mnemonics are determined to be valid.
public func testValidEnglishAndChineseMnemonics() {
let englishMnemonic =
"pear peasant pelican pen pear peasant pelican pen pear peasant pelican pen pear peasant pelican pen"
Expand All @@ -105,7 +101,7 @@ class MnemonicTests: XCTestCase {
XCTAssertTrue(Mnemonic.validate(mnemonic: chineseMnemonic))
}

/** Test invalid chinese and english mnemonics are determined to be invalid. */
/// Test invalid chinese and english mnemonics are determined to be invalid.
public func testInvalidEnglishAndChineseMnemonics() {
let englishMnemonic = "slacktivist snacktivity snuggie"
let chineseMnemonic = "亂 語"
Expand All @@ -114,31 +110,31 @@ class MnemonicTests: XCTestCase {
XCTAssertFalse(Mnemonic.validate(mnemonic: chineseMnemonic))
}

/** Test the empty string is determined to be an invalid mnemonic. */
/// Test the empty string is determined to be an invalid mnemonic.
public func testEmptyStringValidation() {
XCTAssertFalse(Mnemonic.validate(mnemonic: ""))
}

/** Test that strings in an unknown language are determined to be invalid. */
/// Test that strings in an unknown language are determined to be invalid.
public func testUnknownLanguageValidation() {
let spanishMnemonic =
"pera campesina pelican pen pera campesina pelican pen pera campesina pelican pen pera campesina pelican pen"
XCTAssertFalse(Mnemonic.validate(mnemonic: spanishMnemonic))
}

/** Test that strings of mixed case are determined to be valid. */
/// Test that strings of mixed case are determined to be valid.
public func testMixedCaseValidation() {
let mixedCaseMnemonic = "pear PEASANT PeLiCaN pen"
XCTAssertTrue(Mnemonic.validate(mnemonic: mixedCaseMnemonic))
}

/** Test mixed language mnemonics. */
/// Test mixed language mnemonics.
public func testMixedLanguageMnemonicValidation() {
let mixedLanguageMnemonic = "pear peasant pelican pen 路 级 少 图"
XCTAssertFalse(Mnemonic.validate(mnemonic: mixedLanguageMnemonic))
}

/** Test that strings padded with whitespace are determined to be valid. */
/// Test that strings padded with whitespace are determined to be valid.
public func testWhitespacePaddedValidation() {
let whitespacePaddedMnemonic = " pear peasant pelican pen\t\t\n"
XCTAssertTrue(Mnemonic.validate(mnemonic: whitespacePaddedMnemonic))
Expand Down

0 comments on commit 117c483

Please sign in to comment.