   message. When given a valid signature, returns nil. When given an
   invalid signed message or signature, raises RuntimeException."
   ([pk sm]
-   (let [smlen (alength ^bytes sm)
+   (let [smlen (buflen sm)
          m (byte-array (- smlen bytes))
          res (.crypto_sign_open sodium m nil sm smlen pk)]
      (if (zero? res)
        m
        (throw (RuntimeException. "Signature validation failed")))))
   ([pk msg sig]
-   (let [mlen (alength ^bytes msg)
+   (let [mlen (buflen msg)
          res (.crypto_sign_verify_detached sodium sig msg mlen pk)]
      (when-not (zero? res)
        (throw (RuntimeException. "Signature validation failed"))))))

  "Puts a signed version of the given message using given secret key into the
  given out buffer."
  [out sk m]
  (let [mlen (alength ^bytes m)]
    (.crypto_sign sodium out nil m mlen sk)
    out))

(defn signed
  "Produces a signed version of the given message m using given secret key."
  [sk m]
  (let [sm (byte-array (+ bytes (alength ^bytes m)))]
    (signed-to-buf! sm sk m)))

(defn sign-to-buf!
  "Puts a signature of the given message using given secret key into the given
  out buffer."
  [out sk m]
  (let [mlen (alength ^bytes m)]
    (.crypto_sign_detached sodium out nil m mlen sk)
    out))

(defn sign
  "Produces a detached signature for a message m using given secret key."

(ns caesium.crypto.sign
  (:refer-clojure :exclude [bytes])
  (:require [caesium.binding :refer [defconsts sodium]]
            [caesium.byte-bufs :refer [buflen]]))

(defconsts [bytes seedbytes publickeybytes secretkeybytes primitive])

