• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hyperledger / identus-edge-agent-sdk-swift / 9807497631

05 Jul 2024 10:48AM UTC coverage: 41.758% (+0.2%) from 41.529%
9807497631

push

github

goncalo-frade-iohk
feat(agent): add new agent derivation path

Signed-off-by: goncalo-frade-iohk <goncalo.frade@iohk.io>

105 of 138 new or added lines in 13 files covered. (76.09%)

13 existing lines in 4 files now uncovered.

4874 of 11672 relevant lines covered (41.76%)

96.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.24
/EdgeAgentSDK/Domain/Sources/Models/KeyManagement/DerivableKey.swift
1
import Foundation
2

3
/// `DerivationPath` is a structure that represents the path for key derivation in hierarchical deterministic (HD) wallets.
4
public struct DerivationPath {
5

6
    public enum Axis: RawRepresentable {
7
        case normal(Int)
8
        case hardened(Int)
9

NEW
10
        public init?(rawValue: Int) {
×
NEW
11
            if rawValue < 0 {
×
NEW
12
                return nil
×
NEW
13
            }
×
NEW
14
            if rawValue >= 0 && rawValue < (1 << 31) {
×
NEW
15
                self = .normal(rawValue)
×
NEW
16
            } else if rawValue >= (1 << 31) && rawValue < (1 << 32) {
×
NEW
17
                self = .hardened(rawValue - (1 << 31))
×
NEW
18
            } else {
×
NEW
19
                return nil
×
NEW
20
            }
×
NEW
21
        }
×
22

23
        public var rawValue: Int {
186✔
24
            switch self {
186✔
25
            case .normal(let int):
186✔
NEW
26
                return int
×
27
            case .hardened(let int):
186✔
28
                return int
186✔
29
            }
186✔
30
        }
186✔
31

32
        public var string: String {
1,116✔
33
            switch self {
1,116✔
34
            case .normal(let int):
1,116✔
NEW
35
                return "\(int)"
×
36
            case .hardened(let int):
1,116✔
37
                return "\(int)'"
1,116✔
38
            }
1,116✔
39
        }
1,116✔
40
    }
41

42
    /// The index of the key in the path.
43
    @available(*, deprecated, renamed: "axis", message: "Use axis instead this property will be removed on a future version")
44
    public let index: Int
45

46
    public let axis: [Axis]
47

48
    /// Creates a new `DerivationPath` instance from a given index.
49
    /// - Parameter index: The index of the key in the path.
50
    @available(*, deprecated, renamed: "init(axis:)", message: "Use init(axis:) instead this method will be removed on a future version")
51
    public init(index: Int) {
12✔
52
        self.index = index
12✔
53
        self.axis = [.hardened(index), .hardened(0), .hardened(0)]
12✔
54
    }
12✔
55

56
    public init(axis: [Axis] = [.hardened(0), .hardened(0), .hardened(0)]) {
78✔
57
        self.axis = axis
78✔
58
        self.index = axis.first?.rawValue ?? 0
78✔
59
    }
78✔
60

61
    /// Creates a new `DerivationPath` instance from a path string.
62
    /// - Parameter string: A string representation of the path.
63
    /// - Throws: `CommonError.invalidRegex` if the path string cannot be parsed.
64
    public init(string: String) throws {
102✔
65
        let pattern = "^m(\\/\\d+'?)+$"
102✔
66
        let validationRegex = try NSRegularExpression(pattern: pattern, options: [])
102✔
67
        guard !validationRegex.matches(
102✔
68
            in: string,
102✔
69
            options: [],
102✔
70
            range: NSRange(location: 0, length: string.utf16.count)
102✔
71
        ).isEmpty else { throw CommonError.invalidRegex(regex: pattern, invalid: string) }
102✔
72

102✔
73
        let parsingRegex = try NSRegularExpression(pattern: "\\d+", options: [])
102✔
74
        let matches = parsingRegex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
102✔
75

102✔
76
        guard let firstMatch = matches.first else {
102✔
NEW
77
            throw CommonError.invalidRegex(regex: pattern, invalid: string)
×
78
        }
102✔
79
        let range = Range(firstMatch.range, in: string)!
102✔
80
        guard let index = Int(String(string[range])) else {
102✔
NEW
81
            throw CommonError.invalidRegex(regex: pattern, invalid: string)
×
82
        }
102✔
83
        self.index = index
102✔
84
        self.axis = try matches.map {
438✔
85
            let range = Range($0.range, in: string)!
438✔
86
            guard
438✔
87
                let index = Int(String(string[range]))
438✔
88
            else {
438✔
NEW
89
                throw CommonError.invalidRegex(regex: pattern, invalid: string)
×
90
            }
438✔
91
            return Axis.hardened(index)
438✔
92
        }
438✔
93
    }
102✔
94

95
    /// Returns a string representation of this `DerivationPath`.
96
    /// - Returns: A string in the format of "m/<index>'/0'/0'".
97
    public func keyPathString() -> String {
264✔
98
        return (["m"] + axis.map(\.string)).joined(separator: "/")
1,116✔
99
    }
264✔
100
}
101

102
/// `DerivableKey` is a protocol that defines functionality for keys that can be derived using a `DerivationPath`.
103
public protocol DerivableKey {
104
    func deriveKey(withPublicKey otherPublicKey: PublicKey, salt: Data?) throws -> Data
105
    func deriveKey(usingDerivationPath path: DerivationPath) throws -> Key
106
}
107

108
/// Extension to add derivable functionality to `Key`.
109
public extension Key {
110
    /// A Boolean value indicating whether the key is derivable.
111
    var isDerivable: Bool { self is DerivableKey }
×
112

113
    /// Returns the derivable representation of the key.
114
    var derivable: DerivableKey? { self as? DerivableKey }
×
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc