Skip to content

Commit

Permalink
Merge pull request #2 from soramitsu/feature/seed-factory
Browse files Browse the repository at this point in the history
Seed factory
  • Loading branch information
ERussel authored Jul 23, 2020
2 parents 0fa20f1 + c8e3002 commit 58d4a1f
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 1 deletion.
14 changes: 14 additions & 0 deletions Example/FearlessUtils.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
845D80ED24C8D91A00EC2540 /* SeedFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845D80EC24C8D91A00EC2540 /* SeedFactoryTests.swift */; };
84DA3B3C24C8CE5900B5E27F /* ScaleUInt32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA3B3224C8CE5900B5E27F /* ScaleUInt32Tests.swift */; };
84DA3B3D24C8CE5900B5E27F /* ScaleCompactIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA3B3324C8CE5900B5E27F /* ScaleCompactIntTests.swift */; };
84DA3B3E24C8CE5900B5E27F /* ScaleInt64Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA3B3424C8CE5900B5E27F /* ScaleInt64Tests.swift */; };
Expand Down Expand Up @@ -48,6 +49,7 @@
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
607FACE51AFB9204008FA782 /* FearlessUtils_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FearlessUtils_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7BCE5EB68B0A48835979E64A /* Pods-FearlessUtils_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FearlessUtils_Tests.debug.xcconfig"; path = "Target Support Files/Pods-FearlessUtils_Tests/Pods-FearlessUtils_Tests.debug.xcconfig"; sourceTree = "<group>"; };
845D80EC24C8D91A00EC2540 /* SeedFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedFactoryTests.swift; sourceTree = "<group>"; };
84DA3B3224C8CE5900B5E27F /* ScaleUInt32Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScaleUInt32Tests.swift; sourceTree = "<group>"; };
84DA3B3324C8CE5900B5E27F /* ScaleCompactIntTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScaleCompactIntTests.swift; sourceTree = "<group>"; };
84DA3B3424C8CE5900B5E27F /* ScaleInt64Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScaleInt64Tests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -140,9 +142,18 @@
name = "Podspec Metadata";
sourceTree = "<group>";
};
845D80EB24C8D8F500EC2540 /* Common */ = {
isa = PBXGroup;
children = (
845D80EC24C8D91A00EC2540 /* SeedFactoryTests.swift */,
);
path = Common;
sourceTree = "<group>";
};
84DA3B3024C8CE5900B5E27F /* Tests */ = {
isa = PBXGroup;
children = (
845D80EB24C8D8F500EC2540 /* Common */,
84DA3B4824C8CEEF00B5E27F /* Info.plist */,
84DA3B3124C8CE5900B5E27F /* Scale */,
);
Expand Down Expand Up @@ -300,12 +311,14 @@
"${BUILT_PRODUCTS_DIR}/BigInt/BigInt.framework",
"${BUILT_PRODUCTS_DIR}/FearlessUtils/FearlessUtils.framework",
"${BUILT_PRODUCTS_DIR}/IrohaCrypto/IrohaCrypto.framework",
"${BUILT_PRODUCTS_DIR}/xxHash-Swift/xxHash_Swift.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FearlessUtils.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IrohaCrypto.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/xxHash_Swift.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down Expand Up @@ -380,6 +393,7 @@
84DA3B4324C8CE5A00B5E27F /* ScaleStringTests.swift in Sources */,
84DA3B4224C8CE5A00B5E27F /* ScaleUInt64Tests.swift in Sources */,
84DA3B4124C8CE5A00B5E27F /* ScaleInt32Tests.swift in Sources */,
845D80ED24C8D91A00EC2540 /* SeedFactoryTests.swift in Sources */,
84DA3B3C24C8CE5900B5E27F /* ScaleUInt32Tests.swift in Sources */,
84DA3B3F24C8CE5900B5E27F /* ScaleUInt16Tests.swift in Sources */,
);
Expand Down
6 changes: 5 additions & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PODS:
- FearlessUtils (0.1.0):
- BigInt (~> 5.0)
- IrohaCrypto/sr25519 (~> 0.4.0)
- xxHash-Swift (~> 1.0.0)
- IrohaCrypto/BIP39 (0.4.3):
- IrohaCrypto/Common
- IrohaCrypto/blake2 (0.4.3)
Expand All @@ -11,6 +12,7 @@ PODS:
- IrohaCrypto/BIP39
- IrohaCrypto/blake2
- IrohaCrypto/Common
- xxHash-Swift (1.0.13)

DEPENDENCIES:
- FearlessUtils (from `../`)
Expand All @@ -19,15 +21,17 @@ SPEC REPOS:
trunk:
- BigInt
- IrohaCrypto
- xxHash-Swift

EXTERNAL SOURCES:
FearlessUtils:
:path: "../"

SPEC CHECKSUMS:
BigInt: 74b4d88367b0e819d9f77393549226d36faeb0d8
FearlessUtils: 58a574cf727db20bde817672506d4cc38a1e70d7
FearlessUtils: aef3e364c3767287e5302cedff888d3e13dddcdd
IrohaCrypto: cfdfe162065705d1055bed4e37345abcbf5184de
xxHash-Swift: 30bd6a7507b3b7348a277c49b1cb6346c2905ec7

PODFILE CHECKSUM: 002fb4b06641c82f822cb8ddc9d08ba3f79755d6

Expand Down
1 change: 1 addition & 0 deletions FearlessUtils.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Pod::Spec.new do |s|
s.source_files = 'FearlessUtils/Classes/**/*'
s.dependency 'IrohaCrypto/sr25519', '~> 0.4.0'
s.dependency 'BigInt', '~> 5.0'
s.dependency 'xxHash-Swift', '~> 1.0.0'

s.test_spec do |ts|
ts.source_files = 'Tests/**/*.swift'
Expand Down
25 changes: 25 additions & 0 deletions FearlessUtils/Classes/Common/Data+Hash.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation
import xxHash_Swift
import IrohaCrypto

public extension Data {
func xxh128() -> Data {
var hash1Value = XXH64.digest(self, seed: 0)
let hash1 = Data(bytes: &hash1Value, count: MemoryLayout<UInt64>.size)

var hash2Value = XXH64.digest(self, seed: 1)
let hash2 = Data(bytes: &hash2Value, count: MemoryLayout<UInt64>.size)

return hash1 + hash2
}

func blake128Concat() throws -> Data {
let hashed = try (self as NSData).blake2b(16)
return hashed + self
}

func twox64Concat() -> Data {
var hash1Value = XXH64.digest(self, seed: 0)
return Data(bytes: &hash1Value, count: MemoryLayout<UInt64>.size) + self
}
}
36 changes: 36 additions & 0 deletions FearlessUtils/Classes/Common/SeedFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation
import IrohaCrypto

public typealias SeedFactoryResult = (seed: Data, mnemonic: IRMnemonicProtocol)

public protocol SeedFactoryProtocol {
func createSeed(from password: String, strength: IRMnemonicStrength) throws -> SeedFactoryResult
func deriveSeed(from mnemonicWords: String, password: String) throws -> SeedFactoryResult
}

public struct SeedFactory: SeedFactoryProtocol {
private static let seedLength: Int = 32

private let seedFactory: SNBIP39SeedCreatorProtocol = SNBIP39SeedCreator()
private let mnemonicCreator: IRMnemonicCreatorProtocol

public init(mnemonicLanguage: IRMnemonicLanguage = .english) {
mnemonicCreator = IRMnemonicCreator(language: mnemonicLanguage)
}

public func createSeed(from password: String,
strength: IRMnemonicStrength) throws -> SeedFactoryResult {
let mnemonic = try mnemonicCreator.randomMnemonic(strength)
let seed = try seedFactory.deriveSeed(from: mnemonic.entropy(), passphrase: password)

return SeedFactoryResult(seed: seed.prefix(Self.seedLength), mnemonic: mnemonic)
}

public func deriveSeed(from mnemonicWords: String,
password: String) throws -> SeedFactoryResult {
let mnemonic = try mnemonicCreator.mnemonic(fromList: mnemonicWords)
let seed = try seedFactory.deriveSeed(from: mnemonic.entropy(), passphrase: password)

return SeedFactoryResult(seed: seed.prefix(Self.seedLength), mnemonic: mnemonic)
}
}
30 changes: 30 additions & 0 deletions Tests/Common/SeedFactoryTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import XCTest
import FearlessUtils
import IrohaCrypto

class SeedFactoryTests: XCTestCase {
func testGeneratedSeedMatchesDerived() throws {
let passwords: [String] = ["", "password"]
let strengths: [IRMnemonicStrength] = [
.entropy128,
.entropy160,
.entropy192,
.entropy224,
.entropy256,
.entropy288,
.entropy320
]

let seedFactory = SeedFactory()

for password in passwords {
for strength in strengths {
let expectedResult = try seedFactory.createSeed(from: password, strength: strength)
let derivedResult = try seedFactory.deriveSeed(from: expectedResult.mnemonic.toString(),
password: password)

XCTAssertEqual(expectedResult.seed, derivedResult.seed)
}
}
}
}

0 comments on commit 58d4a1f

Please sign in to comment.