Skip to content

Commit

Permalink
- spec structure and definition of VRF.
Browse files Browse the repository at this point in the history
  • Loading branch information
drskalman committed Mar 19, 2024
1 parent e9782f9 commit 26b2778
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 2 deletions.
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.PHONY: spec-build spec-watch

OUT_MD_FILE := ./spec/specification.md
OUT_HTML_FILE := ./spec/specification.html
OUT_TEX_FILE := ./spec/specification.tex
OUT_PDF_FILE := ./spec/specification.pdf
OUT_SPEC_DIRECTORY := ./spec/

# builds the specification once
spec-build:
cargo spec build --output-file $(OUT_MD_FILE)
pandoc $(OUT_MD_FILE) --to=latex --standalone --output $(OUT_TEX_FILE)
pandoc $(OUT_TEX_FILE) --to=pdf --standalone --output $(OUT_PDF_FILE)
# this gives lots of error and does not compile corretly
# pdftex -shell-escape -output-directory $(OUT_SPEC_DIRECTORY) \\nonstopmode\\input specification.tex

# watches specification-related files and rebuilds them on the fly
spec-watch:
cargo spec watch --output-file $(OUT_MD_FILE)

spec-build-html:
cargo spec build --output-format respec --output-file $(OUT_HTML_FILE)
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# ring-vrf

Ring VRF implementation using zkSNARKs.

## Building the Specification document

The specification is built by means of [Cargo spec](https://crates.io/crates/cargo-spec) crate. To build the specification document, one can simply invoke:
```
$ cargo spec build
```
[`specification.md`](./specification.md) then shall contain the newly built specification. The specification could be easily converted to HTML by the help of `pandoc` if desired:
```
$ pandoc -f commonmark specification.md --standalone --output specification.html
```
The specification contais mathematical formula which needs to be converted to LaTeX format in order to be displayed as intended using:
```
$ pandoc -f commonmark specification.md --to=latex --standalone --output specification.tex
```
Alternatively you could simply run:
```
$ make spec-build
```
and get the specification in `./spec/specification.pdf`

Or run:
```
$ make spec-build-html
```
and get the specification in `./spec/specification.html`
21 changes: 21 additions & 0 deletions Specification.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[metadata]
name = "Ring VRF"
description = "Ring VRF implementation using zkSNARKs."
authors = ["Alistair, Jeff, Syed, Sergey"]

[config]
template = "specification_template.md"

[sections]
# DLEQ VRF
dleq-vrf-preliminaries = "dleq_vrf/src/lib.rs"
## VRF
vrf = "dleq_vrf/src/vrf.rs"
### VRF Keys
vrf-keys = "dleq_vrf/src/keys.rs"

## Thin VRF

## Pedersen VRF

# Bandersnatch VRF
7 changes: 6 additions & 1 deletion dleq_vrf/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ use crate::{
};


/// Public key
//~ #### Public key \
//~ \
//~ A Public key of a VRF is a point on an Elliptic Curve $E$. \
#[derive(Debug,Clone,Eq,Hash,CanonicalSerialize,CanonicalDeserialize)] // Copy, PartialOrd, Ord, Hash,
#[repr(transparent)]
pub struct PublicKey<C: AffineRepr>(pub C);
Expand All @@ -35,6 +37,9 @@ impl<C: AffineRepr> PartialEq for PublicKey<C> {
}
}

//~ Public key is represented in Affine form and is serialized using Arkwork compressed serialized
//~ format.
//
/// Arkworks' own serialization traits should be preferred over these.
impl<C: AffineRepr> PublicKey<C> {
pub fn update_digest(&self, h: &mut impl Update) {
Expand Down
23 changes: 22 additions & 1 deletion dleq_vrf/src/vrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
// Authors:
// - Jeffrey Burdges <jeff@web3.foundation>

//~ ## VRF
//~
//~ **Definition**: A *verifiable random function with auxiliary data (VRF-AD)* can be described with three functions:
//~
//~ - $VRF.KeyGen: () \mapsto (pk,sk)$ where $pk$ is a public key and $sk$ is its corresponding secret key.
//~ - $VRF.Sign : (sk,msg,aux) \mapsto \sigma$ takes a secret key $sk$, an input $msg$, and auxiliary data $aux$, and then returns a VRF signature $\sigma$.
//~ - $VRF.Eval : (sk, msg) \mapsto Out$ takes a secret key $sk$ and an input $msg$, and then returns a VRF output $Out$.
//~ - $VRF.Verify: (pk,msg,aux,\sigma)\mapsto (Out|prep)$ for a public key pk, an input msg, and auxiliary data aux, and then returns either an output $Out$ or else failure $perp$.
//~
//~ **Definition**: For an elliptic curve $E$ defined over finite field $F$ with large prime subgroup $G$ generated by point $g$, we call a VRF, EC-VRF is VRF-AD where $pk = sk.g$ and $VRF.Sign$ is an elliptic curve signature scheme.
//~
//~ All VRFs described in this specification are EC-VRF.

//! All VRFs expect a point on the curve as their input.
//! ### VRF input and output handling
//!
//! We caution that ring VRFs based upon DLEQ proofs like ours require
Expand All @@ -18,6 +32,14 @@ use crate::{Transcript,IntoTranscript,transcript::AsLabel,SecretKey};

use core::borrow::{Borrow}; // BorrowMut

//~ For input $msg$ and $aux$ auxilary date first we compute the $VRFInput$ which is a point on elliptic curve $E$ as follows:
//
//~ $$ VRFiput := H2C(ArkTranscript(msg, aux) $$
//~
//~ where
//~ - $ArkTranscript$ function is described in [[ark-transcript]] section.
//~ - $H2C: B \rightarrow G$ is a hash to curve function correspond to curve $E$ specified in Section [[hash-to-curve]] for the specific choice of $E$
//~
/// Create VRF input points
///
/// You select your own hash-to-curve by implementing this trait
Expand Down Expand Up @@ -108,7 +130,6 @@ impl<K: AffineRepr> SecretKey<K> {
}
}


/// VRF pre-output, possibly unverified.
#[derive(Debug,Copy,Clone,PartialEq,Eq,CanonicalSerialize,CanonicalDeserialize)] // Copy, Default, PartialOrd, Ord, Hash
#[repr(transparent)]
Expand Down
84 changes: 84 additions & 0 deletions spec/specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Ring VRF

## VRF

**Definition**: A *verifiable random function with auxiliary data (VRF-AD)* can be described with three functions:

- $VRF.KeyGen: () \mapsto (pk,sk)$ where $pk$ is a public key and $sk$ is its corresponding secret key.
- $VRF.Sign : (sk,msg,aux) \mapsto \sigma$ takes a secret key $sk$, an input $msg$, and auxiliary data $aux$, and then returns a VRF signature $\sigma$.
- $VRF.Eval : (sk, msg) \mapsto Out$ takes a secret key $sk$ and an input $msg$, and then returns a VRF output $Out$.
- $VRF.Verify: (pk,msg,aux,\sigma)\mapsto (Out|prep)$ for a public key pk, an input msg, and auxiliary data aux, and then returns either an output $Out$ or else failure $perp$.

**Definition**: For an elliptic curve $E$ defined over finite field $F$ with large prime subgroup $G$ generated by point $g$, we call a VRF, EC-VRF is VRF-AD where $pk = sk.g$ and $VRF.Sign$ is an elliptic curve signature scheme.

All VRFs described in this specification are EC-VRF.
For input $msg$ and $aux$ auxilary date first we compute the $VRFInput$ which is a point on elliptic curve $E$ as follows:
$$ VRFiput := H2C(ArkTranscript(msg, aux) $$

where
- $ArkTranscript$ function is described in [[ark-transcript]] section.
- $H2C: B \rightarrow G$ is a hash to curve function correspond to curve $E$ specified in Section [[hash-to-curve]] for the specific choice of $E$




### Preliminaries


### VRF Key
#### Public key \
\
A Public key of a VRF is a point on an Elliptic Curve $E$. \
Public key is represented in Affine form and is serialized using Arkwork compressed serialized
format.


### VRF input

VRF input is an ArkTranscript. See ArkTranscript

#### From transcript to point

You need to call challenge and add b"vrf-input" to it. getting random byte (some hash?)
then hash to curve it.


## DELQ VRF
### Preliminaries
Implements the two relevant verifiable random functions (VRFs) with
associated data (VRF-ADs) which arise from Chaum-Pedersen DLEQ proofs,
polymorphic over Arkworks' elliptic curves.

Thin VRF aka `ThinVrf` provides a regular VRF similar but broadly superior
to ["EC VRF"](https://www.ietf.org/id/draft-irtf-cfrg-vrf-15.html).
Thin VRF support batch verification or half-aggregation exactly like
Schnorr signatures, but which ECVRF lacks.
In essence, thin VRF *is* a Schnorr signature with base point given by
a pseudo-random (Fiat-Shamir) linear combination of base points, while
EC VRF is two linked Schnorr signatures on distinct base points.
Thin VRF should be slightly faster than EC VRF, be similarly sized on
typical Edwards curves, but slightly larger on larger BLS12 curves.
As a rule, new applications should always prefer thin VRF over EC VRF.

Pedersen VRF aka `PedersenVRF` resembles EC VRF but replaces the
public key by a Pedersen commitment to the secret key, which makes the
Pedersen VRF useful in anonymized ring VRFs, or perhaps group VRFs.
We provide both batchable and nonbatchable forms of the Pedresen VRF.
We favor the batchable form because our blinding factors enlarge our
signatures anyways, making the batchable form less significant
proportionally than batchable forms of EV VRF.

As the Pedersen VRF needs two verification equations, we support
DLEQ proofs between two distinct curves provided both have the same
subgroup order. Around this, we support omitting the blinding factors
for cross curve DLEQ proofs, like proving public keys on G1 and G2
of a BLS12 curve have the same secret key.



### Thin VRF

### Pedersen VRF

## Bandersnatch VRF

60 changes: 60 additions & 0 deletions specification_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Ring VRF

{sections.vrf}


### Preliminaries


### VRF Key
{sections.vrf-keys}

### VRF input

VRF input is an ArkTranscript. See ArkTranscript

#### From transcript to point

You need to call challenge and add b"vrf-input" to it. getting random byte (some hash?)
then hash to curve it.


## DELQ VRF
### Preliminaries
Implements the two relevant verifiable random functions (VRFs) with
associated data (VRF-ADs) which arise from Chaum-Pedersen DLEQ proofs,
polymorphic over Arkworks' elliptic curves.

Thin VRF aka `ThinVrf` provides a regular VRF similar but broadly superior
to ["EC VRF"](https://www.ietf.org/id/draft-irtf-cfrg-vrf-15.html).
Thin VRF support batch verification or half-aggregation exactly like
Schnorr signatures, but which ECVRF lacks.
In essence, thin VRF *is* a Schnorr signature with base point given by
a pseudo-random (Fiat-Shamir) linear combination of base points, while
EC VRF is two linked Schnorr signatures on distinct base points.
Thin VRF should be slightly faster than EC VRF, be similarly sized on
typical Edwards curves, but slightly larger on larger BLS12 curves.
As a rule, new applications should always prefer thin VRF over EC VRF.

Pedersen VRF aka `PedersenVRF` resembles EC VRF but replaces the
public key by a Pedersen commitment to the secret key, which makes the
Pedersen VRF useful in anonymized ring VRFs, or perhaps group VRFs.
We provide both batchable and nonbatchable forms of the Pedresen VRF.
We favor the batchable form because our blinding factors enlarge our
signatures anyways, making the batchable form less significant
proportionally than batchable forms of EV VRF.

As the Pedersen VRF needs two verification equations, we support
DLEQ proofs between two distinct curves provided both have the same
subgroup order. Around this, we support omitting the blinding factors
for cross curve DLEQ proofs, like proving public keys on G1 and G2
of a BLS12 curve have the same secret key.


{sections.dleq-vrf-preliminaries}
### Thin VRF

### Pedersen VRF

## Bandersnatch VRF

0 comments on commit 26b2778

Please sign in to comment.