   "Generic function that implement salted variant
 of keyed-hash message authentication code (hmac).
 This is a low level function and always return bytes."
-  [data ^String key salt ^String algorithm]
+  [data key salt ^String algorithm]
   (let [key (concat-byte-arrays (->byte-array key)
                                 (->byte-array salt))]
     (make-hmac data (sha512 key) algorithm)))
 
 (defn- verify-salted-hmac
-  [data ^bytes signature ^String key salt ^String algorithm]
+  [data ^bytes signature key salt ^String algorithm]
   (let [key (concat-byte-arrays (->byte-array key)
                                 (->byte-array salt))]
     (verify-hmac data signature (sha512 key) algorithm)))


(extend-protocol HMac
  (Class/forName "[B")
  (make-hmac [^bytes data ^String key ^String algorithm]
    (make-hmac-for-plain-data data key algorithm))
  (verify-hmac [^bytes data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-plain-data data signature key algorithm))

  java.lang.String
  (make-hmac [^String data ^String key ^String algorithm]
    (make-hmac-for-plain-data (->byte-array data) key algorithm))
  (verify-hmac [^String data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-plain-data (->byte-array data) signature key algorithm))

  java.io.InputStream
  (make-hmac [^java.io.InputStream data ^String key ^String algorithm]
    (make-hmac-for-stream data key algorithm))
  (verify-hmac [^java.io.InputStream data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-stream data signature key algorithm))

  java.io.File
  (make-hmac [^java.io.File data ^String key ^String algorithm]
    (make-hmac-for-stream (io/input-stream data) key algorithm))
  (verify-hmac [^java.io.File data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-stream (io/input-stream data) signature key algorithm))

  java.net.URL
  (make-hmac [^java.net.URL data ^String key ^String algorithm]
    (make-hmac-for-stream (io/input-stream data) key algorithm))
  (verify-hmac [^java.net.URL data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-stream (io/input-stream data) signature key algorithm))

  java.net.URI
  (make-hmac [^java.net.URI data ^String key ^String algorithm]
    (make-hmac-for-stream (io/input-stream data) key algorithm))
  (verify-hmac [^java.net.URI data ^bytes signature ^String key ^String algorithm]
    (verify-hmac-for-stream (io/input-stream data) signature key algorithm)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn hmac
  [data key ^String algorithm]
  (make-hmac data key algorithm))

(defn hmac-verify
  [data ^bytes signature key ^String algorithm]
  (verify-hmac data signature key algorithm))

(defn shmac
