Skip to content

Commit 3175312

Browse files
committed
Improve documentation
1 parent 782de1b commit 3175312

File tree

10 files changed

+116
-46
lines changed

10 files changed

+116
-46
lines changed

.github/workflows/publish.yml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,18 @@ jobs:
5757
name: Build and publish Python wheels
5858
steps:
5959
- uses: actions/checkout@v4
60-
- uses: actions/setup-python@v4
61-
with:
62-
python-version: '3.x'
63-
- name: Create virtual environment and install maturin
64-
run: |
65-
python -m venv .venv
66-
source .venv/bin/activate
67-
pip install maturin
6860
- name: Build wheels
6961
uses: PyO3/maturin-action@v1
7062
with:
7163
target: ${{ matrix.target }}
7264
args: --release --out dist --features python
7365
sccache: 'true'
7466
manylinux: auto
67+
python-version: '3.8-3.13'
7568
- name: Upload wheels
7669
uses: actions/upload-artifact@v3
7770
with:
78-
name: wheels
71+
name: wheels-${{ matrix.target }}
7972
path: dist
8073

8174
publish-python-sdist:
@@ -104,7 +97,7 @@ jobs:
10497
- name: Upload sdist
10598
uses: actions/upload-artifact@v3
10699
with:
107-
name: wheels
100+
name: sdist
108101
path: dist
109102

110103
release-python:
@@ -119,7 +112,11 @@ jobs:
119112
- name: Download all artifacts
120113
uses: actions/download-artifact@v3
121114
with:
122-
name: wheels
123-
path: dist
115+
path: artifacts
116+
- name: Move files to dist
117+
run: |
118+
mkdir -p dist
119+
find artifacts -name "*.whl" -exec cp {} dist/ \;
120+
find artifacts -name "*.tar.gz" -exec cp {} dist/ \;
124121
- name: Publish to PyPI
125122
uses: PyPA/gh-action-pypi-publish@release/v1

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
[package]
22
name = "libpep"
33
edition = "2021"
4-
version = "0.6.9"
4+
version = "0.6.10"
55
authors = ["Bernard van Gastel <bvgastel@bitpowder.com>", "Job Doesburg <job@jobdoesburg.nl>"]
66
homepage = "https://github.com/NOLAI/libpep"
77
repository = "https://github.com/NOLAI/libpep"
88
documentation = "https://docs.rs/libpep"
99
license = "Apache-2.0"
10-
keywords = ["crypto", "pep", "pseudonimization"]
11-
categories = ["command-line-interface"]
12-
description = "implementation of PEP primitives, offering pseudonimization and encryption interfaces"
10+
keywords = ["crypto", "pep", "pseudonymization"]
11+
categories = ["cryptography", "algorithms"]
12+
description = "Implementation of PEP primitives, offering pseudonymization and encryption interfaces"
1313
readme = "README.md"
1414

1515
[features]

README.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# `libpep`: Library for polymorphic pseudonymization and encryption
22
[![Crates.io](https://img.shields.io/crates/v/libpep.svg)](https://crates.io/crates/libpep)
3-
[![Downloads](https://img.shields.io/crates/d/libpep.svg)](https://crates.io/crates/libpep)
4-
[![PyPI](https://img.shields.io/pypi/v/libpep-py.svg)](https://pypi.org/project/libpep-py/)
5-
[![PyPI Downloads](https://img.shields.io/pypi/dm/libpep-py.svg)](https://pypi.org/project/libpep-py/)
6-
[![npm](https://img.shields.io/npm/v/@nolai/libpep-wasm.svg)](https://www.npmjs.com/package/@nolai/libpep-wasm)
7-
[![npm Downloads](https://img.shields.io/npm/dm/@nolai/libpep-wasm.svg)](https://www.npmjs.com/package/@nolai/libpep-wasm)
3+
[![Downloads](https://img.shields.io/crates/d/libpep)](https://crates.io/crates/libpep)
4+
[![PyPI](https://img.shields.io/pypi/v/libpep-py)](https://pypi.org/project/libpep-py/)
5+
[![Downloads](https://img.shields.io/pypi/dm/libpep-py)](https://pypi.org/project/libpep-py/)
6+
[![npm](https://img.shields.io/npm/v/@nolai/libpep-wasm)](https://www.npmjs.com/package/@nolai/libpep-wasm)
7+
[![Downloads](https://img.shields.io/npm/dm/@nolai/libpep-wasm.svg)](https://www.npmjs.com/package/@nolai/libpep-wasm)
88
[![License](https://img.shields.io/crates/l/libpep.svg)](https://crates.io/crates/libpep)
99
[![Documentation](https://docs.rs/libpep/badge.svg)](https://docs.rs/libpep)
1010
[![Dependencies](https://deps.rs/repo/github/NOLAI/libpep/status.svg)](https://deps.rs/repo/github/NOLAI/libpep)
@@ -85,11 +85,16 @@ console.log(`Data point: ${data.as_hex()}`);
8585
### API Structure
8686

8787
Both Python and WASM bindings mirror the Rust API structure with the same modules:
88-
- `arithmetic` - Basic arithmetic operations on scalars and group elements
89-
- `elgamal` - ElGamal encryption and decryption
90-
- `primitives` - Core PEP operations (`rekey`, `reshuffle`, `rerandomize`)
91-
- `high_level` - User-friendly API with `Pseudonym` and `DataPoint` classes
92-
- `distributed` - Distributed n-PEP operations with multiple servers
88+
89+
| Module | Description |
90+
|--------|-------------|
91+
| `arithmetic` | Basic arithmetic operations on scalars and group elements |
92+
| `elgamal` | ElGamal encryption and decryption primitives |
93+
| `primitives` | Core PEP operations (`rekey`, `reshuffle`, `rerandomize`) |
94+
| `high_level` | User-friendly API with `Pseudonym` and `DataPoint` classes |
95+
| `distributed` | Distributed n-PEP operations with multiple servers |
96+
97+
For detailed API documentation, see [docs.rs/libpep](https://docs.rs/libpep).
9398

9499
## Applications
95100

@@ -105,9 +110,17 @@ The factor `k` is typically tied to the *current session of a user*, which we ca
105110
When the same encrypted pseudonym is used multiple times, rerandomize is applied every time.
106111
This way a binary compare of the encrypted pseudonym will not leak any information.
107112

108-
## Implementation
113+
## Security and Implementation
114+
115+
This library uses the Ristretto encoding on Curve25519, implemented in the [`curve25519-dalek` crate](https://docs.rs/curve25519-dalek/latest/curve25519_dalek/), with [patches by Signal](https://github.com/signalapp/curve25519-dalek) for _lizard_ encoding of arbitrary 16 byte values into ristretto points.
109116

110-
This library is using the Ristretto encoding on Curve25519, implemented in the [`curve25519-dalek` crate](https://docs.rs/curve25519-dalek/latest/curve25519_dalek/), but with [patches by Signal](https://github.com/signalapp/curve25519-dalek) for _lizard_ encoding of arbitrary 16 byte values into ristretto points.
117+
### Security Considerations
118+
- All cryptographic operations use constant-time algorithms to prevent timing attacks
119+
- Random number generation uses cryptographically secure sources
120+
- The library has been designed for production use but hasn't yet undergone formal security auditing
121+
- Users should properly secure private keys and avoid exposing sensitive cryptographic material
122+
123+
### Arithmetic Rules
111124
There are a number of arithmetic rules for scalars and group elements: group elements can be added and subtracted from each other.
112125
Scalars support addition, subtraction, and multiplication.
113126
Division can be done by multiplying with the inverse (using `s.invert()` for non-zero scalar `s`).
@@ -132,13 +145,27 @@ Depending on the use case, you can choose the appropriate level of abstraction.
132145

133146
## Development
134147

148+
### Prerequisites
149+
- Rust 1.70+ (MSRV)
150+
- Node.js 18+ (for WASM bindings)
151+
- Python 3.8+ (for Python bindings)
152+
153+
### Building and Testing
154+
135155
Build and test the core Rust library:
136156
```bash
137157
cargo build
138158
cargo test
159+
cargo clippy
139160
cargo doc --no-deps
140161
```
141162

163+
Run tests with different feature combinations:
164+
```bash
165+
cargo test --features elgamal3
166+
cargo test --features legacy-pep-repo-compatible
167+
```
168+
142169
## Building Bindings
143170

144171
### Python

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nolai/libpep-wasm",
3-
"version": "0.6.9",
3+
"version": "0.6.10",
44
"description": "The WebAssembly version of the libpep library",
55
"repository": {
66
"type": "git",

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ classifiers = [
2020
"Programming Language :: Python :: 3.10",
2121
"Programming Language :: Python :: 3.11",
2222
"Programming Language :: Python :: 3.12",
23+
"Programming Language :: Python :: 3.13",
2324
"Programming Language :: Rust",
2425
"Topic :: Security :: Cryptography",
2526
]

src/lib/distributed/systems.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl PEPSystem {
110110
transcrypt(encrypted, transcryption_info)
111111
}
112112

113-
/// Transcrypt a batch of encrypted messages for one entity (see [`EncryptedEntityMessages`]),
113+
/// Transcrypt a batch of encrypted messages for one entity (see [`EncryptedEntityData`]),
114114
/// from one pseudonymization domain and session to another, using [`TranscryptionInfo`].
115115
pub fn transcrypt_batch<R: RngCore + CryptoRng>(
116116
&self,

src/lib/high_level/ops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub fn rekey_batch<R: RngCore + CryptoRng>(
167167
/// A pair of encrypted pseudonyms and data points that relate to the same entity, used for batch transcryption.
168168
pub type EncryptedEntityData = (Vec<EncryptedPseudonym>, Vec<EncryptedDataPoint>);
169169

170-
/// Batch transcryption of a slice of [`EncryptedEntityMessages`]s, using [`TranscryptionInfo`].
170+
/// Batch transcryption of a slice of [`EncryptedEntityData`]s, using [`TranscryptionInfo`].
171171
/// The order of the pairs (entities) is randomly shuffled to avoid linking them, but the internal
172172
/// order of pseudonyms and data points for the same entity is preserved.
173173
pub fn transcrypt_batch<R: RngCore + CryptoRng>(

src/lib/lib.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,7 @@ pub mod distributed {
6868
pub mod systems;
6969
}
7070
#[cfg(feature = "wasm")]
71-
mod wasm {
72-
//! Wrappers for WebAssembly bindings.
73-
//! Since WebAssembly does not support the polymorphic properties we use in the rest of the
74-
//! library, we need to provide wrappers around all structs and functions.
75-
//! This module is only available when the `wasm` feature is enabled.
76-
mod arithmetic;
77-
mod distributed;
78-
mod elgamal;
79-
mod high_level;
80-
mod primitives;
81-
}
71+
pub mod wasm;
8272

8373
#[cfg(feature = "python")]
8474
mod python;

src/lib/wasm/high_level.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ pub struct WASMSessionKeyPair {
385385
#[wasm_bindgen(js_name = makeGlobalKeys)]
386386
pub fn wasm_make_global_keys() -> WASMGlobalKeyPair {
387387
let mut rng = rand::thread_rng();
388-
let (public, secret) = make_global_keys(&mut rng);
388+
let (public, secret) = crate::high_level::keys::make_global_keys(&mut rng);
389389
WASMGlobalKeyPair {
390390
public: WASMGlobalPublicKey::from(WASMGroupElement::from(public.0)),
391391
secret: WASMGlobalSecretKey::from(WASMScalarNonZero::from(secret.0)),
@@ -399,14 +399,14 @@ pub fn wasm_make_session_keys(
399399
session: &str,
400400
secret: &WASMEncryptionSecret,
401401
) -> WASMSessionKeyPair {
402-
let (public, secret) = make_session_keys(
403-
&GlobalSecretKey(*global.0),
402+
let (public, secret_key) = crate::high_level::keys::make_session_keys(
403+
&GlobalSecretKey(global.0 .0),
404404
&EncryptionContext::from(session),
405405
&secret.0,
406406
);
407407
WASMSessionKeyPair {
408408
public: WASMSessionPublicKey::from(WASMGroupElement::from(public.0)),
409-
secret: WASMSessionSecretKey::from(WASMScalarNonZero::from(secret.0)),
409+
secret: WASMSessionSecretKey::from(WASMScalarNonZero::from(secret_key.0)),
410410
}
411411
}
412412

src/lib/wasm/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! WebAssembly bindings for libpep using wasm-bindgen.
2+
//!
3+
//! This module provides WebAssembly access to all libpep functionality including:
4+
//! - Basic arithmetic operations on group elements and scalars
5+
//! - ElGamal encryption and decryption
6+
//! - PEP primitives (rekey, reshuffle, rsk operations)
7+
//! - High-level API for pseudonyms and data points
8+
//! - Distributed n-PEP systems
9+
//!
10+
//! This module is only available when the `wasm` feature is enabled.
11+
12+
pub mod arithmetic;
13+
pub mod distributed;
14+
pub mod elgamal;
15+
pub mod high_level;
16+
pub mod primitives;
17+
18+
use wasm_bindgen::prelude::*;
19+
20+
/// Initialize the WASM module
21+
#[wasm_bindgen(start)]
22+
pub fn wasm_main() {
23+
// Module initialization - can be used for setup
24+
}
25+
26+
// Re-export all types from submodules for convenient access
27+
// This allows users to import directly from the main module if they prefer
28+
29+
// Arithmetic types
30+
pub use arithmetic::{WASMGroupElement, WASMScalarCanBeZero, WASMScalarNonZero};
31+
32+
// ElGamal types
33+
pub use elgamal::WASMElGamal;
34+
35+
// Primitives
36+
pub use high_level::{WASMRekeyFactor, WASMReshuffleFactor};
37+
38+
// High-level types and functions
39+
pub use high_level::{
40+
wasm_make_global_keys as make_global_keys, wasm_make_session_keys as make_session_keys,
41+
wasm_pseudonymize as pseudonymize, wasm_pseudonymize_batch as pseudonymize_batch,
42+
wasm_rekey_batch as rekey_batch, wasm_rekey_data as rekey_data,
43+
wasm_transcrypt_batch as transcrypt_batch, WASMDataPoint, WASMEncryptedDataPoint,
44+
WASMEncryptedEntityData, WASMEncryptedPseudonym, WASMEncryptionSecret, WASMGlobalKeyPair,
45+
WASMGlobalPublicKey, WASMGlobalSecretKey, WASMPseudonym, WASMPseudonymizationInfo,
46+
WASMPseudonymizationSecret, WASMRSKFactors, WASMRekeyInfo, WASMSessionKeyPair,
47+
WASMSessionPublicKey, WASMSessionSecretKey,
48+
};
49+
50+
// Distributed types
51+
pub use distributed::{
52+
wasm_make_blinded_global_secret_key as make_blinded_global_secret_key,
53+
WASMBlindedGlobalSecretKey, WASMBlindingFactor, WASMOfflinePEPClient, WASMPEPClient,
54+
WASMPEPSystem, WASMSessionKeyShare,
55+
};

0 commit comments

Comments
 (0)