Skip to content

Commit

Permalink
Merge pull request #255 from tangem/IOS-3059_seed
Browse files Browse the repository at this point in the history
IOS-3059 Seed generation
  • Loading branch information
tureck1y authored Mar 20, 2023
2 parents 06ff871 + ccf272a commit 00fceec
Show file tree
Hide file tree
Showing 45 changed files with 4,514 additions and 127 deletions.
3 changes: 2 additions & 1 deletion TangemSdk.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Tangem is a Swiss-based secure hardware wallet manufacturer that enables blockch
s.weak_frameworks = 'CoreNFC', 'CryptoKit', 'Combine', 'SwiftUI'

s.resource_bundles = { 'TangemSdk' => ['TangemSdk/TangemSdk/**/*.lproj/*.strings',
'TangemSdk/TangemSdk/Haptics/*.ahap']}
'TangemSdk/TangemSdk/Haptics/*.ahap',
'TangemSdk/TangemSdk/**/Wordlists/*.txt']}

end
126 changes: 125 additions & 1 deletion TangemSdk/TangemSdk.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions TangemSdk/TangemSdk/Common/Extensions/Byte+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Foundation
import CryptoKit

public typealias Byte = UInt8

Expand All @@ -18,6 +19,23 @@ extension UInt8 {
public var hexString: String {
return String(format: "%02X", self)
}

func toBits() -> [String] {
let totalBitsCount = 8

var bits = [String](repeating: "0", count: totalBitsCount)

for index in 0..<totalBitsCount {
let mask: UInt8 = 1 << UInt8(totalBitsCount - 1 - index)
let currentBit = self & mask

if currentBit != 0 {
bits[index] = "1"
}
}

return bits
}
}

extension UInt16 {
Expand All @@ -29,3 +47,20 @@ extension UInt16 {
return String(format: "%02X", self)
}
}

@available(iOS 13.0, *)
extension Array where Element == UInt8 {
public func getSha256() -> Data {
let digest = SHA256.hash(data: self)
return Data(digest)
}

public func getSha512() -> Data {
let digest = SHA512.hash(data: self)
return Data(digest)
}

public func getDoubleSha256() -> Data {
return getSha256().getSha256()
}
}
59 changes: 55 additions & 4 deletions TangemSdk/TangemSdk/Common/Extensions/Data+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension Data {
return hexString
}

public func toInt() -> Int {
public func toInt() -> Int? {
return Int(hexData: self)
}

Expand All @@ -38,6 +38,20 @@ extension Data {
let calendar = Calendar.current
return calendar.date(from: components)
}

@available(iOS 13.0, *)
public var sha256Ripemd160: Data {
var md = RIPEMD160()
let hash = getSha256()
md.update(data: hash)
return md.finalize()
}

public var ripemd160: Data {
var md = RIPEMD160()
md.update(data: self)
return md.finalize()
}

public init(hexString: String) {
self = Data()
Expand Down Expand Up @@ -82,7 +96,30 @@ extension Data {
public init(_ byte: Byte) {
self = Data([byte])
}


init?(bitsString: String) {
let byteLength = 8

guard bitsString.count % byteLength == 0 else {
return nil
}

let binaryBytes = Array(bitsString).chunked(into: byteLength)

var bytes = [UInt8]()
bytes.reserveCapacity(bitsString.count / byteLength)

for binaryByte in binaryBytes {
guard let byte = UInt8(String(binaryByte), radix: 2) else {
return nil
}

bytes.append(byte)
}

self = Data(bytes)
}

@available(iOS 13.0, *)
public func getSha256() -> Data {
let digest = SHA256.hash(data: self)
Expand All @@ -94,10 +131,19 @@ extension Data {
let digest = SHA512.hash(data: self)
return Data(digest)
}

@available(iOS 13.0, *)
public func getDoubleSha256() -> Data {
return getSha256().getSha256()
}

public var toBytes: [Byte] {
return Array(self)
}

func toBits() -> [String] {
return flatMap { $0.toBits() }
}

@available(iOS 13.0, *)
func decodeTlv<T>(tag: TlvTag) -> T? {
Expand Down Expand Up @@ -145,8 +191,13 @@ extension Data {
}

@available(iOS 13.0, *)
public func pbkdf2sha256(salt: Data, rounds: Int) throws -> Data {
return try pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), salt: salt, keyByteCount: 32, rounds: rounds)
public func pbkdf2sha256(salt: Data, rounds: Int, keyByteCount: Int = 32) throws -> Data {
return try pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), salt: salt, keyByteCount: keyByteCount, rounds: rounds)
}

@available(iOS 13.0, *)
public func pbkdf2sha512(salt: Data, rounds: Int, keyByteCount: Int = 64) throws -> Data {
return try pbkdf2(hash: CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), salt: salt, keyByteCount: keyByteCount, rounds: rounds)
}

//SO14443A
Expand Down
27 changes: 27 additions & 0 deletions TangemSdk/TangemSdk/Common/Extensions/HexConvertible.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// HexConvertible.swift
// TangemSdk
//
// Created by Alexander Osokin on 09.03.2023.
// Copyright © 2023 Tangem AG. All rights reserved.
//

import Foundation

// Convert hex data to Integer
public protocol HexConvertible {
init?(hexData: Data)
}

public extension HexConvertible where Self: FixedWidthInteger {
init?(hexData: Data) {
guard let intValue = Self(hexData.hexString, radix: 16) else {
return nil
}

self = intValue
}
}

extension Int: HexConvertible {}
extension UInt64: HexConvertible {}
9 changes: 0 additions & 9 deletions TangemSdk/TangemSdk/Common/Extensions/Int+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@
import Foundation

extension Int {
/// Convert hex data to Integer
/// - Parameter hexData: length bytes
public init(hexData: Data) {
let value = hexData.reduce(0) { v, byte in
return v << 8 | Int(byte)
}
self = value
}

/// Convert int to byte, truncatingIfNeeded
public var byte: Data {
return Data([Byte(truncatingIfNeeded: self)])
Expand Down
18 changes: 6 additions & 12 deletions TangemSdk/TangemSdk/Common/Extensions/String+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,12 @@ public extension String {
internal func trim() -> String {
return trimmingCharacters(in: .whitespacesAndNewlines)
}

internal func camelCaseToSnakeCase() -> String {
let acronymPattern = "([A-Z]+)([A-Z][a-z]|[0-9])"
let normalPattern = "([a-z0-9])([A-Z])"
return self.processCamelCaseRegex(pattern: acronymPattern)?
.processCamelCaseRegex(pattern: normalPattern)?.lowercased() ?? self.lowercased()
}

private func processCamelCaseRegex(pattern: String) -> String? {
let regex = try? NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: count)
return regex?.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "$1_$2")

internal func leadingZeroPadding(toLength newLength: Int) -> String {
guard count < newLength else { return self }

let prefix = String(repeating: "0", count: newLength - count)
return prefix + self
}
}

Expand Down
20 changes: 0 additions & 20 deletions TangemSdk/TangemSdk/Common/HDWallet/BIP32/BIP32.swift

This file was deleted.

61 changes: 0 additions & 61 deletions TangemSdk/TangemSdk/Common/HDWallet/BIP32/ExtendedPublicKey.swift

This file was deleted.

29 changes: 19 additions & 10 deletions TangemSdk/TangemSdk/Common/TLV/TlvDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,30 +136,38 @@ public final class TlvDecoder {
case .settingsMask:
do {
try typeCheck(CardSettingsMask.self, T.self, for: tag)
let intValue = tagValue.toInt()
guard let intValue = tagValue.toInt() else {
throw TangemSdkError.decodingFailed("Decoding error. Failed convert \(tag) to SettingsMask")
}

let settingsMask = CardSettingsMask(rawValue: intValue)
return settingsMask as! T
} catch TangemSdkError.decodingFailedTypeMismatch {
try typeCheck(WalletSettingsMask.self, T.self, for: tag)
let intValue = tagValue.toInt()
guard let intValue = tagValue.toInt() else {
throw TangemSdkError.decodingFailed("Decoding error. Failed convert \(tag) to WalletSettingsMask")
}

let settingsMask = WalletSettingsMask(rawValue: intValue)
return settingsMask as! T
}
case .status:
do {
try typeCheck(Card.Status.self, T.self, for: tag)
let intValue = tagValue.toInt()
guard let cardStatus = Card.Status(rawValue: intValue) else {
guard let intValue = tagValue.toInt(),
let cardStatus = Card.Status(rawValue: intValue) else {
throw TangemSdkError.decodingFailed("Decoding error. Failed convert \(tag) to int and CardStatus")
}

return cardStatus as! T
} catch TangemSdkError.decodingFailedTypeMismatch {
try typeCheck(Card.Wallet.Status.self, T.self, for: tag)
let intValue = tagValue.toInt()
guard let walletStatus = Card.Wallet.Status(rawValue: intValue) else {

guard let intValue = tagValue.toInt(),
let walletStatus = Card.Wallet.Status(rawValue: intValue) else {
throw TangemSdkError.decodingFailed("Decoding error. Failed convert \(tag) to int and WalletStatus")
}

return walletStatus as! T
}
case .signingMethod:
Expand Down Expand Up @@ -195,10 +203,11 @@ public final class TlvDecoder {
try typeCheck(DerivationPath.self, T.self, for: tag)
return try DerivationPath(from: tagValue) as! T
case .backupStatus:
let intValue = tagValue.toInt()

try typeCheck(Card.BackupRawStatus.self, T.self, for: tag)
guard let status = Card.BackupRawStatus.make(from: intValue) else {
throw TangemSdkError.decodingFailed("Decoding error. Unknown iBackupStatus")
guard let intValue = tagValue.toInt(),
let status = Card.BackupRawStatus.make(from: intValue) else {
throw TangemSdkError.decodingFailed("Decoding error. Unknown BackupRawStatus")
}
return status as! T
}
Expand Down
Loading

0 comments on commit 00fceec

Please sign in to comment.