crypto

Operations involving a key, a secret, or authentication. The security sibling of cx-stdlib/hash, which fingerprints public data: if it involves a key, a secret, or authentication it lives here; a bare fingerprint lives in hash. Covers HMAC, keyed-BLAKE3, HKDF, constant-time MAC verification, AEAD, Ed25519/X25519, Argon2id password hashing, and fail-closed JWT/JWKS verification. Keys, messages, MACs, and other byte material are all CXDM bytes — convert hex or base64 via cx-stdlib/bytes before passing in.

crypto:hmac-sha256

[$crypto:hmac-sha256] -> bytes — Compute the HMAC-SHA-256 (RFC 2104) of a message under a key — 32 bytes, key of any length.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hmac-sha256 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843'
          

crypto:hmac-sha384

[$crypto:hmac-sha384] -> bytes — Compute the HMAC-SHA-384 (RFC 2104) of a message under a key — 48 bytes, key of any length.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hmac-sha384 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649'
          

crypto:hmac-sha512

[$crypto:hmac-sha512] -> bytes — Compute the HMAC-SHA-512 (RFC 2104) of a message under a key — 64 bytes, key of any length.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hmac-sha512 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'
          

crypto:hmac-new

[$crypto:hmac-new] -> element — Start a streaming HMAC hasher for the named algorithm and key (sha256/sha384/sha512).

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:equals [$crypto:hmac-finalize [$crypto:hmac-update [$crypto:hmac-update [$crypto:hmac-new "sha256" [$bytes:from-string-utf8 "Jefe"]] [$bytes:from-string-utf8 "what do ya want "]] [$bytes:from-string-utf8 "for nothing?"]]] [$crypto:hmac-sha256 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            true
          

crypto:hmac-update

[$crypto:hmac-update] -> element — Feed a chunk into a streaming HMAC hasher, returning a new hasher — the input is unchanged.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:equals [$crypto:hmac-finalize [$crypto:hmac-update [$crypto:hmac-update [$crypto:hmac-new "sha256" [$bytes:from-string-utf8 "Jefe"]] [$bytes:from-string-utf8 "what do ya want "]] [$bytes:from-string-utf8 "for nothing?"]]] [$crypto:hmac-sha256 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            true
          

crypto:hmac-finalize

[$crypto:hmac-finalize] -> bytes — Finish a streaming HMAC hasher and return the MAC — equal to the single-shot HMAC over the concatenated chunks.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:equals [$crypto:hmac-finalize [$crypto:hmac-update [$crypto:hmac-update [$crypto:hmac-new "sha256" [$bytes:from-string-utf8 "Jefe"]] [$bytes:from-string-utf8 "what do ya want "]] [$bytes:from-string-utf8 "for nothing?"]]] [$crypto:hmac-sha256 [$bytes:from-string-utf8 "Jefe"] [$bytes:from-string-utf8 "what do ya want for nothing?"]]]
          
            true
          

crypto:blake3-keyed

[$crypto:blake3-keyed] -> bytes — Compute the keyed-BLAKE3 MAC of a message — exactly-32-byte key, 32-byte output.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:length [$crypto:blake3-keyed [$bytes:from-hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"] [$bytes:from-string-utf8 "abc"]]]
          
            32
          

crypto:blake3-mac-verify

[$crypto:blake3-mac-verify] -> bool — Verify a keyed-BLAKE3 MAC in constant time — returns true on match, raises CXER3701 otherwise.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $k [$bytes:from-hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"]] [= $m [$bytes:from-string-utf8 "abc"]] [$crypto:blake3-mac-verify $k $m [$crypto:blake3-keyed $k $m]]]
          
            true
          

crypto:hkdf-extract

[$crypto:hkdf-extract] -> bytes — Concentrate input keying material into a fixed-length SHA-256 PRK (HKDF-Extract, RFC 5869); empty salt allowed.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hkdf-extract [$bytes:from-hex "000102030405060708090a0b0c"] [$bytes:from-hex "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"]]]
          
            '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5'
          

crypto:hkdf-expand

[$crypto:hkdf-expand] -> bytes — Stretch a SHA-256 PRK into length bytes domain-separated by info (HKDF-Expand, RFC 5869).

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hkdf-expand [$bytes:from-hex "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"] [$bytes:from-hex "f0f1f2f3f4f5f6f7f8f9"] 42]]
          
            '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865'
          

crypto:hkdf

[$crypto:hkdf] -> bytes — Derive length bytes of key material from one secret in a single SHA-256 extract-then-expand step (RFC 5869).

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$bytes:to-hex [$crypto:hkdf [$bytes:from-hex "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"] [$bytes:from-hex "000102030405060708090a0b0c"] [$bytes:from-hex "f0f1f2f3f4f5f6f7f8f9"] 42]]
          
            '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865'
          

crypto:hkdf-extract-sha512

[$crypto:hkdf-extract-sha512] -> bytes — HKDF-Extract over SHA-512 — concentrate input keying material into a 64-byte PRK.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $ikm [$bytes:from-hex "0b0b0b0b0b0b0b0b0b0b0b"]] [= $salt [$bytes:from-hex "000102030405060708090a0b0c"]] [$bytes:length [$crypto:hkdf-extract-sha512 $salt $ikm]]]
          
            64
          

crypto:hkdf-expand-sha512

[$crypto:hkdf-expand-sha512] -> bytes — HKDF-Expand over SHA-512 — stretch a PRK into length bytes domain-separated by info.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $ikm [$bytes:from-hex "0b0b0b0b0b0b0b0b0b0b0b"]] [= $salt [$bytes:from-hex "000102030405060708090a0b0c"]] [= $info [$bytes:from-hex "f0f1f2f3f4f5f6f7f8f9"]] [$bytes:equals [$crypto:hkdf-sha512 $ikm $salt $info 42] [$crypto:hkdf-expand-sha512 [$crypto:hkdf-extract-sha512 $salt $ikm] $info 42]]]
          
            true
          

crypto:hkdf-sha512

[$crypto:hkdf-sha512] -> bytes — One-shot HKDF over SHA-512 — extract-then-expand a secret into length bytes of key material.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $ikm [$bytes:from-hex "0b0b0b0b0b0b0b0b0b0b0b"]] [= $salt [$bytes:from-hex "000102030405060708090a0b0c"]] [= $info [$bytes:from-hex "f0f1f2f3f4f5f6f7f8f9"]] [$bytes:length [$crypto:hkdf-sha512 $ikm $salt $info 42]]]
          
            42
          

crypto:hmac-verify

[$crypto:hmac-verify] -> bool — Recompute and compare an HMAC in constant time — returns true on match, raises CXER3701 otherwise, never false.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $k [$bytes:from-string-utf8 "secret"]] [= $m [$bytes:from-string-utf8 "raw-body"]] [$crypto:hmac-verify "sha256" $k $m [$crypto:hmac-sha256 $k $m]]]
          
            true
          

crypto:aead-encrypt

[$crypto:aead-encrypt] -> element — Authenticated-encrypt plaintext with associated data (AES-256-GCM or ChaCha20-Poly1305), generating a fresh nonce per call.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $k [$bytes:from-hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"]] [= $pt [$bytes:from-string-utf8 "attack at dawn"]] [= $ct [$crypto:aead-encrypt "aes-256-gcm" $k $pt [$bytes:from-string-utf8 "hdr"]]] [$bytes:equals [$crypto:aead-decrypt "aes-256-gcm" $k $ct [$bytes:from-string-utf8 "hdr"]] $pt]]
          
            cx-err:CXER0271
          

crypto:aead-decrypt

[$crypto:aead-decrypt] -> bytes — Verify the tag in constant time before returning any plaintext — auth failure raises CXER3704.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $k [$bytes:from-hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"]] [= $pt [$bytes:from-string-utf8 "attack at dawn"]] [= $ct [$crypto:aead-encrypt "aes-256-gcm" $k $pt [$bytes:from-string-utf8 "hdr"]]] [$bytes:equals [$crypto:aead-decrypt "aes-256-gcm" $k $ct [$bytes:from-string-utf8 "hdr"]] $pt]]
          
            cx-err:CXER0271
          

crypto:ed25519-keypair

[$crypto:ed25519-keypair] -> element — Sample a fresh Ed25519 keypair — 32-byte public key and 32-byte private seed.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $kp [$crypto:ed25519-keypair]] [$bytes:length $kp@public]]
          
            cx-err:CXER0271
          

crypto:ed25519-sign

[$crypto:ed25519-sign] -> bytes — Sign a message with an Ed25519 private key (RFC 8032) — deterministic per the standard.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $kp [$crypto:ed25519-keypair]] [= $m [$bytes:from-string-utf8 "sign me"]] [$crypto:ed25519-verify $kp@public $m [$crypto:ed25519-sign $kp@private $m]]]
          
            cx-err:CXER0271
          

crypto:ed25519-verify

[$crypto:ed25519-verify] -> bool — Verify an Ed25519 signature — returns true on success, raises CXER3705 on an invalid or malformed signature.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $kp [$crypto:ed25519-keypair]] [= $m [$bytes:from-string-utf8 "sign me"]] [$crypto:ed25519-verify $kp@public $m [$crypto:ed25519-sign $kp@private $m]]]
          
            cx-err:CXER0271
          

crypto:x25519-keypair

[$crypto:x25519-keypair] -> element — Sample a fresh X25519 keypair for key exchange — both keys 32 bytes.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $kp [$crypto:x25519-keypair]] [$bytes:length $kp@public]]
          
            cx-err:CXER0271
          

crypto:x25519-shared-secret

[$crypto:x25519-shared-secret] -> bytes — Compute the 32-byte X25519 Diffie-Hellman shared secret — the natural ikm for hkdf.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $a [$crypto:x25519-keypair]] [= $b [$crypto:x25519-keypair]] [$bytes:equals [$crypto:x25519-shared-secret $a@private $b@public] [$crypto:x25519-shared-secret $b@private $a@public]]]
          
            cx-err:CXER0271
          

crypto:rsa-verify

[$crypto:rsa-verify] -> bool — Verify an RSASSA-PKCS1-v1_5 signature (RFC 8017) backing the JWT RS256/384/512 families — true or raise.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$crypto:rsa-verify [rsa-public-key [n [$bytes:from-hex "8ddc3005c68c6502e848d6063449b7974dc7210aa9448bf47aa2d43540a4cafef2b15c388babd981d63171d5340f7912bd40888c7fa272a9383c20f1e40c2478da79e4daadeb02970eff531f9a6bf96737056999d6c10e130c8df10948f3fe44a58de2d70e6dcac0dd785ba247b04e8e9903e3d459cc5d186a39a872c078fe35e865c95d54d08e0a15c06c47cec3e06d8c5251374377124b32985e1ace47b2f10deb5f4eec5e44476af45f00e9e8c07d75f512f557e5e693f0d45fcc1247edb3765a7c1718ad2563e06cc9a7b33b1380442b4e14f0b2e32b9ddab327f9d0ec74e7b8ad8b5c41661705f0f4d003b29ab666742666237b0979c4606f16080a73c7"]] [e [$bytes:from-hex "010001"]]] [$bytes:from-hex "68656c6c6f2063782063727970746f"] [$bytes:from-hex "1569ad4ad6ac4d94167dc7dcac1bbfe8e263bdc974defeaa98ec51e45ff74ba1eb9084228b0914f3379f719af1fbb7f6848cfca6e89c37ea30511b06ab4cf9c25d1d39b930b4888d7d8b486c59d4b909c07594e37a087b3255c9c9396def19d2d897212a5a5b021c8ab49bd9071b27867b680b05f195081c2bd447ea961d3603aadb4cd5b28a5986df112ef2b04ed59326a78d5c03923dba456d7a5936b25d2b34c43b8ce4c9d76825236b33f91984a98a1d02df3ed64b1ef78ad1fef673f14e403da8e0fd4f713faf355b417a948de48ba64ab7718aeb0a61f2f90bb964fb07818d022c3bcebb0ae7866b65876390b8d8a3c11188973e0bfff1fde3c05e6a49"] {hash: "sha256"}]
          
            true
          

crypto:ecdsa-verify

[$crypto:ecdsa-verify] -> bool — Verify an ECDSA P-256 signature over a JOSE raw r-concat-s pair (RFC 7518 §3.4) backing JWT ES256 — true or raise.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[$crypto:ecdsa-verify [ec-public-key crv="P-256" [x [$bytes:from-hex "97d49c2f327683c64795ce33c7a8ea90b6ebc3d341fe3ece449d874d006019e4"]] [y [$bytes:from-hex "b29043a977e05ce76a0c6b38fd67a7644991166cbbd6ab6cd5d304a7cc6b83a3"]]] [$bytes:from-hex "68656c6c6f2063782063727970746f"] [$bytes:from-hex "5db3b4f367aa22dfa532452151d8a2bb9ecf0fdc968b82a0ad1ac5ed0b8a42cc15b1ce90768ccc59116297c0866874c416823cf92ed1d55b75ca828083d19920"] {curve: "P-256" hash: "sha256"}]
          
            true
          

crypto:password-hash

[$crypto:password-hash] -> string — Hash a password with Argon2id and a fresh salt, returning a self-describing PHC-string.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $enc [$crypto:password-hash [$bytes:from-string-utf8 "correct horse battery staple"] [argon2-cost memory-kib=65536 iterations=3 parallelism=4]]] [$starts-with $enc "$argon2id$v=19$"]]
          
            cx-err:CXER0271
          

crypto:password-verify

[$crypto:password-verify] -> bool — Verify a password against an Argon2id PHC-string — true on match, raises CXER3706 otherwise.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/bytes']
[?let [= $pw [$bytes:from-string-utf8 "correct horse battery staple"]] [$crypto:password-verify $pw [$crypto:password-hash $pw [argon2-cost memory-kib=65536 iterations=3 parallelism=4]]]]
          
            cx-err:CXER0271
          

crypto:jwt-verify

[$crypto:jwt-verify] -> element — Fail-closed verify a JWT against a key set at a given time, returning a [claims] value or raising — never false, never unverified claims.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/time']
[$crypto:claim [$crypto:jwt-verify "eyJhbGciOiJSUzI1NiIsImtpZCI6InJzYS0xIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlIiwic3ViIjoidXNlci0xIiwiYXVkIjoibXktYXBpIiwiZXhwIjoxNzAwMDAzNjAwLCJuYmYiOjE2OTk5OTk5OTAsImlhdCI6MTY5OTk5OTk5MH0.e4bn1A_a5Q0_4IZxKWipmmrUCCdmNkiTUs071mBMtMVXb68RGPtV2FTR1nRWvM3Zw2XTMuBsk_Y1HPinat_2JQkm3s90lltrErpYOky6Nwm6ha57BxQ0Sg5kWxuQF5KhWUqHzePIVDTfkr0WeN591nDTDn6VuajLaHn2pjXBsaJ0reT6mh6v40UQcBW-yy-XOfrsMeGVj_qZd1UmlE81XN957rjPENcPpH2E1SHfVhu3fQP3QZapxtdMADgWmryw_z5O2lDIIWb7miT0siXRCDjVEhDzKH6Hsf1aUPcYx9x44o1B5OBpX6z1uM1SP0qaOZu6x26H0AbHj84nIISE1A" [$crypto:jwks-parse "{\"keys\":[{\"kid\":\"rsa-1\",\"kty\":\"RSA\",\"alg\":\"RS256\",\"n\":\"jdwwBcaMZQLoSNYGNEm3l03HIQqpRIv0eqLUNUCkyv7ysVw4i6vZgdYxcdU0D3kSvUCIjH-icqk4PCDx5AwkeNp55Nqt6wKXDv9TH5pr-Wc3BWmZ1sEOEwyN8QlI8_5EpY3i1w5tysDdeFuiR7BOjpkD49RZzF0YajmocsB4_jXoZcldVNCOChXAbEfOw-BtjFJRN0N3EksymF4azkey8Q3rX07sXkRHavRfAOnowH119RL1V-Xmk_DUX8wSR-2zdlp8FxitJWPgbMmnszsTgEQrThTwsuMrndqzJ_nQ7HTnuK2LXEFmFwXw9NADspq2ZnQmZiN7CXnEYG8WCApzxw\",\"e\":\"AQAB\"},{\"kid\":\"ec-1\",\"kty\":\"EC\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"l9ScLzJ2g8ZHlc4zx6jqkLbrw9NB_j7ORJ2HTQBgGeQ\",\"y\":\"spBDqXfgXOdqDGs4_WenZEmRFmy71qts1dMEp8xrg6M\"},{\"kid\":\"ed-1\",\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"alg\":\"EdDSA\",\"x\":\"W7aFRt4kKu7VuwPv6oBWPpxSwy9jCzk2QqawxURsnsk\"}]}"] [$time:datetime 2023 11 14 22 13 20] {}] "iss"]
          
            'https://idp.example'
          

crypto:jwks-fetch

[$crypto:jwks-fetch] -> element — GET a JWKS document over http and return a parsed [jwks] — non-2xx, transport fault, or non-JWKS body raises CXER3716.

            [?lib 'cx-stdlib/crypto']
[$crypto:jwks-fetch "https://idp.example/.well-known/jwks.json" {}]
          
            cx-err:CXER0271
          

crypto:jwks-parse

[$crypto:jwks-parse] -> element — Parse already-fetched JWKS JSON into a [jwks] value — malformed or inconsistent alg/kty raises CXER3717.

            [?lib 'cx-stdlib/crypto']
[?let [= $k [$crypto:jwk-by-kid [$crypto:jwks-parse "{\"keys\":[{\"kid\":\"rsa-1\",\"kty\":\"RSA\",\"alg\":\"RS256\",\"n\":\"jdwwBcaMZQLoSNYGNEm3l03HIQqpRIv0eqLUNUCkyv7ysVw4i6vZgdYxcdU0D3kSvUCIjH-icqk4PCDx5AwkeNp55Nqt6wKXDv9TH5pr-Wc3BWmZ1sEOEwyN8QlI8_5EpY3i1w5tysDdeFuiR7BOjpkD49RZzF0YajmocsB4_jXoZcldVNCOChXAbEfOw-BtjFJRN0N3EksymF4azkey8Q3rX07sXkRHavRfAOnowH119RL1V-Xmk_DUX8wSR-2zdlp8FxitJWPgbMmnszsTgEQrThTwsuMrndqzJ_nQ7HTnuK2LXEFmFwXw9NADspq2ZnQmZiN7CXnEYG8WCApzxw\",\"e\":\"AQAB\"},{\"kid\":\"ec-1\",\"kty\":\"EC\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"l9ScLzJ2g8ZHlc4zx6jqkLbrw9NB_j7ORJ2HTQBgGeQ\",\"y\":\"spBDqXfgXOdqDGs4_WenZEmRFmy71qts1dMEp8xrg6M\"},{\"kid\":\"ed-1\",\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"alg\":\"EdDSA\",\"x\":\"W7aFRt4kKu7VuwPv6oBWPpxSwy9jCzk2QqawxURsnsk\"}]}"] "ec-1"]] $k@kty]
          
            'EC'
          

crypto:claim

[$crypto:claim] -> element — Read a named claim from a verified [claims] value — absent yields the absence channel, never null.

            [?lib 'cx-stdlib/crypto']
[?lib 'cx-stdlib/time']
[$crypto:claim [$crypto:jwt-verify "eyJhbGciOiJSUzI1NiIsImtpZCI6InJzYS0xIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlIiwic3ViIjoidXNlci0xIiwiYXVkIjoibXktYXBpIiwiZXhwIjoxNzAwMDAzNjAwLCJuYmYiOjE2OTk5OTk5OTAsImlhdCI6MTY5OTk5OTk5MH0.e4bn1A_a5Q0_4IZxKWipmmrUCCdmNkiTUs071mBMtMVXb68RGPtV2FTR1nRWvM3Zw2XTMuBsk_Y1HPinat_2JQkm3s90lltrErpYOky6Nwm6ha57BxQ0Sg5kWxuQF5KhWUqHzePIVDTfkr0WeN591nDTDn6VuajLaHn2pjXBsaJ0reT6mh6v40UQcBW-yy-XOfrsMeGVj_qZd1UmlE81XN957rjPENcPpH2E1SHfVhu3fQP3QZapxtdMADgWmryw_z5O2lDIIWb7miT0siXRCDjVEhDzKH6Hsf1aUPcYx9x44o1B5OBpX6z1uM1SP0qaOZu6x26H0AbHj84nIISE1A" [$crypto:jwks-parse "{\"keys\":[{\"kid\":\"rsa-1\",\"kty\":\"RSA\",\"alg\":\"RS256\",\"n\":\"jdwwBcaMZQLoSNYGNEm3l03HIQqpRIv0eqLUNUCkyv7ysVw4i6vZgdYxcdU0D3kSvUCIjH-icqk4PCDx5AwkeNp55Nqt6wKXDv9TH5pr-Wc3BWmZ1sEOEwyN8QlI8_5EpY3i1w5tysDdeFuiR7BOjpkD49RZzF0YajmocsB4_jXoZcldVNCOChXAbEfOw-BtjFJRN0N3EksymF4azkey8Q3rX07sXkRHavRfAOnowH119RL1V-Xmk_DUX8wSR-2zdlp8FxitJWPgbMmnszsTgEQrThTwsuMrndqzJ_nQ7HTnuK2LXEFmFwXw9NADspq2ZnQmZiN7CXnEYG8WCApzxw\",\"e\":\"AQAB\"},{\"kid\":\"ec-1\",\"kty\":\"EC\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"l9ScLzJ2g8ZHlc4zx6jqkLbrw9NB_j7ORJ2HTQBgGeQ\",\"y\":\"spBDqXfgXOdqDGs4_WenZEmRFmy71qts1dMEp8xrg6M\"},{\"kid\":\"ed-1\",\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"alg\":\"EdDSA\",\"x\":\"W7aFRt4kKu7VuwPv6oBWPpxSwy9jCzk2QqawxURsnsk\"}]}"] [$time:datetime 2023 11 14 22 13 20] {}] "iss"]
          
            'https://idp.example'
          

crypto:jwk-by-kid

[$crypto:jwk-by-kid] -> element — Select a [jwk] from a [jwks] by key id — no match yields the absence channel.

            [?lib 'cx-stdlib/crypto']
[?let [= $k [$crypto:jwk-by-kid [$crypto:jwks-parse "{\"keys\":[{\"kid\":\"rsa-1\",\"kty\":\"RSA\",\"alg\":\"RS256\",\"n\":\"jdwwBcaMZQLoSNYGNEm3l03HIQqpRIv0eqLUNUCkyv7ysVw4i6vZgdYxcdU0D3kSvUCIjH-icqk4PCDx5AwkeNp55Nqt6wKXDv9TH5pr-Wc3BWmZ1sEOEwyN8QlI8_5EpY3i1w5tysDdeFuiR7BOjpkD49RZzF0YajmocsB4_jXoZcldVNCOChXAbEfOw-BtjFJRN0N3EksymF4azkey8Q3rX07sXkRHavRfAOnowH119RL1V-Xmk_DUX8wSR-2zdlp8FxitJWPgbMmnszsTgEQrThTwsuMrndqzJ_nQ7HTnuK2LXEFmFwXw9NADspq2ZnQmZiN7CXnEYG8WCApzxw\",\"e\":\"AQAB\"},{\"kid\":\"ec-1\",\"kty\":\"EC\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"l9ScLzJ2g8ZHlc4zx6jqkLbrw9NB_j7ORJ2HTQBgGeQ\",\"y\":\"spBDqXfgXOdqDGs4_WenZEmRFmy71qts1dMEp8xrg6M\"},{\"kid\":\"ed-1\",\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"alg\":\"EdDSA\",\"x\":\"W7aFRt4kKu7VuwPv6oBWPpxSwy9jCzk2QqawxURsnsk\"}]}"] "ec-1"]] $k@kty]
          
            'EC'