root verification
diff --git a/src/error.rs b/src/error.rs
index d11b616..09a40d4 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -21,6 +21,7 @@
     UnsupportedKeyFormat(String),
     UnsupportedKeyType(String),
     UnsupportedSignatureScheme(String),
+    VerificationFailure(String),
 }
 
 impl From<json::error::Error> for Error {
diff --git a/src/metadata/metadata.rs b/src/metadata/metadata.rs
index 031de51..a0d9d6d 100644
--- a/src/metadata/metadata.rs
+++ b/src/metadata/metadata.rs
@@ -180,14 +180,22 @@
 #[derive(Debug, Serialize, Deserialize)]
 pub struct Signature {
     key_id: KeyId,
-    method: SignatureScheme,
-    sig: SignatureValue,
+    scheme: SignatureScheme,
+    signature: SignatureValue,
 }
 
 impl Signature {
     pub fn key_id(&self) -> &KeyId {
         &self.key_id
     }
+
+    pub fn scheme(&self) -> &SignatureScheme {
+         &self.scheme    
+    }
+
+    pub fn signature(&self) -> &SignatureValue {
+        &self.signature
+    }
 }
 
 /// A `KeyId` is calculated as `sha256(public_key_bytes)`. The TUF spec says that it should be
diff --git a/src/tuf.rs b/src/tuf.rs
index b140000..425b432 100644
--- a/src/tuf.rs
+++ b/src/tuf.rs
@@ -8,6 +8,7 @@
 
 #[derive(Debug)]
 pub struct Tuf<D: DataInterchange, R: RawData<D>> {
+    root: RootMetadata,
     _raw_data: PhantomData<R>,
     _interchange: PhantomData<D>,
 }
@@ -20,19 +21,54 @@
         signed_root.signatures_mut().retain(|s| {
             root_key_ids.contains(s.key_id())
         });
-        let canonical_bytes = signed_root.signed().canonicalize()?;
-
-        let mut valid = 0;
-        for sig in signed_root.signatures() {
-             
-        }
-
-        let root = signed_root.signed().deserialize::<RootMetadata>()?;
-
-        panic!() // TODO
+        Self::from_root(signed_root)
     }
 
     pub fn from_root(signed_root: SignedMetadata<D, R, RootMetadata>) -> Result<Self, Error> {
-        panic!() // TODO
+        if signed_root.signatures().len() < 1 {
+            return Err(Error::VerificationFailure(
+                    "The root metadata was not signed with any authorized keys.".into()))
+        }
+
+        let canonical_bytes = signed_root.signed().canonicalize()?;
+        let root = signed_root.signed().deserialize::<RootMetadata>()?;
+
+        let mut signatures_needed = root.root().threshold();
+        if signatures_needed < 1 {
+            return Err(Error::VerificationFailure("Threshold must be strictly greater than zero".into()))
+        }
+
+        for sig in signed_root.signatures() {
+            if !root.root().key_ids().contains(sig.key_id()) {
+                warn!("Key ID {:?} is not authorized to sign root metadata.", sig.key_id());
+                continue
+            }
+
+            match root.keys().get(sig.key_id()) {
+                Some(ref pub_key) => {
+                    match pub_key.verify(sig.scheme(), &canonical_bytes, sig.signature()) {
+                        Ok(()) => {
+                            debug!("Good signature from key ID {:?}", pub_key.key_id());
+                            signatures_needed -= 1;    
+                        },
+                        Err(e) => {
+                            warn!("Bad signature from key ID {:?}", pub_key.key_id());   
+                        },
+                    }
+                },
+                None => {
+                    warn!("Key ID {:?} was not found in the set of available keys.", sig.key_id());
+                }
+            }
+            if signatures_needed == 0 {
+                break
+            }
+        }
+
+        Ok(Tuf {
+            root: root,
+            _raw_data: PhantomData,
+            _interchange: PhantomData,
+        })
     }
 }