;; ported-from: src/crypto.ts @ v1.1.0
;;
;; Byte + base64url primitives shared by the identity kit. WebCrypto only.
;; A subset of the sueta p2p core's lib/crypto, kept byte-compatible so
;; encodings interop with every app in the suite. Uint8Array at every boundary.
;;
;; No `clojure.string` here (nor in ardegazu.id.identity): requiring it retains
;; cljs.core's seq/collection runtime through :advanced DCE, which lands in the
;; shared module of every consumer that compiles this kit from source. The
;; replacements below are the exact expansion clojure.string/replace performs —
;; a global js/RegExp per pattern — so behavior is unchanged.
(ns ardegazu.id.crypto)
;; clojure.string/replace forces the "g" flag for BOTH string and regex
;; matches, so each of these is global. Reuse is safe: String.prototype.replace
;; sets lastIndex to 0 on a global regex before it matches.
(def ^:private re-plus (js/RegExp. "\\+" "g"))
(def ^:private re-slash (js/RegExp. "/" "g"))
(def ^:private re-pad (js/RegExp. "=+$" "g"))
(def ^:private re-minus (js/RegExp. "-" "g"))
(def ^:private re-underscore (js/RegExp. "_" "g"))
(defn utf8 [s]
(.encode (js/TextEncoder.) s))
(defn random-bytes [n]
(let [b (js/Uint8Array. n)]
(js/crypto.getRandomValues b)
b))
(defn to-b64 [bytes]
(let [n (.-length ^js bytes)]
(loop [i 0 s ""]
(if (< i n)
(recur (inc i) (str s (js/String.fromCharCode (aget bytes i))))
(js/btoa s)))))
(defn from-b64 [s]
(let [bin (js/atob s)
b (js/Uint8Array. (.-length bin))]
(dotimes [i (.-length bin)]
(aset b i (.charCodeAt bin i)))
b))
(defn to-b64url [bytes]
(-> (to-b64 bytes)
(.replace re-plus "-")
(.replace re-slash "_")
(.replace re-pad "")))
(defn from-b64url [s]
(from-b64 (-> s
(.replace re-minus "+")
(.replace re-underscore "/"))))