From 92e01d57211ee0ef00204fd360efa42b605db361 Mon Sep 17 00:00:00 2001 From: Enjeck C Date: Mon, 2 Jun 2025 15:35:47 +0100 Subject: [PATCH 1/2] [doc] improve READMEs --- README.md | 95 +++++++++++++++++------------ python/README.md | 153 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 204 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 7ad119b..b63bfdc 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,63 @@ # liboprf -This library implements the basic OPRF(ristretto255, SHA-512) variant -from the IRTF CFRG Draft: https://github.com/cfrg/draft-irtf-cfrg-voprf/ - -Additionally it implements a threshold OPRF variant based on -https://eprint.iacr.org/2017/363 by Krawczyk et al. which is -compatible with the CFRG OPRF(ristretto255, SHA-512) variant. - -Furthermore it also implements the 3hashTDH from -https://eprint.iacr.org/2024/1455 "Threshold PAKE with Security -against Compromise of all Servers" by Gu, Jarecki, Kedzior, Nazarian, -Xu. This too is compatible with the CFRG OPRF(ristretto255, SHA-512) -variant. - -For the threshold OPRF this library also provides distributed -key-generation (DKG) implementation that is based on a trusted -party handling the broadcasts necessary for the DKG, this is -based on the JF-DKG (fig 1.) a variant on Pedersens DKG from -the paper "Secure Distributed Key Generation for Discrete-Log -Based Cryptosystems" by R. Gennaro, S. Jarecki, H. Krawczyk, -and T. Rabin. - -The semi-trusted version of the DKG implements FT-Joint-DL-VSS from fig. 7 in -R. Gennaro, M. O. Rabin, and T. Rabin. "Simplified VSS and fact-track -multiparty computations with applications to threshold cryptography" In B. A. -Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June / July 1998 - - -In order to update a threshold OPRF instantiation this library contains the -multi-party multiplication is based on Fig. 2 from R. Gennaro, M. O. Rabin, and -T. Rabin. "Simplified VSS and fact-track multiparty computations with -applications to threshold cryptography" In B. A. Coan and Y. Afek, editors, -17th ACM PODC, pages 101–111. ACM, June / July 1998. - -Additionally a python wrapper is provided, which can be installed -using `pip install pyoprf` - -This library depends on libsodium. +## Overview + +liboprf is a library for Oblivious Pseudorandom Functions (OPRFs), including support for Threshold OPRFs. It is designed to make advanced cryptographic protocols easy to integrate across applications. + +## What is an OPRF? + +An Oblivious Pseudorandom Function (OPRF) is a two-party cryptographic primitive involving a sender and receiver who jointly compute a function, `F`, in such a way that: +- The sender holds a secret key `k` +- The receiver provides an input `x` +- The receiver learns `F(k, x)` but nothing about `k` +- The sender learns nothing about `x` or `F(k, x)` + +OPRFs are the foundation for many privacy-preserving protocols including: +- Password-based authentication without exposing passwords +- Private set intersection, which allows two parties to find the intersection of their private sets without revealing the full sets +- Privacy-preserving information retrieval, allowing users to get specific information from a database without revealing what information is being retrieved + +## Features + +### Basic OPRF +liboprf implements the basic OPRF(ristretto255, SHA-512) variant from the [IRTF CFRG Draft](https://github.com/cfrg/draft-irtf-cfrg-voprf/), "Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups". + +### Threshold OPRF +liboprf implements a threshold OPRF variant based on [Krawczyk et al. (2017)](https://eprint.iacr.org/2017/363) which is compatible with the [CFRG OPRF(ristretto255, SHA-512) variant](#basic-oprf). A threshold implementation distributes trust among multiple servers, requiring a minimum number (threshold) to cooperate for operation. It uses Distributed Key Generation (DKG) protocols, as described below, to distribute secret key shares among multiple servers. + +### 3hashTDH +This library also implements the 3hashTDH from [Gu, Jarecki, Kedzior, Nazarian, Xu (2024)](https://eprint.iacr.org/2024/1455) "Threshold PAKE with Security against Compromise of all Servers". This implementation is compatible with the aforementioned [IRTF CFRG OPRF(ristretto255, SHA-512)](#basic-oprf) variant. + +### Distributed Key Generation (DKG) +For the [threshold OPRF](#threshold-oprf), liboprf provides: + +- **Trusted Party DKG**: An implementation based on Joint Feldman DKG (JF-DKG) from the paper "[Secure Distributed Key Generation for Discrete-Log Based Cryptosystems](https://link.springer.com/article/10.1007/s00145-006-0347-3)" by R. Gennaro, S. Jarecki, Hugo Krawczyk & T. Rabin. + +- **Semi-trusted DKG**: Implements Fast-Track Joint Verifiable Secret Sharing (FT-Joint-DL-VSS) described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fact-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. + +### Threshold OPRF Updates +To update a threshold OPRF instantiation, liboprf contains multi-party multiplication described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fact-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. + +## Installation + +### Dependencies +- **libsodium**: You must install [libsodium](https://github.com/jedisct1/libsodium) first. libsodium is a cryptographic library that provides a range of cryptographic operations including encryption, decryption, digital signatures, and secure password hashing. +- **pkgconf**: Needed for building the library. + +### Building from source + +```bash +git clone https://github.com/stef/liboprf.git +cd liboprf/src +make +sudo make install +``` + +### Python Wrapper +A Python wrapper, `pyoprf`, is provided. Look at [its README](/python/README.md) for installation and usage instructions. + + +## Funding This project is funded through [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the diff --git a/python/README.md b/python/README.md index 02fa505..4649b7e 100644 --- a/python/README.md +++ b/python/README.md @@ -1,16 +1,155 @@ # pyoprf -This is the python bindings for liboprf. +pyoprf offers Python bindings for the liboprf library, allowing integration of Oblivious Pseudorandom Functions (OPRFs) into Python applications. It provides access to the [features](../README.md#features) of the [liboprf](https://github.com/stef/liboprf) library. -## installation +## Installation -you'll need https://github.com/stef/liboprf/ -which depends on libsodium. -a simple `pip install pyoprf` should suffice to install the bindings. +### Prerequisites -## usage +- [liboprf](https://github.com/stef/liboprf): The core library +- [libsodium](https://github.com/jedisct1/libsodium): Required dependency for liboprf +- OpenSSL: For cryptographic functions -see the file `test.py` +### Installing from PyPI + +```bash +pip install pyoprf +``` + +### Installing from source + +```bash +git clone https://github.com/stef/liboprf.git +cd liboprf/python +pip install . +``` + +## Usage + +For detailed usage examples, refer to the [`test.py`](./tests/test.py) file and the [`examples`](/examples) folder. + +### Basic Example +Imagine a scenario where a client wants to retrieve data from a server using a password, but doesn't want to reveal the actual password to the server: + +```python +import pyoprf + +# Basic OPRF evaluation process +# Step 1: Client blinds the input value +input_value = b"password123" +blind_factor, blinded_input = pyoprf.blind(input_value) + +# Step 2: Server generates a key and evaluates the blinded input +server_key = pyoprf.keygen() +server_evaluation = pyoprf.evaluate(server_key, blinded_input) + +# Step 3: Client unblinds the server's response +unblinded_result = pyoprf.unblind(blind_factor, server_evaluation) + +# Step 4: Client finalizes the OPRF computation +final_result = pyoprf.finalize(input_value, unblinded_result) + +print(f"OPRF result: {final_result.hex()}") + +# Verify that repeated evaluations with the same key and input produce the same result +blind_factor2, blinded_input2 = pyoprf.blind(input_value) +server_evaluation2 = pyoprf.evaluate(server_key, blinded_input2) +unblinded_result2 = pyoprf.unblind(blind_factor2, server_evaluation2) +final_result2 = pyoprf.finalize(input_value, unblinded_result2) + +print(f"Verification result: {final_result2.hex()}") +assert final_result == final_result2, "OPRF evaluations should be deterministic for the same input and key" + +# The `final_result` can be used as a key for encryption, authentication token, and more. +# Both client and server can derive the same value without the server learning the password +``` + +### Threshold Example +Suppose you want to build a password authentication system that distributes trust across multiple servers, so no single server can learn a user's password. The library also supports threshold OPRFs, where multiple servers hold shares of a key: + +```python +import pyoprf + +# Setting up a threshold OPRF with 3 servers, threshold of 2 +# Server setup, which would happen on each server +n = 3 # Total number of servers +t = 2 # The minimum servers needed, also called the threshold + +# Generate a key +key = pyoprf.keygen() + +# Create shares of the key for distributed evaluation +shares = pyoprf.create_shares(key, n, t) + +# On client +input_value = b"password123" +blind_factor, blinded_input = pyoprf.blind(input_value) + +# Each server evaluates the input with its share +evaluations = [] +for i in range(n): + # This evaluation happens on server i + server_evaluation = pyoprf.evaluate(shares[i][1:], blinded_input) + evaluations.append(shares[i][:1] + server_evaluation) + +# Client combines evaluations (need at least t of them) +collected_evaluations = evaluations[:t] # Just use the first t evaluations +combined = pyoprf.thresholdmult(collected_evaluations) + +# Client unblinds the combined result +unblinded = pyoprf.unblind(blind_factor, combined) + +# Finalize to get the OPRF output +final_result = pyoprf.finalize(input_value, unblinded) +print(f"Threshold OPRF result: {final_result.hex()}") + +# Verify that it matches a direct evaluation with the key +server_evaluation = pyoprf.evaluate(key, blinded_input) +unblinded_direct = pyoprf.unblind(blind_factor, server_evaluation) +direct_result = pyoprf.finalize(input_value, unblinded_direct) +print(f"Direct OPRF result: {direct_result.hex()}") +assert final_result == direct_result, "Threshold evaluation should match direct evaluation" +``` + +## Troubleshooting + +If you encounter issues, first ensure that libsodium, liboprf and OpenSSL are properly installed. + +### OpenSSL Header Issues + +If after installing OpenSSL, you get the error `'openssl/crypto.h' file not found`, you might need to provide OpenSSL headers to the compiler. For example, if OpenSSL was installed on Mac using Homebrew: +``` +export CFLAGS="-I/opt/homebrew/opt/openssl@3/include" +export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib" +``` + +### Library Loading Issues + +When running Python code, you might encounter errors like: + +``` +OSError: liboprf.so.0: cannot open shared object file: No such file or directory +OSError: liboprf-noiseXK.so.0: cannot open shared object file: No such file or directory +``` + +To fix this, first create symbolic links: + +```bash +cd /path/to/liboprf/src +ln -s liboprf.so liboprf.so.0 +cd noise_xk +ln -s liboprf-noiseXK.so liboprf-noiseXK.so.0 +``` + +Then when running your Python code, use the LD_LIBRARY_PATH environment variable: + +```bash +LD_LIBRARY_PATH=/path/to/liboprf/src:/path/to/liboprf/src/noise_xk python your_script.py +``` + +## Documentation + +For more information on the underlying liboprf functionality, visit the [liboprf documentation](../README.md). ## License From c1ce089483bb310f72384a5b48d20dcc9399b764 Mon Sep 17 00:00:00 2001 From: Enjeck C Date: Fri, 20 Jun 2025 08:16:35 +0100 Subject: [PATCH 2/2] [doc] fix spelling --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b63bfdc..0b58c8a 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ For the [threshold OPRF](#threshold-oprf), liboprf provides: - **Trusted Party DKG**: An implementation based on Joint Feldman DKG (JF-DKG) from the paper "[Secure Distributed Key Generation for Discrete-Log Based Cryptosystems](https://link.springer.com/article/10.1007/s00145-006-0347-3)" by R. Gennaro, S. Jarecki, Hugo Krawczyk & T. Rabin. -- **Semi-trusted DKG**: Implements Fast-Track Joint Verifiable Secret Sharing (FT-Joint-DL-VSS) described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fact-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. +- **Semi-trusted DKG**: Implements Fast-Track Joint Verifiable Secret Sharing (FT-Joint-DL-VSS) described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fast-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. ### Threshold OPRF Updates -To update a threshold OPRF instantiation, liboprf contains multi-party multiplication described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fact-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. +To update a threshold OPRF instantiation, liboprf contains multi-party multiplication described in R. Gennaro, M. O. Rabin, and T. Rabin, "[Simplified VSS and fast-track multiparty computations with applications to threshold cryptography](https://dl.acm.org/doi/10.1145/277697.277716)" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages 101–111. ACM, June/July 1998. ## Installation