id-kit / src / ardegazu / id / crypto.cljs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
;; 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 "/"))))

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/id-kit.git