             [clojure.string :as string])
   (:import
     (java.security Security)
-    (org.bouncycastle.jce.provider BouncyCastleProvider)
-    (org.bouncycastle.openpgp PGPUtil
-                              PGPPublicKey
-                              PGPPublicKeyRingCollection
-                              PGPSecretKey
-                              PGPSecretKeyRingCollection
-                              PGPSignature
-                              PGPSignatureGenerator
-                              )))
+    (org.bouncycastle.jce.provider
+      BouncyCastleProvider)
+    (org.bouncycastle.openpgp
+      PGPObjectFactory
+      PGPPublicKey
+      PGPPublicKeyRingCollection
+      PGPSecretKey
+      PGPSecretKeyRingCollection
+      PGPSignature
+      PGPSignatureGenerator
+      PGPSignatureList
+      PGPUtil)
+    (org.bouncycastle.openpgp.operator.bc
+      BcPGPContentSignerBuilder
+      BcPGPContentVerifierBuilderProvider
+      BcPGPDigestCalculatorProvider
+      BcPBESecretKeyDecryptorBuilder)))
 
 
-; Install the BouncyCastle security provider.
+; Install the BouncyCastle security provider. TODO: is this necessary?
 (Security/addProvider (new BouncyCastleProvider))
 
 

        (.getSecretKey (key-id id)))))


(defn- generate-signature
  [data-source
   hash-algorithm-code
   key-algorithm-code
   private-key]
  (let [generator (PGPSignatureGenerator.
                    key-algorithm-code
                    hash-algorithm-code
                    security-provider)]
    (.init generator PGPSignature/BINARY_DOCUMENT private-key)
    (with-open [data (io/input-stream data-source)]
      (let [buffer (byte-array 256)]
        (loop [n (.read data buffer)]
          (when (> n 0)
            (.update generator buffer 0 n)


(defn sign
  [data-source secret-key passphrase]
  (generate-signature
    data-source
    (hash-algorithms *hash-algorithm*)
    (key-algorithm-code secret-key)
    (extract-private-key secret-key passphrase)))


(defn encode-signature
  [sig]
  (.getEncoded sig))


(defn decode-signature
  [data]
  (with-open [data-stream (PGPUtil/getDecoderStream
                            (io/input-stream data))]
    (let [sig-list (.nextObject (PGPObjectFactory. data-stream))]
      (when-not (instance? PGPSignatureList sig-list)
        (throw (IllegalArgumentException.
                 (str "Data did not contain a PGPSignatureList: " sig-list))))
      (when-not (.isEmpty sig-list)
        (.get sig-list 0)))))


(defn print-key-info
