npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluree/crypto

v4.0.1

Published

Cryptography library for Fluree

Downloads

1,399

Readme

Cryptography Library for Fluree

A collection of cryptography functions for Fluree, implemented in Clojure/ClojureScript with platform-specific optimizations.

Features

  • Ed25519 Digital Signatures - Fast, secure signatures using Noble Ed25519 (JS) and Java 17+ native support (JVM)
  • JWS (JSON Web Signatures) - RFC 7515/8037 compliant JWS creation and verification
  • DID Support - Decentralized identifier generation and verification (did:key method)
  • SHA-2 Hashing - SHA-256 and SHA-512 implementations
  • AES Encryption - Symmetric encryption/decryption
  • Cross-platform - Consistent API across JVM, Node.js, and browser environments
  • GraalVM Native Image Support - Can be compiled to native executables

Installation

Clojure/ClojureScript

Add to your deps.edn:

{:deps {com.fluree/crypto {:mvn/version "4.0.0"}}}

Node.js

npm install @fluree/crypto

Browser

The browser build is available at dist/browser/fluree-crypto.js after building.

API Reference

Key Generation

Generate Key Pair

;; Clojure
(require '[fluree.crypto :as crypto])

;; Generate a new Ed25519 key pair
(crypto/generate-key-pair)
;; => {:private "hex-string", :public "hex-string"}

;; Generate from existing private key
(crypto/generate-key-pair "your-private-key-hex")
// JavaScript
// Generate a new Ed25519 key pair
const keyPair = crypto.generateKeyPair();
// Returns: { private: "hex-string", public: "hex-string" }

// Generate from existing private key
const keyPair2 = crypto.generateKeyPair("your-private-key-hex");

Public Key from Private

;; Clojure
(crypto/public-key-from-private "private-key-hex")
;; => "public-key-hex"
// JavaScript
const publicKey = crypto.publicKeyFromPrivate("private-key-hex");
// Returns: "public-key-hex"

Account IDs and DIDs

Account ID from Public Key

;; Clojure
(crypto/account-id-from-public "public-key-hex")
;; => "base58-account-id" (e.g., "TfGvAdKH2nRdV4zP4yBz4kJ2R9WzYHDe2EV")

;; With output format
(crypto/account-id-from-public "public-key-hex" {:output-format :multibase})
;; => "did:key:z6Mk..." format
// JavaScript
const accountId = crypto.accountIdFromPublic("public-key-hex");
// Returns: "base58-account-id" (e.g., "TfGvAdKH2nRdV4zP4yBz4kJ2R9WzYHDe2EV")

Account ID from Private Key

;; Clojure
(crypto/account-id-from-private "private-key-hex")
;; => "base58-account-id"
// JavaScript
const accountId = crypto.accountIdFromPrivate("private-key-hex");
// Returns: "base58-account-id"

DID from Public Key

;; Clojure
(crypto/did-from-public "public-key-hex")
;; => "did:key:z6Mk..." (multibase-encoded DID)
// JavaScript
const did = crypto.didFromPublic("public-key-hex");
// Returns: "did:key:z6Mk..." (multibase-encoded DID)

Digital Signatures

Sign Message

;; Clojure
(crypto/sign-message "message" "private-key-hex")
;; => "signature-hex"

;; With key pair map
(crypto/sign-message "message" {:private "private-key-hex" :public "public-key-hex"})
// JavaScript
const signature = crypto.signMessage("message", "private-key-hex");
// Returns: "signature-hex"

Verify Signature

;; Clojure
(crypto/verify-signature "public-key-hex" "message" "signature-hex")
;; => true or false
// JavaScript
const isValid = crypto.verifySignature("public-key-hex", "message", "signature-hex");
// Returns: true or false

JWS (JSON Web Signatures)

Create JWS

;; Clojure
;; Basic JWS
(crypto/create-jws "payload" keypair)
;; => "header.payload.signature"

;; With embedded public key (for self-contained verification)
(crypto/create-jws "payload" keypair {:include-pubkey true})

;; With key ID (account ID)
(crypto/create-jws "payload" keypair {:account-id true})

;; With custom key ID
(crypto/create-jws "payload" keypair {:kid "my-key-id"})
// JavaScript
// Basic JWS
const jws = crypto.createJWS("payload", keyPair);
// Returns: "header.payload.signature"

// With embedded public key (for self-contained verification)
const jws2 = crypto.createJWS("payload", keyPair, { includePublicKey: true });

// With key ID (account ID)
const jws3 = crypto.createJWS("payload", keyPair, { accountId: true });

// With custom key ID
const jws4 = crypto.createJWS("payload", keyPair, { kid: "my-key-id" });

Verify JWS

;; Clojure
;; Verify with explicit public key
(crypto/verify-jws jws "public-key-hex")
;; => {:payload "original-payload", :pubkey "public-key-hex", :header {...}}

;; Verify self-contained JWS (with embedded key or account ID)
(crypto/verify-jws jws)
;; => {:payload "...", :pubkey "...", :header {...}, :kid "..."}

;; Error case returns an Exception
(crypto/verify-jws "invalid-jws")
;; => #error {:cause "..." :data {...}}
// JavaScript
// Verify with explicit public key
const result = crypto.verifyJWS(jws, "public-key-hex");
// Returns: { payload: "original-payload", pubkey: "public-key-hex", header: {...} }

// Verify self-contained JWS (with embedded key or account ID)
const result2 = crypto.verifyJWS(jws2);
// Returns: { payload: "...", pubkey: "...", header: {...}, kid: "..." }

// Error case returns an Error object
const error = crypto.verifyJWS("invalid-jws");
// Returns: Error instance

Hashing

SHA-256

;; Clojure
;; Basic usage
(crypto/sha2-256 "message")
;; => "hex-string"

;; With output format
(crypto/sha2-256 "message" :bytes)
;; Valid formats: :hex, :bytes, :base64, :base58, :string

;; With input and output format
(crypto/sha2-256 "68656c6c6f" :base64 :hex)
// JavaScript
// Basic usage
const hash = crypto.sha2_256("message");
// Returns: "hex-string"

// With output format
const hashBytes = crypto.sha2_256("message", "bytes");
// Valid formats: "hex", "bytes", "base64", "base58", "string"

// With input and output format
const hash2 = crypto.sha2_256("68656c6c6f", "base64", "hex");

SHA-256 Normalize

Normalizes the input string using NFKC before hashing:

;; Clojure
(crypto/sha2-256-normalize "message")
;; => "hex-string"

;; With output format
(crypto/sha2-256-normalize "message" :base64)
// JavaScript
const hash = crypto.sha2_256_normalize("message");
// Returns: "hex-string"

SHA-512

;; Clojure
(crypto/sha2-512 "message")
;; => "hex-string"

;; With formats (same as SHA-256)
(crypto/sha2-512 "message" :base64)
// JavaScript
const hash = crypto.sha2_512("message");
// Returns: "hex-string"

// With formats (same as SHA-256)
const hashBase64 = crypto.sha2_512("message", "base64");

Encryption

AES Encrypt

;; Clojure
(def iv [6 224 71 170 241 204 115 21 30 8 46 223 106 207 55 42])
(crypto/aes-encrypt "message" iv "password")
;; => "hex-string"

;; With output format
(crypto/aes-encrypt "message" iv "password" :base64)
// JavaScript
const iv = [6, 224, 71, 170, 241, 204, 115, 21, 30, 8, 46, 223, 106, 207, 55, 42];
const encrypted = crypto.aesEncrypt("message", iv, "password");
// Returns: "hex-string"

// With output format
const encryptedBase64 = crypto.aesEncrypt("message", iv, "password", "base64");

AES Decrypt

;; Clojure
(crypto/aes-decrypt encrypted iv "password")
;; => "message"

;; With input/output formats
(crypto/aes-decrypt encrypted-base64 iv "password" :string :base64)
// JavaScript
const decrypted = crypto.aesDecrypt(encrypted, iv, "password");
// Returns: "message"

// With input/output formats
const decrypted2 = crypto.aesDecrypt(encryptedBase64, iv, "password", "string", "base64");

Utility Functions

Normalize String

;; Clojure
(crypto/normalize-string "\u0041\u030apple")
;; => NFKC normalized string
// JavaScript
const normalized = crypto.normalizeString("\u0041\u030apple");
// Returns NFKC normalized string

String to Byte Array

;; Clojure
(crypto/string->byte-array "hello")
;; => [104 101 108 108 111]
// JavaScript
const bytes = crypto.stringToByteArray("hello");
// Returns: [104, 101, 108, 108, 111]

Byte Array to String

;; Clojure
(crypto/byte-array->string [104 101 108 108 111])
;; => "hello"
// JavaScript
const str = crypto.byteArrayToString([104, 101, 108, 108, 111]);
// Returns: "hello"

Platform-Specific Implementation Details

JavaScript (Node.js/Browser)

  • Uses @noble/ed25519 v2.3.0 for Ed25519 operations
  • Pure JavaScript implementation ensures consistent behavior

JVM

  • Uses Java 17+ native Ed25519 support via JCA/JCE
  • EdECPrivateKeySpec and EdECPublicKeySpec for key management
  • Hardware-accelerated when available

Development

Prerequisites

  • Clojure CLI tools
  • Node.js and npm
  • Java 17+

Building

# Build everything
make all

# Build JAR only
make jar

# Build Node.js package
make node

# Build browser package
make browser

Testing

# Run all tests
make test

# Run specific test suites
make cljtest      # JVM tests
make cljstest     # ClojureScript tests
make node-test    # Node.js integration tests

GraalVM Native Image

The library supports GraalVM native image compilation. See README-graalvm.md for details.

Changes from v3.x

  • Ed25519 only: Removed SECP256K1 support (use v3.x if needed)
  • No SHA-3/RIPEMD: Removed to improve GraalVM compatibility
  • Upgraded dependencies: Noble Ed25519 v2.3.0, Java 17+ required
  • New features: DID support, automatic public key derivation in JWS

Contributing

  1. Fork and clone the repository
  2. Create a branch for your feature
  3. Write tests for new functionality
  4. Ensure all tests pass with make test
  5. Submit a pull request

License

Copyright © 2025 Fluree, PBC

Distributed under the MIT License.