Skip to content

Commit

Permalink
updating to voprf draft v20 (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
aldenml authored Feb 18, 2023
1 parent dae7c10 commit 80a1349
Show file tree
Hide file tree
Showing 20 changed files with 747 additions and 363 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2021-2022 Alden Torres
Copyright (c) 2021-2023 Alden Torres

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
43 changes: 23 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ecc
# elliptic-curve cryptography

[![macOS](https://github.com/aldenml/ecc/actions/workflows/macos.yml/badge.svg?branch=master)](https://github.com/aldenml/ecc/actions/workflows/macos.yml)
[![Linux](https://github.com/aldenml/ecc/actions/workflows/linux.yml/badge.svg?branch=master)](https://github.com/aldenml/ecc/actions/workflows/linux.yml)
Expand All @@ -19,50 +19,53 @@ and [blst](https://github.com/supranational/blst).
|------------|----------------------------------|---|
| Java | [jvm/ecc](bindings/jvm) | [![maven](https://img.shields.io/maven-central/v/org.ssohub/ecc.svg?label=maven)](https://search.maven.org/search?q=g:%22org.ssohub%22%20AND%20a:%22ecc%22) |
| Javascript | [js/ecc](bindings/js) | [![npm](https://img.shields.io/npm/v/@aldenml/ecc)](https://www.npmjs.com/package/@aldenml/ecc) |
| Python | [python/libecc](bindings/python) | [![PyPI version](https://badge.fury.io/py/libecc.svg)](https://badge.fury.io/py/libecc) |

### Features

- [OPRF](#oprf-oblivious-pseudo-random-functions-using-ristretto255)
- [OPRF](#oprf-oblivious-pseudo-random-functions)
- [OPAQUE](#opaque-the-opaque-asymmetric-pake-protocol)
- [Two-Round Threshold Schnorr Signatures with FROST](#two-round-threshold-schnorr-signatures-with-frost)
- [Ethereum BLS Signature](#ethereum-bls-signature)
- [BLS12-381 Pairing](#bls12-381-pairing)
- [Proxy Re-Encryption (PRE)](#proxy-re-encryption-pre)

### OPRF Oblivious pseudo-random functions using ristretto255
### OPRF Oblivious pseudo-random functions

This is an implementation of [draft-irtf-cfrg-voprf-16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-16)
This is an implementation of [draft-irtf-cfrg-voprf-20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-20)
ciphersuite **OPRF(ristretto255, SHA-512)** using `libsodium`.

There are two variants in this protocol: a *base* mode and *verifiable* mode. In the
base mode, a client and server interact to compute `output = F(skS, input, info)`,
where `input` is the client's private input, `skS` is the server's private key, `info`
is the public input, and `output` is the computation output. The client learns `output`
and the server learns nothing. In the verifiable mode, the client also receives proof
that the server used `skS` in computing the function.
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol between client
and server for computing the output of a Pseudorandom Function (PRF). The server
provides the PRF secret key, and the client provides the PRF input. At the end
of the protocol, the client learns the PRF output without learning anything
about the PRF secret key, and the server learns neither the PRF input nor
output.

The flow is shown below (from the IRTF draft):
There are two variations of the basic protocol:

- VOPRF: is OPRF with the notion of verifiability. Clients can verify that the
server used a specific private key during the execution of the protocol.
- POPRF: is a partially-oblivious VOPRF that allows clients and servers to
provide public input to the PRF computation.

The OPRF flow is shown below (from the IRTF draft):
```
Client(input, info) Server(skS, info)
----------------------------------------------------------------------
Client(input) Server(skS)
-------------------------------------------------------------------
blind, blindedElement = Blind(input)
blindedElement
---------->
evaluatedElement = Evaluate(skS, blindedElement, info)
evaluatedElement = BlindEvaluate(skS, blindedElement)
evaluatedElement
<----------
output = Finalize(input, blind, evaluatedElement, blindedElement, info)
output = Finalize(input, blind, evaluatedElement)
```

In the verifiable mode of the protocol, the server additionally
computes a proof in `Evaluate`. The client verifies this proof using
the server's expected public key before completing the protocol and
producing the protocol output.
For the advanced modes VOPRF and POPRF refer to the published draft.

### OPAQUE The OPAQUE Asymmetric PAKE Protocol

Expand Down
40 changes: 22 additions & 18 deletions bindings/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,50 @@ top to expose the cryptographic primitives.

### Features

- [OPRF](#oprf-oblivious-pseudo-random-functions-using-ristretto255)
- [OPRF](#oprf-oblivious-pseudo-random-functions)
- [OPAQUE](#opaque-the-opaque-asymmetric-pake-protocol)
- [Two-Round Threshold Schnorr Signatures with FROST](#two-round-threshold-schnorr-signatures-with-frost)
- [Ethereum BLS Signature](#ethereum-bls-signature)
- [BLS12-381 Pairing](#bls12-381-pairing)
- [Proxy Re-Encryption (PRE)](#proxy-re-encryption-pre)

### OPRF Oblivious pseudo-random functions using ristretto255
### OPRF Oblivious pseudo-random functions

This is an implementation of [draft-irtf-cfrg-voprf-16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-16)
This is an implementation of [draft-irtf-cfrg-voprf-20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-20)
ciphersuite **OPRF(ristretto255, SHA-512)** using `libsodium`.

There are two variants in this protocol: a *base* mode and *verifiable* mode. In the
base mode, a client and server interact to compute `output = F(skS, input, info)`,
where `input` is the client's private input, `skS` is the server's private key, `info`
is the public input, and `output` is the computation output. The client learns `output`
and the server learns nothing. In the verifiable mode, the client also receives proof
that the server used `skS` in computing the function.
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol between client
and server for computing the output of a Pseudorandom Function (PRF). The server
provides the PRF secret key, and the client provides the PRF input. At the end
of the protocol, the client learns the PRF output without learning anything
about the PRF secret key, and the server learns neither the PRF input nor
output.

The flow is shown below (from the irtf draft):
There are two variations of the basic protocol:

- VOPRF: is OPRF with the notion of verifiability. Clients can verify that the
server used a specific private key during the execution of the protocol.
- POPRF: is a partially-oblivious VOPRF that allows clients and servers to
provide public input to the PRF computation.

The OPRF flow is shown below (from the IRTF draft):
```
Client(input, info) Server(skS, info)
----------------------------------------------------------------------
Client(input) Server(skS)
-------------------------------------------------------------------
blind, blindedElement = Blind(input)
blindedElement
---------->
evaluatedElement = Evaluate(skS, blindedElement, info)
evaluatedElement = BlindEvaluate(skS, blindedElement)
evaluatedElement
<----------
output = Finalize(input, blind, evaluatedElement, blindedElement, info)
output = Finalize(input, blind, evaluatedElement)
```

In the verifiable mode of the protocol, the server additionally
computes a proof in Evaluate. The client verifies this proof using
the server's expected public key before completing the protocol and
producing the protocol output.
For the advanced modes VOPRF and POPRF refer to the published draft.

### OPAQUE The OPAQUE Asymmetric PAKE Protocol

Expand Down
81 changes: 61 additions & 20 deletions bindings/js/libecc-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -2134,7 +2134,7 @@ Module.ecc_voprf_ristretto255_sha512_SCALARSIZE = ecc_voprf_ristretto255_sha512_

const ecc_voprf_ristretto255_sha512_PROOFSIZE = 64;
/**
* Size of a proof. Proof is a sequence of two scalars.
* Size of a proof. Proof is a tuple of two scalars.
*
* @type {number}
*/
Expand Down Expand Up @@ -2185,7 +2185,11 @@ const ecc_voprf_ristretto255_sha512_MAXINFOSIZE = 2000;
Module.ecc_voprf_ristretto255_sha512_MAXINFOSIZE = ecc_voprf_ristretto255_sha512_MAXINFOSIZE;

/**
*
* Generates a proof using the specified scalar. Given elements A and B, two
* non-empty lists of elements C and D of length m, and a scalar k; this
* function produces a proof that k*A == B and k*C[i] == D[i] for each i in
* [0, ..., m - 1]. The output is a value of type Proof, which is a tuple of two
* scalar values.
*
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
* @param {Uint8Array} k size:ecc_voprf_ristretto255_sha512_SCALARSIZE
Expand Down Expand Up @@ -2237,7 +2241,11 @@ Module.ecc_voprf_ristretto255_sha512_GenerateProofWithScalar = (
}

/**
*
* Generates a proof. Given elements A and B, two
* non-empty lists of elements C and D of length m, and a scalar k; this
* function produces a proof that k*A == B and k*C[i] == D[i] for each i in
* [0, ..., m - 1]. The output is a value of type Proof, which is a tuple of two
* scalar values.
*
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
* @param {Uint8Array} k size:ecc_voprf_ristretto255_sha512_SCALARSIZE
Expand Down Expand Up @@ -2284,7 +2292,9 @@ Module.ecc_voprf_ristretto255_sha512_GenerateProof = (
}

/**
*
* Helper function used in GenerateProof. It is an optimization of the
* ComputeComposites function for servers since they have knowledge of the
* private key.
*
* @param {Uint8Array} M (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} Z (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2332,7 +2342,11 @@ Module.ecc_voprf_ristretto255_sha512_ComputeCompositesFast = (
}

/**
*
* This function takes elements A and B, two non-empty lists of elements C and D
* of length m, and a Proof value output from GenerateProof. It outputs a single
* boolean value indicating whether or not the proof is valid for the given DLEQ
* inputs. Note this function can verify proofs on lists of inputs whenever the
* proof was generated as a batched DLEQ proof with the same inputs.
*
* @param {Uint8Array} A size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} B size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2375,7 +2389,7 @@ Module.ecc_voprf_ristretto255_sha512_VerifyProof = (
}

/**
*
* Helper function used in `VerifyProof`.
*
* @param {Uint8Array} M (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} Z (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2519,7 +2533,8 @@ Module.ecc_voprf_ristretto255_sha512_BlindWithScalar = (
}

/**
*
* The OPRF protocol begins with the client blinding its input. Note that this
* function can fail for certain inputs that map to the group identity element.
*
* @param {Uint8Array} blind (output) scalar used in the blind operation, size:ecc_voprf_ristretto255_sha512_SCALARSIZE
* @param {Uint8Array} blindedElement (output) blinded element, size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2554,7 +2569,8 @@ Module.ecc_voprf_ristretto255_sha512_Blind = (
}

/**
*
* Clients store blind locally, and send blindedElement to the server for
* evaluation. Upon receipt, servers process blindedElement using this function.
*
* @param {Uint8Array} evaluatedElement (output) blinded element, size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} skS scalar used in the blind operation, size:ecc_voprf_ristretto255_sha512_SCALARSIZE
Expand All @@ -2580,7 +2596,11 @@ Module.ecc_voprf_ristretto255_sha512_BlindEvaluate = (
}

/**
*
* Servers send the output evaluatedElement to clients for processing. Recall
* that servers may process multiple client inputs by applying the BlindEvaluate
* function to each blindedElement received, and returning an array with the
* corresponding evaluatedElement values. Upon receipt of evaluatedElement,
* clients process it to complete the OPRF evaluation with this function.
*
* @param {Uint8Array} output (output) size:ecc_voprf_ristretto255_sha512_Nh
* @param {Uint8Array} input the input message, size:inputLen
Expand Down Expand Up @@ -2614,7 +2634,8 @@ Module.ecc_voprf_ristretto255_sha512_Finalize = (
}

/**
*
* An entity which knows both the secret key and the input can compute the PRF
* result using this function.
*
* @param {Uint8Array} output (output) size:ecc_voprf_ristretto255_sha512_Nh
* @param {Uint8Array} skS size:ecc_voprf_ristretto255_sha512_SCALARSIZE
Expand Down Expand Up @@ -2648,7 +2669,8 @@ Module.ecc_voprf_ristretto255_sha512_Evaluate = (
}

/**
*
* Same as calling ecc_voprf_ristretto255_sha512_VerifiableBlindEvaluate but
* using an specified scalar `r`.
*
* @param {Uint8Array} evaluatedElement (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
Expand Down Expand Up @@ -2690,7 +2712,10 @@ Module.ecc_voprf_ristretto255_sha512_VerifiableBlindEvaluateWithScalar = (
}

/**
*
* The VOPRF protocol begins with the client blinding its input. Clients store
* the output blind locally and send blindedElement to the server for
* evaluation. Upon receipt, servers process blindedElement to compute an
* evaluated element and DLEQ proof using this function.
*
* @param {Uint8Array} evaluatedElement (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
Expand Down Expand Up @@ -2727,7 +2752,9 @@ Module.ecc_voprf_ristretto255_sha512_VerifiableBlindEvaluate = (
}

/**
*
* The server sends both evaluatedElement and proof back to the client. Upon
* receipt, the client processes both values to complete the VOPRF computation
* using this function below.
*
* @param {Uint8Array} output (output) size:ecc_voprf_ristretto255_sha512_Nh
* @param {Uint8Array} input the input message, size:inputLen
Expand Down Expand Up @@ -2778,7 +2805,8 @@ Module.ecc_voprf_ristretto255_sha512_VerifiableFinalize = (
}

/**
*
* Same as calling ecc_voprf_ristretto255_sha512_PartiallyBlind with an
* specified blind scalar.
*
* @param {Uint8Array} blindedElement (output) blinded element, size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} tweakedKey (output) blinded element, size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2830,7 +2858,12 @@ Module.ecc_voprf_ristretto255_sha512_PartiallyBlindWithScalar = (
}

/**
*
* The POPRF protocol begins with the client blinding its input, using the
* following modified Blind function. In this step, the client also binds a
* public info value, which produces an additional tweakedKey to be used later
* in the protocol. Note that this function can fail for certain private inputs
* that map to the group identity element, as well as certain public inputs
* that, if not detected at this point, will cause server evaluation to fail.
*
* @param {Uint8Array} blind (output) scalar used in the blind operation, size:ecc_voprf_ristretto255_sha512_SCALARSIZE
* @param {Uint8Array} blindedElement (output) blinded element, size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
Expand Down Expand Up @@ -2883,7 +2916,8 @@ Module.ecc_voprf_ristretto255_sha512_PartiallyBlind = (
}

/**
*
* Same as calling ecc_voprf_ristretto255_sha512_PartiallyBlindEvaluate with an
* specified scalar r.
*
* @param {Uint8Array} evaluatedElement (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
Expand Down Expand Up @@ -2932,7 +2966,10 @@ Module.ecc_voprf_ristretto255_sha512_PartiallyBlindEvaluateWithScalar = (
}

/**
*
* Clients store the outputs blind and tweakedKey locally and send
* blindedElement to the server for evaluation. Upon receipt, servers process
* blindedElement to compute an evaluated element and DLEQ proof using the
* this function.
*
* @param {Uint8Array} evaluatedElement (output) size:ecc_voprf_ristretto255_sha512_ELEMENTSIZE
* @param {Uint8Array} proof (output) size:ecc_voprf_ristretto255_sha512_PROOFSIZE
Expand Down Expand Up @@ -2976,7 +3013,9 @@ Module.ecc_voprf_ristretto255_sha512_PartiallyBlindEvaluate = (
}

/**
*
* The server sends both evaluatedElement and proof back to the client. Upon
* receipt, the client processes both values to complete the POPRF computation
* using this function.
*
* @param {Uint8Array} output (output) size:ecc_voprf_ristretto255_sha512_Nh
* @param {Uint8Array} input the input message, size:inputLen
Expand Down Expand Up @@ -3140,7 +3179,8 @@ Module.ecc_voprf_ristretto255_sha512_HashToGroup = (
}

/**
*
* Same as calling ecc_voprf_ristretto255_sha512_HashToScalar with an specified
* DST.
*
* @param {Uint8Array} out (output) size:ecc_voprf_ristretto255_sha512_SCALARSIZE
* @param {Uint8Array} input size:inputLen
Expand Down Expand Up @@ -3172,7 +3212,8 @@ Module.ecc_voprf_ristretto255_sha512_HashToScalarWithDST = (
}

/**
*
* Deterministically maps an array of bytes x to an element in GF(p) in
* the ristretto255 curve.
*
* @param {Uint8Array} out (output) size:ecc_voprf_ristretto255_sha512_SCALARSIZE
* @param {Uint8Array} input size:inputLen
Expand Down
2 changes: 1 addition & 1 deletion bindings/js/libecc.js

Large diffs are not rendered by default.

Loading

0 comments on commit 80a1349

Please sign in to comment.