   (to-timestamp [obj]
     (quot (jodac/to-long obj) 1000)))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Implementation details
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defn- normalize-date-claims
   "Normalize date related claims and return transformed object."
   [data]

    (-> (signer candidate pkey)
        (codecs/bytes->safebase64))))

(defn sign
  "Sign arbitrary length string/byte array using json web signature."
  [claims pkey & [{:keys [alg exp nbf iat headers] :or {alg :hs256 headers {}}}]]
  {:pre [(map? claims)]}
  (let [headers-data (make-headers alg headers)
        claims-data  (make-claims claims exp nbf iat)
        signature    (make-signature pkey alg headers-data claims-data)]
    (str/join "." [headers-data claims-data signature])))

(defn unsign
  "Unsings jws and return clear caims as clojure map."
  [input pkey & [{:keys [maxage] :as opts}]]
  {:pre [(string? input)]}
  (let [[header claims signature] (str/split input #"\." 3)]
    (maybe-let [candidate (str/join "." [header claims])
                header    (parse-header header)
                claims    (parse-claims claims)
                algorithm (parse-algorithm header)
                signature (codecs/safebase64->bytes signature)
                verifier  (get-verifier-for-algorithm algorithm)
                now       (-> (jodat/now) (to-timestamp))]
      (when-let [isok? (verifier candidate signature pkey)]
        (maybe-let [_ (if (:exp claims)
                        (or (< now (:exp claims)) nil)
                        true)
                    _ (if (:nbf claims)
                        (or (< now (:nbf claims)) nil)
                        true)
                    _ (if (and (:iat claims) maxage)
                        (or (< (- now (:iat claims)) maxage) nil)
                        true)]
          claims)))))

      (codecs/str->bytes)
      (codecs/bytes->safebase64)))

(defn- calculate-signature
  "Make a jws signature."
  [pkey alg header claims]
  (let [candidate (str/join "." [header claims])
