{"action":"created","comment":{"url":"https://api.github.com/repos/briansmith/ring/pulls/comments/225043910","pull_request_review_id":164554554,"id":225043910,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyNTA0MzkxMA==","diff_hunk":"@@ -0,0 +1,224 @@\n+// Copyright 2018 Brian Smith.\n+//\n+// Permission to use, copy, modify, and/or distribute this software for any\n+// purpose with or without fee is hereby granted, provided that the above\n+// copyright notice and this permission notice appear in all copies.\n+//\n+// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHORS DISCLAIM ALL WARRANTIES\n+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY\n+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\n+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n+\n+//! Unauthenticated stream cipher.\n+//!\n+//! # Warning\n+//! This API does not provide any authentification! You should use the\n+//! [aead](aead/index.html) module instead.\n+//!\n+//! C analog: `EVP_CIPHER`\n+//!\n+//! Go analog: [`crypto.cipher.Stream`]\n+//!\n+//! [`crypto.cipher.Stream`]: https://golang.org/pkg/crypto/cipher/#Stream\n+\n+use {chacha, error, init, polyfill};\n+\n+pub use self::chacha20::CHACHA20;\n+\n+/// A key for decrypting data encrypted using an unauthenticated stream cipher.\n+///\n+/// C analog: `EVP_CIPHER_CTX`\n+///\n+/// Go analog: [`crypto.cipher.Stream`]\n+pub struct DecryptingKey {\n+    key: Key,\n+}\n+\n+impl DecryptingKey {\n+    /// Create a new decrypting key.\n+    ///\n+    /// `key_bytes` must be exactly `algorithm.key_len` bytes long.\n+    ///\n+    /// C analogs: `EVP_CIPHER_CTX_init`.\n+    ///\n+    /// Go analog:\n+    ///   [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)\n+    #[inline]\n+    pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8])\n+               -> Result<DecryptingKey, error::Unspecified> {\n+        Ok(DecryptingKey {\n+            key: Key::new(algorithm, key_bytes)?,\n+        })\n+    }\n+\n+    /// The key's unauthenticated stream cipher algorithm.\n+    ///\n+    /// C analog: `EVP_CIPHER_CTX.cipher`\n+    #[inline(always)]\n+    pub fn algorithm(&self) -> &'static Algorithm { self.key.algorithm() }\n+}\n+\n+/// Decrypts the input data in place.\n+pub fn decrypt_in_place<'a>(key: &DecryptingKey, nonce: &[u8],\n+                            in_out: &'a mut [u8])\n+                            -> Result<&'a mut [u8], error::Unspecified> {\n+    let nonce = slice_as_array_ref!(nonce, NONCE_LEN)?;\n+    check_per_nonce_max_bytes(key.key.algorithm, in_out.len())?;\n+    (key.key.algorithm.xor_keystream)(&key.key.ctx_buf, nonce, in_out)?;\n+    Ok(&mut in_out[..])\n+}\n+\n+/// A key for encrypting data using an unauthenticated stream cipher.\n+///\n+/// C analog: `EVP_CIPHER_CTX`\n+///\n+/// Go analog: [`crypto.cipher.Stream`]\n+pub struct EncryptingKey {\n+    key: Key,\n+}\n+\n+impl EncryptingKey {\n+    /// Create a new encrypting key.\n+    ///\n+    /// `key_bytes` must be exactly `algorithm.key_len` bytes long.\n+    ///\n+    /// C analogs: `EVP_CIPHER_CTX_init`.\n+    ///\n+    /// Go analog:\n+    ///   [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)\n+    #[inline]\n+    pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8])\n+               -> Result<EncryptingKey, error::Unspecified> {\n+        Ok(EncryptingKey {\n+            key: Key::new(algorithm, key_bytes)?,\n+        })\n+    }\n+\n+    /// The key's unauthenticated stream cipher algorithm.\n+    ///\n+    /// C analog: `EVP_CIPHER_CTX.cipher`\n+    #[inline(always)]\n+    pub fn algorithm(&self) -> &'static Algorithm { self.key.algorithm() }\n+}\n+\n+/// Encrypts the input data in place.\n+pub fn encrypt_in_place(key: &EncryptingKey, nonce: &[u8], in_out: &mut [u8])\n+                        -> Result<usize, error::Unspecified> {\n+    let nonce = slice_as_array_ref!(nonce, NONCE_LEN)?;\n+    check_per_nonce_max_bytes(key.key.algorithm, in_out.len())?;\n+    (key.key.algorithm.xor_keystream)(&key.key.ctx_buf, nonce, in_out)?;\n+    Ok(in_out.len())\n+}\n+\n+/// `DecryptingKey` and `EncryptingKey` are type-safety wrappers around `Key`,\n+/// which does all the actual work via the C stream cipher interface.\n+///\n+/// C analog: `EVP_CIPHER_CTX`\n+struct Key {\n+    ctx_buf: [u64; KEY_CTX_BUF_ELEMS],\n+    algorithm: &'static Algorithm,\n+}\n+\n+const KEY_CTX_BUF_ELEMS: usize = (KEY_CTX_BUF_LEN + 7) / 8;\n+\n+const KEY_CTX_BUF_LEN: usize = chacha::KEY_LEN_IN_BYTES;\n+\n+impl Key {\n+    fn new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self, error::Unspecified> {\n+        if key_bytes.len() != algorithm.key_len() {\n+            return Err(error::Unspecified);\n+        }\n+\n+        let mut r = Key {\n+            algorithm,\n+            ctx_buf: [0; KEY_CTX_BUF_ELEMS],\n+        };\n+\n+        init::init_once();\n+        {\n+            let ctx_buf_bytes = polyfill::slice::u64_as_u8_mut(&mut r.ctx_buf);\n+            (r.algorithm.init)(ctx_buf_bytes, key_bytes)?;\n+        }\n+\n+        Ok(r)\n+    }\n+\n+    /// The key's unauthenticated stream cipher algorithm.\n+    #[inline(always)]\n+    fn algorithm(&self) -> &'static Algorithm { self.algorithm }\n+}\n+\n+/// An unauthenticated stream cipher Algorithm.\n+///\n+/// C analog: `EVP_CIPHER`\n+///\n+/// Go analog:\n+///     [`crypto.cipher.Stream`](https://golang.org/pkg/crypto/cipher/#Stream)\n+pub struct Algorithm {\n+    init: fn(ctx_buf: &mut [u8], key: &[u8]) -> Result<(), error::Unspecified>,\n+\n+    xor_keystream: fn(ctx: &[u64; KEY_CTX_BUF_ELEMS], nonce: &[u8; NONCE_LEN],\n+                      in_out: &mut [u8]) -> Result<(), error::Unspecified>,\n+\n+    key_len: usize,\n+    id: AlgorithmID,\n+\n+    /// Use `max_input_len!()` to initialize this.\n+    // TODO: Make this `usize`.\n+    max_input_len: u64,\n+}\n+\n+/// TODO: Make this a `const fn` when those become stable.\n+macro_rules! max_input_len {\n+    ($block_len:expr, $overhead_blocks_per_nonce:expr) => {\n+        // Each of our AEADs use a 32-bit block counter so the maximum is the\n+        // largest input that will not overflow the counter.\n+        (((1u64 << 32) - $overhead_blocks_per_nonce) * $block_len)\n+    }\n+}\n+\n+impl Algorithm {\n+    /// The length of the key.\n+    ///\n+    /// C analog: `EVP_CIPHER_key_length`\n+    #[inline(always)]\n+    pub fn key_len(&self) -> usize { self.key_len }\n+\n+    /// The length of the nonces.\n+    ///\n+    /// C analog: `EVP_CIPHER_nonce_length`\n+    ///\n+    /// Go analog:\n+    /// [`crypto.cipher.Stream.NonceSize`](https://golang.org/pkg/crypto/cipher/#Stream)\n+    #[inline(always)]\n+    pub fn nonce_len(&self) -> usize { NONCE_LEN }\n+}\n+\n+derive_debug_from_field!(Algorithm, id);\n+\n+#[derive(Debug, Eq, PartialEq)]\n+enum AlgorithmID {\n+    CHACHA20,\n+}\n+\n+impl PartialEq for Algorithm {\n+    fn eq(&self, other: &Self) -> bool { self.id == other.id }\n+}\n+\n+impl Eq for Algorithm {}\n+\n+// All the stream ciphers we support use 128-bit nonces.\n+const NONCE_LEN: usize = 128 / 8;\n+\n+fn check_per_nonce_max_bytes(alg: &Algorithm, in_out_len: usize)","path":"src/unauthenticated_stream/mod.rs","position":216,"original_position":216,"commit_id":"a0992fe25bff005315957fad76bd40e0de567420","original_commit_id":"a0992fe25bff005315957fad76bd40e0de567420","user":{"login":"briansmith","id":16816,"node_id":"MDQ6VXNlcjE2ODE2","avatar_url":"https://avatars0.githubusercontent.com/u/16816?v=4","gravatar_id":"","url":"https://api.github.com/users/briansmith","html_url":"https://github.com/briansmith","followers_url":"https://api.github.com/users/briansmith/followers","following_url":"https://api.github.com/users/briansmith/following{/other_user}","gists_url":"https://api.github.com/users/briansmith/gists{/gist_id}","starred_url":"https://api.github.com/users/briansmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briansmith/subscriptions","organizations_url":"https://api.github.com/users/briansmith/orgs","repos_url":"https://api.github.com/users/briansmith/repos","events_url":"https://api.github.com/users/briansmith/events{/privacy}","received_events_url":"https://api.github.com/users/briansmith/received_events","type":"User","site_admin":false},"body":"Ditto.","created_at":"2018-10-15T05:51:01Z","updated_at":"2018-10-15T05:55:21Z","html_url":"https://github.com/briansmith/ring/pull/695#discussion_r225043910","pull_request_url":"https://api.github.com/repos/briansmith/ring/pulls/695","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/briansmith/ring/pulls/comments/225043910"},"html":{"href":"https://github.com/briansmith/ring/pull/695#discussion_r225043910"},"pull_request":{"href":"https://api.github.com/repos/briansmith/ring/pulls/695"}}},"pull_request":{"url":"https://api.github.com/repos/briansmith/ring/pulls/695","id":220848646,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIwODQ4NjQ2","html_url":"https://github.com/briansmith/ring/pull/695","diff_url":"https://github.com/briansmith/ring/pull/695.diff","patch_url":"https://github.com/briansmith/ring/pull/695.patch","issue_url":"https://api.github.com/repos/briansmith/ring/issues/695","number":695,"state":"open","locked":false,"title":"Expose unauthenticated stream cipher API","user":{"login":"ghedo","id":117643,"node_id":"MDQ6VXNlcjExNzY0Mw==","avatar_url":"https://avatars3.githubusercontent.com/u/117643?v=4","gravatar_id":"","url":"https://api.github.com/users/ghedo","html_url":"https://github.com/ghedo","followers_url":"https://api.github.com/users/ghedo/followers","following_url":"https://api.github.com/users/ghedo/following{/other_user}","gists_url":"https://api.github.com/users/ghedo/gists{/gist_id}","starred_url":"https://api.github.com/users/ghedo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghedo/subscriptions","organizations_url":"https://api.github.com/users/ghedo/orgs","repos_url":"https://api.github.com/users/ghedo/repos","events_url":"https://api.github.com/users/ghedo/events{/privacy}","received_events_url":"https://api.github.com/users/ghedo/received_events","type":"User","site_admin":false},"body":"This adds a new \"unauthenticated_stream\" module, to expose a plain stream\r\ncipher API, which mostly follows the aead module, but instead of providing\r\n\"open\" and \"seal\" operations, it just provides a \"xor_keystream\" operation\r\nand uses 128 bits nonces instead of 96 bits.\r\n\r\nThe 128 bits nonce are necessary to match the usage of the stream ciphers\r\nfor the QUIC protocol packet number protection scheme, where 16 octets are\r\nsampled from the packet payload and used as explicit nonce for AES-CTR\r\nand ChaCha20.\r\n\r\nThis also implements support for the ChaCha20 cipher, exposed through the\r\nnew API described above, by reusing the existing ChaCha20 C interface. The\r\nfirst 32 bits of the 128 bits nonce are extracted and used as an explicit\r\ninitial counter.\r\n\r\nThe ChaCha20 test vectors were copied from the AEAD ChaCha20-Poly1305 ones,\r\nwith the nonces modified to add an explicit little-endian counter of \"1\", and\r\nwith AD and TAG parameters removed.\r\n\r\nI agree to license my contributions to each file under the terms given\r\nat the top of each file I changed.","created_at":"2018-10-05T23:37:48Z","updated_at":"2018-10-15T05:55:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"21d78bf8fc45a2318d97e507f3a20e0896caff7b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/briansmith/ring/pulls/695/commits","review_comments_url":"https://api.github.com/repos/briansmith/ring/pulls/695/comments","review_comment_url":"https://api.github.com/repos/briansmith/ring/pulls/comments{/number}","comments_url":"https://api.github.com/repos/briansmith/ring/issues/695/comments","statuses_url":"https://api.github.com/repos/briansmith/ring/statuses/a0992fe25bff005315957fad76bd40e0de567420","head":{"label":"ghedo:unauthenticated_stream","ref":"unauthenticated_stream","sha":"a0992fe25bff005315957fad76bd40e0de567420","user":{"login":"ghedo","id":117643,"node_id":"MDQ6VXNlcjExNzY0Mw==","avatar_url":"https://avatars3.githubusercontent.com/u/117643?v=4","gravatar_id":"","url":"https://api.github.com/users/ghedo","html_url":"https://github.com/ghedo","followers_url":"https://api.github.com/users/ghedo/followers","following_url":"https://api.github.com/users/ghedo/following{/other_user}","gists_url":"https://api.github.com/users/ghedo/gists{/gist_id}","starred_url":"https://api.github.com/users/ghedo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghedo/subscriptions","organizations_url":"https://api.github.com/users/ghedo/orgs","repos_url":"https://api.github.com/users/ghedo/repos","events_url":"https://api.github.com/users/ghedo/events{/privacy}","received_events_url":"https://api.github.com/users/ghedo/received_events","type":"User","site_admin":false},"repo":{"id":151788660,"node_id":"MDEwOlJlcG9zaXRvcnkxNTE3ODg2NjA=","name":"ring","full_name":"ghedo/ring","private":false,"owner":{"login":"ghedo","id":117643,"node_id":"MDQ6VXNlcjExNzY0Mw==","avatar_url":"https://avatars3.githubusercontent.com/u/117643?v=4","gravatar_id":"","url":"https://api.github.com/users/ghedo","html_url":"https://github.com/ghedo","followers_url":"https://api.github.com/users/ghedo/followers","following_url":"https://api.github.com/users/ghedo/following{/other_user}","gists_url":"https://api.github.com/users/ghedo/gists{/gist_id}","starred_url":"https://api.github.com/users/ghedo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghedo/subscriptions","organizations_url":"https://api.github.com/users/ghedo/orgs","repos_url":"https://api.github.com/users/ghedo/repos","events_url":"https://api.github.com/users/ghedo/events{/privacy}","received_events_url":"https://api.github.com/users/ghedo/received_events","type":"User","site_admin":false},"html_url":"https://github.com/ghedo/ring","description":"Safe, fast, small crypto using Rust","fork":true,"url":"https://api.github.com/repos/ghedo/ring","forks_url":"https://api.github.com/repos/ghedo/ring/forks","keys_url":"https://api.github.com/repos/ghedo/ring/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ghedo/ring/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ghedo/ring/teams","hooks_url":"https://api.github.com/repos/ghedo/ring/hooks","issue_events_url":"https://api.github.com/repos/ghedo/ring/issues/events{/number}","events_url":"https://api.github.com/repos/ghedo/ring/events","assignees_url":"https://api.github.com/repos/ghedo/ring/assignees{/user}","branches_url":"https://api.github.com/repos/ghedo/ring/branches{/branch}","tags_url":"https://api.github.com/repos/ghedo/ring/tags","blobs_url":"https://api.github.com/repos/ghedo/ring/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ghedo/ring/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ghedo/ring/git/refs{/sha}","trees_url":"https://api.github.com/repos/ghedo/ring/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ghedo/ring/statuses/{sha}","languages_url":"https://api.github.com/repos/ghedo/ring/languages","stargazers_url":"https://api.github.com/repos/ghedo/ring/stargazers","contributors_url":"https://api.github.com/repos/ghedo/ring/contributors","subscribers_url":"https://api.github.com/repos/ghedo/ring/subscribers","subscription_url":"https://api.github.com/repos/ghedo/ring/subscription","commits_url":"https://api.github.com/repos/ghedo/ring/commits{/sha}","git_commits_url":"https://api.github.com/repos/ghedo/ring/git/commits{/sha}","comments_url":"https://api.github.com/repos/ghedo/ring/comments{/number}","issue_comment_url":"https://api.github.com/repos/ghedo/ring/issues/comments{/number}","contents_url":"https://api.github.com/repos/ghedo/ring/contents/{+path}","compare_url":"https://api.github.com/repos/ghedo/ring/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ghedo/ring/merges","archive_url":"https://api.github.com/repos/ghedo/ring/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ghedo/ring/downloads","issues_url":"https://api.github.com/repos/ghedo/ring/issues{/number}","pulls_url":"https://api.github.com/repos/ghedo/ring/pulls{/number}","milestones_url":"https://api.github.com/repos/ghedo/ring/milestones{/number}","notifications_url":"https://api.github.com/repos/ghedo/ring/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ghedo/ring/labels{/name}","releases_url":"https://api.github.com/repos/ghedo/ring/releases{/id}","deployments_url":"https://api.github.com/repos/ghedo/ring/deployments","created_at":"2018-10-05T23:37:06Z","updated_at":"2018-10-05T23:37:10Z","pushed_at":"2018-10-11T21:45:08Z","git_url":"git://github.com/ghedo/ring.git","ssh_url":"git@github.com:ghedo/ring.git","clone_url":"https://github.com/ghedo/ring.git","svn_url":"https://github.com/ghedo/ring","homepage":"https://briansmith.org/rustdoc/ring/","size":50434,"stargazers_count":0,"watchers_count":0,"language":"Assembly","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"briansmith:master","ref":"master","sha":"7e3682c02170f5eafa423b63bacfa018de2878a9","user":{"login":"briansmith","id":16816,"node_id":"MDQ6VXNlcjE2ODE2","avatar_url":"https://avatars0.githubusercontent.com/u/16816?v=4","gravatar_id":"","url":"https://api.github.com/users/briansmith","html_url":"https://github.com/briansmith","followers_url":"https://api.github.com/users/briansmith/followers","following_url":"https://api.github.com/users/briansmith/following{/other_user}","gists_url":"https://api.github.com/users/briansmith/gists{/gist_id}","starred_url":"https://api.github.com/users/briansmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briansmith/subscriptions","organizations_url":"https://api.github.com/users/briansmith/orgs","repos_url":"https://api.github.com/users/briansmith/repos","events_url":"https://api.github.com/users/briansmith/events{/privacy}","received_events_url":"https://api.github.com/users/briansmith/received_events","type":"User","site_admin":false},"repo":{"id":39527318,"node_id":"MDEwOlJlcG9zaXRvcnkzOTUyNzMxOA==","name":"ring","full_name":"briansmith/ring","private":false,"owner":{"login":"briansmith","id":16816,"node_id":"MDQ6VXNlcjE2ODE2","avatar_url":"https://avatars0.githubusercontent.com/u/16816?v=4","gravatar_id":"","url":"https://api.github.com/users/briansmith","html_url":"https://github.com/briansmith","followers_url":"https://api.github.com/users/briansmith/followers","following_url":"https://api.github.com/users/briansmith/following{/other_user}","gists_url":"https://api.github.com/users/briansmith/gists{/gist_id}","starred_url":"https://api.github.com/users/briansmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briansmith/subscriptions","organizations_url":"https://api.github.com/users/briansmith/orgs","repos_url":"https://api.github.com/users/briansmith/repos","events_url":"https://api.github.com/users/briansmith/events{/privacy}","received_events_url":"https://api.github.com/users/briansmith/received_events","type":"User","site_admin":false},"html_url":"https://github.com/briansmith/ring","description":"Safe, fast, small crypto using Rust","fork":false,"url":"https://api.github.com/repos/briansmith/ring","forks_url":"https://api.github.com/repos/briansmith/ring/forks","keys_url":"https://api.github.com/repos/briansmith/ring/keys{/key_id}","collaborators_url":"https://api.github.com/repos/briansmith/ring/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/briansmith/ring/teams","hooks_url":"https://api.github.com/repos/briansmith/ring/hooks","issue_events_url":"https://api.github.com/repos/briansmith/ring/issues/events{/number}","events_url":"https://api.github.com/repos/briansmith/ring/events","assignees_url":"https://api.github.com/repos/briansmith/ring/assignees{/user}","branches_url":"https://api.github.com/repos/briansmith/ring/branches{/branch}","tags_url":"https://api.github.com/repos/briansmith/ring/tags","blobs_url":"https://api.github.com/repos/briansmith/ring/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/briansmith/ring/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/briansmith/ring/git/refs{/sha}","trees_url":"https://api.github.com/repos/briansmith/ring/git/trees{/sha}","statuses_url":"https://api.github.com/repos/briansmith/ring/statuses/{sha}","languages_url":"https://api.github.com/repos/briansmith/ring/languages","stargazers_url":"https://api.github.com/repos/briansmith/ring/stargazers","contributors_url":"https://api.github.com/repos/briansmith/ring/contributors","subscribers_url":"https://api.github.com/repos/briansmith/ring/subscribers","subscription_url":"https://api.github.com/repos/briansmith/ring/subscription","commits_url":"https://api.github.com/repos/briansmith/ring/commits{/sha}","git_commits_url":"https://api.github.com/repos/briansmith/ring/git/commits{/sha}","comments_url":"https://api.github.com/repos/briansmith/ring/comments{/number}","issue_comment_url":"https://api.github.com/repos/briansmith/ring/issues/comments{/number}","contents_url":"https://api.github.com/repos/briansmith/ring/contents/{+path}","compare_url":"https://api.github.com/repos/briansmith/ring/compare/{base}...{head}","merges_url":"https://api.github.com/repos/briansmith/ring/merges","archive_url":"https://api.github.com/repos/briansmith/ring/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/briansmith/ring/downloads","issues_url":"https://api.github.com/repos/briansmith/ring/issues{/number}","pulls_url":"https://api.github.com/repos/briansmith/ring/pulls{/number}","milestones_url":"https://api.github.com/repos/briansmith/ring/milestones{/number}","notifications_url":"https://api.github.com/repos/briansmith/ring/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/briansmith/ring/labels{/name}","releases_url":"https://api.github.com/repos/briansmith/ring/releases{/id}","deployments_url":"https://api.github.com/repos/briansmith/ring/deployments","created_at":"2015-07-22T19:57:40Z","updated_at":"2018-10-14T23:51:50Z","pushed_at":"2018-10-13T00:56:43Z","git_url":"git://github.com/briansmith/ring.git","ssh_url":"git@github.com:briansmith/ring.git","clone_url":"https://github.com/briansmith/ring.git","svn_url":"https://github.com/briansmith/ring","homepage":"https://briansmith.org/rustdoc/ring/","size":50452,"stargazers_count":989,"watchers_count":989,"language":"Assembly","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":194,"mirror_url":null,"archived":false,"open_issues_count":229,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":194,"open_issues":229,"watchers":989,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/briansmith/ring/pulls/695"},"html":{"href":"https://github.com/briansmith/ring/pull/695"},"issue":{"href":"https://api.github.com/repos/briansmith/ring/issues/695"},"comments":{"href":"https://api.github.com/repos/briansmith/ring/issues/695/comments"},"review_comments":{"href":"https://api.github.com/repos/briansmith/ring/pulls/695/comments"},"review_comment":{"href":"https://api.github.com/repos/briansmith/ring/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/briansmith/ring/pulls/695/commits"},"statuses":{"href":"https://api.github.com/repos/briansmith/ring/statuses/a0992fe25bff005315957fad76bd40e0de567420"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"briansmith"}}