{"action":"created","comment":{"url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/comments/27542634","id":27542634,"diff_hunk":"@@ -8,18 +8,144 @@\n \n import Foundation\n \n+\n+\n+\n+public enum KeyType {\n+  case PublicKey\n+  case PrivateKey\n+}\n+\n+public protocol ExtendedKeyVersionParameters: class {\n+  var addresses: (pub:UInt32, prv: UInt32) { get }\n+  func addressForKeyType(type:KeyType) -> UInt32\n+}\n+\n+\n /// An ExtendedECKey represents a key that is part of a DeterministicECKeyChain. It is just an\n /// ECKey except an additional chainCode parameter and an index are used to derive the key.\n /// Extended keys can be used to derive child keys.\n /// BIP 32: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n public class ExtendedECKey : ECKey {\n-\n+  \n   public let chainCode: SecureData\n   public let index: UInt32\n+  public let version: ExtendedKeyVersionParameters\n+  public let parent: ExtendedECKey?\n+  \n+  \n+  // This key's identifier (this corresponds exactly to a traditional bitcoin address)\n+  public var identifier:NSData {\n+    return publicKey.SHA256Hash().RIPEMD160Hash()\n+  }\n+  \n+  // Return this key's fingerprint\n+  public var fingerprint:NSData {\n+    return self.identifier.subdataWithRange(NSMakeRange(0, 4))\n+  }\n+  \n+  // Return the parent's fingerprint. 0x0000000 if master\n+  public var parentFingerprint:NSData {\n+    if let parent = parent {\n+      return parent.fingerprint\n+    }\n+    else {\n+      let masterprint: [UInt8] = [\n+        0x00, 0x00, 0x00, 0x00]\n+      return NSData(bytes: masterprint, length: masterprint.count)\n+    }\n+  }\n+  \n+  // Find the depth of this key\n+  public var depth:UInt8 {\n+    if let parent = parent {\n+      return parent.depth + 1\n+    }\n+    else {\n+      return 0\n+    }\n+  }\n+  \n+  // True if this key has no parent\n+  public var isMaster:Bool {\n+    return self.parent == nil\n+  }\n+  \n+  // Find the master key by traversing the parents until a parentless key is found.\n+  public var master:ExtendedECKey {\n+    if let parent = self.parent {\n+      return parent.master\n+    }\n+    else {\n+      return self\n+    }\n+  }\n+  \n+  // Return an array of path components from the master key.\n+  // Add apostrophe (') to hardened indexes, and use the letter (m) to represent the master - to make an absolute path.\n+  public var pathComponents:Array<String> {\n+    if let parent = self.parent {\n+      if let hIndex = self.hardenedIndex {\n+        return parent.pathComponents + [NSNumber(unsignedInt: hIndex).stringValue + \"'\"]\n+      }\n+      else {\n+        return parent.pathComponents + [NSNumber(unsignedInt: self.index).stringValue]\n+      }\n+    }\n+    else {\n+      return [\"m\"]\n+    }\n+  }\n+  \n+  // Combines the path components into a string path separated with slashes (\\)\n+  public var path:String {\n+    return \"\\\\\".join(self.pathComponents)\n+  }\n+  \n+  // Serialize the extended key data\n+  public func serializeExtendedKey(ofType type:KeyType = .PublicKey, version: ExtendedKeyVersionParameters = BitcoinMainNetParameters.get()) -> NSMutableData {\n+    \n+    func keyDataForType(type:KeyType) -> NSData {\n+      \n+      if type == .PublicKey {\n+        return self.publicKey\n+      }\n+      else {\n+        let keyData = NSMutableData()\n+        keyData.appendUInt8(0x00)\n+        keyData.appendData(self.privateKey.mutableData)\n+        \n+        return keyData\n+      }\n+    }\n+    \n+    let extKey = NSMutableData()\n+    \n+    extKey.appendUInt32(version.addressForKeyType(type), endianness: .BigEndian)    // address\n+    extKey.appendUInt8(self.depth)                                                  // depth\n+    extKey.appendData(self.parentFingerprint)                                       // parent fingerprint\n+    extKey.appendUInt32(self.index, endianness: .BigEndian)                         // child number\n+    extKey.appendData(self.chainCode.mutableData)                                   // chain code\n+    extKey.appendData(keyDataForType(type))                                         // public/private key\n+    \n+    return extKey\n+  }\n+  \n+  // Encode the extended key into a base64check string\n+  public func encodeExtendedKey(ofType type:KeyType = .PublicKey, version: ExtendedKeyVersionParameters = BitcoinMainNetParameters.get()) -> String {","path":"BitcoinSwift/ExtendedECKey.swift","position":129,"original_position":129,"commit_id":"836ff2da301406aa41e56e38959177bb603a5218","original_commit_id":"836ff2da301406aa41e56e38959177bb603a5218","user":{"login":"kgreenek","id":1295700,"avatar_url":"https://avatars.githubusercontent.com/u/1295700?v=3","gravatar_id":"","url":"https://api.github.com/users/kgreenek","html_url":"https://github.com/kgreenek","followers_url":"https://api.github.com/users/kgreenek/followers","following_url":"https://api.github.com/users/kgreenek/following{/other_user}","gists_url":"https://api.github.com/users/kgreenek/gists{/gist_id}","starred_url":"https://api.github.com/users/kgreenek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kgreenek/subscriptions","organizations_url":"https://api.github.com/users/kgreenek/orgs","repos_url":"https://api.github.com/users/kgreenek/repos","events_url":"https://api.github.com/users/kgreenek/events{/privacy}","received_events_url":"https://api.github.com/users/kgreenek/received_events","type":"User","site_admin":false},"body":"Sorry, I know this isn't documented anywhere, the the maximum line length is 100 chars. Please wrap when longer than that.","created_at":"2015-04-01T03:32:56Z","updated_at":"2015-04-01T03:32:56Z","html_url":"https://github.com/DoubleSha/BitcoinSwift/pull/10#discussion_r27542634","pull_request_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10","_links":{"self":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/comments/27542634"},"html":{"href":"https://github.com/DoubleSha/BitcoinSwift/pull/10#discussion_r27542634"},"pull_request":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10"}}},"pull_request":{"url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10","id":31738364,"html_url":"https://github.com/DoubleSha/BitcoinSwift/pull/10","diff_url":"https://github.com/DoubleSha/BitcoinSwift/pull/10.diff","patch_url":"https://github.com/DoubleSha/BitcoinSwift/pull/10.patch","issue_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/10","number":10,"state":"open","locked":false,"title":"Extended keys serialization and path generation / derivation","user":{"login":"A-Zak","id":302774,"avatar_url":"https://avatars.githubusercontent.com/u/302774?v=3","gravatar_id":"","url":"https://api.github.com/users/A-Zak","html_url":"https://github.com/A-Zak","followers_url":"https://api.github.com/users/A-Zak/followers","following_url":"https://api.github.com/users/A-Zak/following{/other_user}","gists_url":"https://api.github.com/users/A-Zak/gists{/gist_id}","starred_url":"https://api.github.com/users/A-Zak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/A-Zak/subscriptions","organizations_url":"https://api.github.com/users/A-Zak/orgs","repos_url":"https://api.github.com/users/A-Zak/repos","events_url":"https://api.github.com/users/A-Zak/events{/privacy}","received_events_url":"https://api.github.com/users/A-Zak/received_events","type":"User","site_admin":false},"body":"Hey Kevin,\r\n\r\nI've added the extended keys serialization and also methods to generate key paths and to derive child keys with a path. I've also added some tests - for the serialization I've tested according to the BIP32 test vectors, and for the path, I've just tried to cover all edge cases...\r\nI also tried to comply to your style :D\r\n\r\nCheers...","created_at":"2015-03-23T14:46:18Z","updated_at":"2015-04-01T03:32:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"12ad41ee76dede1a01b1409c23b8c600b22afc9f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10/commits","review_comments_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10/comments","review_comment_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/10/comments","statuses_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/statuses/836ff2da301406aa41e56e38959177bb603a5218","head":{"label":"A-Zak:feature/extended-keys-and-path-deriviation","ref":"feature/extended-keys-and-path-deriviation","sha":"836ff2da301406aa41e56e38959177bb603a5218","user":{"login":"A-Zak","id":302774,"avatar_url":"https://avatars.githubusercontent.com/u/302774?v=3","gravatar_id":"","url":"https://api.github.com/users/A-Zak","html_url":"https://github.com/A-Zak","followers_url":"https://api.github.com/users/A-Zak/followers","following_url":"https://api.github.com/users/A-Zak/following{/other_user}","gists_url":"https://api.github.com/users/A-Zak/gists{/gist_id}","starred_url":"https://api.github.com/users/A-Zak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/A-Zak/subscriptions","organizations_url":"https://api.github.com/users/A-Zak/orgs","repos_url":"https://api.github.com/users/A-Zak/repos","events_url":"https://api.github.com/users/A-Zak/events{/privacy}","received_events_url":"https://api.github.com/users/A-Zak/received_events","type":"User","site_admin":false},"repo":{"id":32527407,"name":"BitcoinSwift","full_name":"A-Zak/BitcoinSwift","owner":{"login":"A-Zak","id":302774,"avatar_url":"https://avatars.githubusercontent.com/u/302774?v=3","gravatar_id":"","url":"https://api.github.com/users/A-Zak","html_url":"https://github.com/A-Zak","followers_url":"https://api.github.com/users/A-Zak/followers","following_url":"https://api.github.com/users/A-Zak/following{/other_user}","gists_url":"https://api.github.com/users/A-Zak/gists{/gist_id}","starred_url":"https://api.github.com/users/A-Zak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/A-Zak/subscriptions","organizations_url":"https://api.github.com/users/A-Zak/orgs","repos_url":"https://api.github.com/users/A-Zak/repos","events_url":"https://api.github.com/users/A-Zak/events{/privacy}","received_events_url":"https://api.github.com/users/A-Zak/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/A-Zak/BitcoinSwift","description":"A native framework for working with Bitcoin on iOS and OSX","fork":true,"url":"https://api.github.com/repos/A-Zak/BitcoinSwift","forks_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/forks","keys_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/keys{/key_id}","collaborators_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/teams","hooks_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/hooks","issue_events_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/issues/events{/number}","events_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/events","assignees_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/assignees{/user}","branches_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/branches{/branch}","tags_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/tags","blobs_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/git/refs{/sha}","trees_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/git/trees{/sha}","statuses_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/statuses/{sha}","languages_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/languages","stargazers_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/stargazers","contributors_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/contributors","subscribers_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/subscribers","subscription_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/subscription","commits_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/commits{/sha}","git_commits_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/git/commits{/sha}","comments_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/comments{/number}","issue_comment_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/issues/comments{/number}","contents_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/contents/{+path}","compare_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/compare/{base}...{head}","merges_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/merges","archive_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/downloads","issues_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/issues{/number}","pulls_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/pulls{/number}","milestones_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/milestones{/number}","notifications_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/labels{/name}","releases_url":"https://api.github.com/repos/A-Zak/BitcoinSwift/releases{/id}","created_at":"2015-03-19T14:47:56Z","updated_at":"2015-03-19T14:47:57Z","pushed_at":"2015-03-24T13:16:10Z","git_url":"git://github.com/A-Zak/BitcoinSwift.git","ssh_url":"git@github.com:A-Zak/BitcoinSwift.git","clone_url":"https://github.com/A-Zak/BitcoinSwift.git","svn_url":"https://github.com/A-Zak/BitcoinSwift","homepage":"","size":6798,"stargazers_count":0,"watchers_count":0,"language":"Swift","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"DoubleSha:master","ref":"master","sha":"1ee2a7bc50e1b91f68bcae25edfecc920cb8915c","user":{"login":"DoubleSha","id":7895523,"avatar_url":"https://avatars.githubusercontent.com/u/7895523?v=3","gravatar_id":"","url":"https://api.github.com/users/DoubleSha","html_url":"https://github.com/DoubleSha","followers_url":"https://api.github.com/users/DoubleSha/followers","following_url":"https://api.github.com/users/DoubleSha/following{/other_user}","gists_url":"https://api.github.com/users/DoubleSha/gists{/gist_id}","starred_url":"https://api.github.com/users/DoubleSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DoubleSha/subscriptions","organizations_url":"https://api.github.com/users/DoubleSha/orgs","repos_url":"https://api.github.com/users/DoubleSha/repos","events_url":"https://api.github.com/users/DoubleSha/events{/privacy}","received_events_url":"https://api.github.com/users/DoubleSha/received_events","type":"Organization","site_admin":false},"repo":{"id":21020073,"name":"BitcoinSwift","full_name":"DoubleSha/BitcoinSwift","owner":{"login":"DoubleSha","id":7895523,"avatar_url":"https://avatars.githubusercontent.com/u/7895523?v=3","gravatar_id":"","url":"https://api.github.com/users/DoubleSha","html_url":"https://github.com/DoubleSha","followers_url":"https://api.github.com/users/DoubleSha/followers","following_url":"https://api.github.com/users/DoubleSha/following{/other_user}","gists_url":"https://api.github.com/users/DoubleSha/gists{/gist_id}","starred_url":"https://api.github.com/users/DoubleSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DoubleSha/subscriptions","organizations_url":"https://api.github.com/users/DoubleSha/orgs","repos_url":"https://api.github.com/users/DoubleSha/repos","events_url":"https://api.github.com/users/DoubleSha/events{/privacy}","received_events_url":"https://api.github.com/users/DoubleSha/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DoubleSha/BitcoinSwift","description":"A native framework for working with Bitcoin on iOS and OSX","fork":false,"url":"https://api.github.com/repos/DoubleSha/BitcoinSwift","forks_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/forks","keys_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/teams","hooks_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/hooks","issue_events_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/events{/number}","events_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/events","assignees_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/assignees{/user}","branches_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/branches{/branch}","tags_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/tags","blobs_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/git/refs{/sha}","trees_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/statuses/{sha}","languages_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/languages","stargazers_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/stargazers","contributors_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/contributors","subscribers_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/subscribers","subscription_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/subscription","commits_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/commits{/sha}","git_commits_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/git/commits{/sha}","comments_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/comments{/number}","issue_comment_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/comments{/number}","contents_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/contents/{+path}","compare_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/merges","archive_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/downloads","issues_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues{/number}","pulls_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls{/number}","milestones_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/milestones{/number}","notifications_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/labels{/name}","releases_url":"https://api.github.com/repos/DoubleSha/BitcoinSwift/releases{/id}","created_at":"2014-06-20T00:27:23Z","updated_at":"2015-03-21T03:13:40Z","pushed_at":"2015-03-24T13:16:11Z","git_url":"git://github.com/DoubleSha/BitcoinSwift.git","ssh_url":"git@github.com:DoubleSha/BitcoinSwift.git","clone_url":"https://github.com/DoubleSha/BitcoinSwift.git","svn_url":"https://github.com/DoubleSha/BitcoinSwift","homepage":"","size":7572,"stargazers_count":41,"watchers_count":41,"language":"Swift","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":1,"forks":9,"open_issues":1,"watchers":41,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10"},"html":{"href":"https://github.com/DoubleSha/BitcoinSwift/pull/10"},"issue":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/10"},"comments":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/issues/10/comments"},"review_comments":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10/comments"},"review_comment":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/pulls/10/commits"},"statuses":{"href":"https://api.github.com/repos/DoubleSha/BitcoinSwift/statuses/836ff2da301406aa41e56e38959177bb603a5218"}}}}