don't use default hash algorithms, let implementer decide

fixes #106
diff --git a/src/interchange/cjson.rs b/src/interchange/cjson.rs
index daff772..d06a31e 100644
--- a/src/interchange/cjson.rs
+++ b/src/interchange/cjson.rs
@@ -37,8 +37,7 @@
             &Value::String(ref s) => {
                 // this mess is abusing serde_json to get json escaping
                 let s = json::Value::String(s.clone());
-                let s = json::to_string(&s)
-                    .map_err(|e| format!("{:?}", e))?;
+                let s = json::to_string(&s).map_err(|e| format!("{:?}", e))?;
                 Ok(buf.extend(s.as_bytes()))
             }
             &Value::Array(ref arr) => {
@@ -61,11 +60,10 @@
                         buf.push(b',');
                     }
                     first = false;
-                    
+
                     // this mess is abusing serde_json to get json escaping
                     let k = json::Value::String(k.clone());
-                    let k = json::to_string(&k)
-                        .map_err(|e| format!("{:?}", e))?;
+                    let k = json::to_string(&k).map_err(|e| format!("{:?}", e))?;
                     buf.extend(k.as_bytes());
 
                     buf.push(b':');
diff --git a/src/metadata.rs b/src/metadata.rs
index 341ab85..e6662b6 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -927,29 +927,41 @@
     ///
     /// fn main() {
     ///     let bytes: &[u8] = b"it was a pleasure to burn";
-    ///     let target_description = TargetDescription::from_reader(bytes).unwrap();
     ///
     ///     // $ printf 'it was a pleasure to burn' | sha256sum
     ///     let s = "Rd9zlbzrdWfeL7gnIEi05X-Yv2TCpy4qqZM1N72ZWQs=";
     ///     let sha256 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
     ///
+    ///     let target_description =
+    ///         TargetDescription::from_reader(bytes, &[HashAlgorithm::Sha256]).unwrap();
+    ///     assert_eq!(target_description.length(), bytes.len() as u64);
+    ///     assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
+    ///
     ///     // $ printf 'it was a pleasure to burn' | sha512sum
     ///     let s ="tuIxwKybYdvJpWuUj6dubvpwhkAozWB6hMJIRzqn2jOUdtDTBg381brV4K\
     ///         BU1zKP8GShoJuXEtCf5NkDTCEJgQ==";
     ///     let sha512 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
     ///
+    ///     let target_description =
+    ///         TargetDescription::from_reader(bytes, &[HashAlgorithm::Sha512]).unwrap();
     ///     assert_eq!(target_description.length(), bytes.len() as u64);
-    ///     assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
     ///     assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha512), Some(&sha512));
     /// }
     /// ```
-    pub fn from_reader<R>(mut read: R) -> Result<Self>
+    pub fn from_reader<R>(mut read: R, hash_algs: &[HashAlgorithm]) -> Result<Self>
     where
         R: Read,
     {
         let mut length = 0;
-        let mut sha256 = digest::Context::new(&SHA256);
-        let mut sha512 = digest::Context::new(&SHA512);
+        let mut hashes = HashMap::new();
+        for alg in hash_algs {
+            let context = match alg {
+                &HashAlgorithm::Sha256 => digest::Context::new(&SHA256),
+                &HashAlgorithm::Sha512 => digest::Context::new(&SHA512),
+            };
+
+            let _ = hashes.insert(alg, context);
+        }
 
         let mut buf = vec![0; 1024];
         loop {
@@ -960,22 +972,22 @@
                     }
 
                     length += read_bytes as u64;
-                    sha256.update(&buf[0..read_bytes]);
-                    sha512.update(&buf[0..read_bytes]);
+
+                    for (_, mut context) in hashes.iter_mut() {
+                        context.update(&buf[0..read_bytes]);
+                    }
                 }
                 e @ Err(_) => e.map(|_| ())?,
             }
         }
 
-        let mut hashes = HashMap::new();
-        let _ = hashes.insert(
-            HashAlgorithm::Sha256,
-            HashValue::new(sha256.finish().as_ref().to_vec()),
-        );
-        let _ = hashes.insert(
-            HashAlgorithm::Sha512,
-            HashValue::new(sha512.finish().as_ref().to_vec()),
-        );
+        let hashes = hashes
+            .drain()
+            .map(|(k, v)| {
+                (k.clone(), HashValue::new(v.finish().as_ref().to_vec()))
+            })
+            .collect();
+
         Ok(TargetDescription {
             length: length,
             hashes: hashes,
@@ -1297,14 +1309,12 @@
     #[test]
     fn serde_target_description() {
         let s: &[u8] = b"from water does all life begin";
-        let description = TargetDescription::from_reader(s).unwrap();
+        let description = TargetDescription::from_reader(s, &[HashAlgorithm::Sha256]).unwrap();
         let jsn_str = json::to_string(&description).unwrap();
         let jsn = json!({
             "length": 30,
             "hashes": {
                 "sha256": "_F10XHEryG6poxJk2sDJVu61OFf2d-7QWCm7cQE8rhg=",
-                "sha512": "593J2T34bimKdKT5MmaSZ0tXvmj13EVdpTGK5p2E2R3ife-xxZ8Ql\
-                    EHsezz8HeN1_Y0SJqvLfK2WKUZQc98R_A==",
             },
         });
         let parsed_str: TargetDescription = json::from_str(&jsn_str).unwrap();
@@ -1496,7 +1506,7 @@
             Utc.ymd(2017, 1, 1).and_hms(0, 0, 0),
             hashmap! {
                 TargetPath::new("foo".into()).unwrap() =>
-                    TargetDescription::from_reader(b"foo" as &[u8]).unwrap(),
+                    TargetDescription::from_reader(b"foo" as &[u8], &[HashAlgorithm::Sha256]).unwrap(),
             },
             None,
         ).unwrap();
@@ -1510,8 +1520,6 @@
                     "length": 3,
                     "hashes": {
                         "sha256": "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564=",
-                        "sha512": "9_u6bgY2-JDlb7vzKD5STG-jIErimDgtYkdB0NxmODJuKCx\
-                            Bvl5CVNiCB3LFUYosWowMf37aGVlKfrU5RT4e1w==",
                     },
                 },
             },
diff --git a/src/repository.rs b/src/repository.rs
index a0c6866..6e5808f 100644
--- a/src/repository.rs
+++ b/src/repository.rs
@@ -307,7 +307,7 @@
     D: DataInterchange,
 {
     /// Create a new repository with the given `Url` and `Client`. Callers *should* include a
-    /// custom User-Agent prefix to maintainers of TUF repositories keep track of which client
+    /// custom User-Agent prefix to help maintainers of TUF repositories keep track of which client
     /// versions exist in the field.
     pub fn new(url: Url, client: Client, user_agent_prefix: Option<String>) -> Self {
         let user_agent = match user_agent_prefix {
@@ -536,8 +536,8 @@
         repo.initialize().expect("initialize repo");
 
         let data: &[u8] = b"like tears in the rain";
-        let target_description =
-            TargetDescription::from_reader(data).expect("generate target description");
+        let target_description = TargetDescription::from_reader(data, &[HashAlgorithm::Sha256])
+            .expect("generate target description");
         let path = TargetPath::new("batty".into()).expect("make target path");
         repo.store_target(data, &path, &target_description).expect(
             "store target",
@@ -568,8 +568,8 @@
         repo.initialize().expect("initialize repo");
 
         let data: &[u8] = b"like tears in the rain";
-        let target_description =
-            TargetDescription::from_reader(data).expect("generate target desert");
+        let target_description = TargetDescription::from_reader(data, &[HashAlgorithm::Sha256])
+            .expect("generate target desert");
         let path = TargetPath::new("batty".into()).expect("make target path");
         repo.store_target(data, &path, &target_description).expect(
             "store target",
diff --git a/tests/integration.rs b/tests/integration.rs
index 8c82754..1c57fa7 100644
--- a/tests/integration.rs
+++ b/tests/integration.rs
@@ -5,7 +5,7 @@
 use chrono::offset::Utc;
 use std::collections::{HashSet, HashMap};
 use tuf::Tuf;
-use tuf::crypto::{PrivateKey, SignatureScheme};
+use tuf::crypto::{PrivateKey, SignatureScheme, HashAlgorithm};
 use tuf::interchange::JsonDataInterchange;
 use tuf::metadata::{RoleDefinition, RootMetadata, MetadataPath, SignedMetadata, TargetDescription,
                     TargetPath, TargetsMetadata, MetadataDescription, SnapshotMetadata,
@@ -142,7 +142,8 @@
     //// build the delegation ////
     let target_file: &[u8] = b"bar";
     let target_path = TargetPath::new("foo".into()).unwrap();
-    let target_description = TargetDescription::from_reader(target_file).unwrap();
+    let target_description = TargetDescription::from_reader(target_file, &[HashAlgorithm::Sha256])
+        .unwrap();
 
     let mut target_map = HashMap::new();
     let _ = target_map.insert(target_path, target_description);
@@ -332,7 +333,8 @@
     //// build delegation B ////
     let target_file: &[u8] = b"bar";
     let target_path = TargetPath::new("foo".into()).unwrap();
-    let target_description = TargetDescription::from_reader(target_file).unwrap();
+    let target_description = TargetDescription::from_reader(target_file, &[HashAlgorithm::Sha256])
+        .unwrap();
 
     let mut target_map = HashMap::new();
     let _ = target_map.insert(target_path, target_description);
diff --git a/tests/simple_example.rs b/tests/simple_example.rs
index 6e63325..76f24ea 100644
--- a/tests/simple_example.rs
+++ b/tests/simple_example.rs
@@ -6,7 +6,7 @@
 use std::collections::{HashSet, HashMap};
 use tuf::{Tuf, Error};
 use tuf::client::{Client, Config};
-use tuf::crypto::{PrivateKey, SignatureScheme, KeyId};
+use tuf::crypto::{PrivateKey, SignatureScheme, KeyId, HashAlgorithm};
 use tuf::interchange::JsonDataInterchange;
 use tuf::metadata::{RoleDefinition, RootMetadata, Role, MetadataVersion, MetadataPath,
                     SignedMetadata, TargetDescription, TargetPath, TargetsMetadata,
@@ -117,7 +117,7 @@
 
     let target_file: &[u8] = b"things fade, alternatives exclude";
     let target_path = TargetPath::new("grendel".into())?;
-    let target_description = TargetDescription::from_reader(target_file)?;
+    let target_description = TargetDescription::from_reader(target_file, &[HashAlgorithm::Sha256])?;
     let _ = remote.store_target(target_file, &target_path, &target_description);
 
     let mut target_map = HashMap::new();