Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.

Repository files navigation

This repo has been merge into https://github.com/cedoor/squid

🐙 Poulpy JS

Try the live demo

poulpy-js is a JavaScript library for browser-usable FHE, built on Poulpy via Squid (an ergonomic Rust wrapper). It ships a WebAssembly client (poulpy-js/client) and a napi-rs Node evaluator (poulpy-js/server) — see packages/poulpy-js/README.md for install and API docs.

This repo is the Cargo + pnpm monorepo that builds the library, plus a client/server demo showing it end-to-end: the browser generates its own (secret_key, evaluation_key) pair, ships only the evaluation key and ciphertexts to the server, and decrypts results locally. The server never sees plaintexts and never holds secret-key material.

poulpy-js/
├─ Cargo.toml                  # Rust workspace
├─ pnpm-workspace.yaml
├─ package.json                # root scripts
├─ crates/
│  ├─ poulpy-wasm/             # wasm-bindgen bindings (browser)
│  └─ poulpy-napi/             # napi-rs bindings (Node server)
├─ packages/
│  └─ poulpy-js/               # dual entry point:
│                              #   `poulpy-js/client` (browser, wasm worker + PoulpyClient)
│                              #   `poulpy-js/server` (Node, napi-backed Evaluator)
├─ demo/                       # Next.js FHE demo
└─ tests/                      # Playwright end-to-end tests

Prerequisites

  • Rust nightly (pinned in rust-toolchain.toml), with the wasm32-unknown-unknown target
  • wasm-pack (cargo install wasm-pack)
  • Node.js 20+ and pnpm 9+

Build

pnpm install
pnpm build          # build:poulpy (wasm + napi + ts) → build:demo
pnpm dev            # Next.js demo on :3000
pnpm test           # Playwright: installs Chromium (pretest), runs demo flow

Individual steps are also available (pnpm build:poulpy, pnpm build:demo). build:poulpy compiles the wasm crate via wasm-pack, the napi crate via @napi-rs/cli, and the TS wrappers via tsc — all into packages/poulpy-js/.

CI

GitHub Actions (.github/workflows/e2e.yml) runs pnpm install, pnpm build, and pnpm test on pushes and pull requests to main / master.

How it works

  1. Browser. PoulpyClient.create({ paramsSet }) spins up a module worker that loads wasm and calls Session::new_random(paramsSet). Squid resolves the name with Params::by_name (e.g. "test" or "unsecure"), then Context::keygen_with_seeds runs under that parameter set. The client exposes evaluationKey plus async encryptU32, decryptU32, and exportSeeds (all in the worker). The same paramsSet must be used on the server (POULPY_PARAMS_SET in the demo).
  2. Client → server handshake. The browser POSTs raw evaluation-key bytes (Content-Type: application/octet-stream) to POST /session. The server deserializes into a poulpy_napi::Evaluator and stores it in an in-memory Map keyed by a UUID.
  3. Compute. The browser POSTs packed ciphertext bytes to POST /session/:id/add. The server deserializes both, runs homomorphic add, and returns the serialized result ciphertext.
  4. Decrypt. Browser awaits client.decryptU32(result); secret-key material never leaves the worker/page.

Known constraints

  • Parameter setsparamsSet is a Squid name (currently "test" or "unsecure"). The demo defaults to "test"; that set uses the same layout bundle as Poulpy’s bdd_arithmetic test_suite and is smaller/faster than "unsecure". Neither is a vetted production security level.
  • Sessions are in-memory and unauthenticated (single-process demo only).
  • Keygen runs in the wasm worker until it finishes; the demo UI stays on “Booting wasm…” until the worker reports ready (the main thread stays responsive).

About

Browser and Node bindings for Poulpy homomorphic encryption, using Squid’s Rust API.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages