Skip to content

Commit

Permalink
Add VDF to sui framework (#16196)
Browse files Browse the repository at this point in the history
## Description 

This adds a VDF verifier (Wesolowski's construction based on imaginary
class groups) to the Sui framework. It can be used to generate on-chain
randomness in an 1-out-of-n trust model (see for example [this
paper](https://crypto.stanford.edu/~dabo/pubs/papers/VDFsurvey.pdf) for
an explanation).

This PR also includes an example of a lottery using VDF to generate it's
randomness.

Boilerplate code and snapshots will be added after the review.

Closing #7222.

## Test Plan 

Unit tests.

### Type of Change (Check all that apply)

- [X] protocol change
- [X] user-visible impact
- [X] breaking change for a client SDKs
- [X] breaking change for FNs (FN binary must upgrade)
- [X] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

Add verifiable delay functions (VDFs) to the Sui framework. The VDF is
based on Wesolowski's construction over imaginary class groups. Note
that this is supported in Devnet only.

---------

Co-authored-by: Todd Nowacki <tmn@mystenlabs.com>
Co-authored-by: Ashok Menon <ashok@mystenlabs.com>
  • Loading branch information
3 people authored May 27, 2024
1 parent e42c8c5 commit 7b19a35
Show file tree
Hide file tree
Showing 20 changed files with 1,031 additions and 170 deletions.
48 changes: 47 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ move-abstract-stack = { path = "external-crates/move/crates/move-abstract-stack"
fastcrypto = { git = "https://github.com/MystenLabs/fastcrypto", rev = "c101a5176799db3eb9c801b844e7add92153d291" }
fastcrypto-tbls = { git = "https://github.com/MystenLabs/fastcrypto", rev = "c101a5176799db3eb9c801b844e7add92153d291" }
fastcrypto-zkp = { git = "https://github.com/MystenLabs/fastcrypto", rev = "c101a5176799db3eb9c801b844e7add92153d291", package = "fastcrypto-zkp" }
fastcrypto-vdf = { git = "https://github.com/MystenLabs/fastcrypto", rev = "c101a5176799db3eb9c801b844e7add92153d291", features = ["experimental"] }

# anemo dependencies
anemo = { git = "https://github.com/mystenlabs/anemo.git", rev = "26d415eb9aa6a2417be3c03c57d6e93c30bd1ad7" }
Expand Down
12 changes: 6 additions & 6 deletions crates/sui-framework/docs/sui-framework/group_ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,29 @@ Generic Move and native functions for group operations.
## Constants


<a name="0x2_group_ops_EInputTooLong"></a>
<a name="0x2_group_ops_EInvalidInput"></a>



<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInputTooLong">EInputTooLong</a>: u64 = 2;
<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInvalidInput">EInvalidInput</a>: u64 = 1;
</code></pre>



<a name="0x2_group_ops_EInvalidBufferLength"></a>
<a name="0x2_group_ops_EInputTooLong"></a>



<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInvalidBufferLength">EInvalidBufferLength</a>: u64 = 3;
<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInputTooLong">EInputTooLong</a>: u64 = 2;
</code></pre>



<a name="0x2_group_ops_EInvalidInput"></a>
<a name="0x2_group_ops_EInvalidBufferLength"></a>



<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInvalidInput">EInvalidInput</a>: u64 = 1;
<pre><code><b>const</b> <a href="group_ops.md#0x2_group_ops_EInvalidBufferLength">EInvalidBufferLength</a>: u64 = 3;
</code></pre>


Expand Down
137 changes: 137 additions & 0 deletions crates/sui-framework/docs/sui-framework/vdf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
title: Module `0x2::vdf`
---



- [Constants](#@Constants_0)
- [Function `hash_to_input`](#0x2_vdf_hash_to_input)
- [Function `hash_to_input_internal`](#0x2_vdf_hash_to_input_internal)
- [Function `vdf_verify`](#0x2_vdf_vdf_verify)
- [Function `vdf_verify_internal`](#0x2_vdf_vdf_verify_internal)


<pre><code></code></pre>



<a name="@Constants_0"></a>

## Constants


<a name="0x2_vdf_EInvalidInput"></a>



<pre><code><b>const</b> <a href="vdf.md#0x2_vdf_EInvalidInput">EInvalidInput</a>: u64 = 0;
</code></pre>



<a name="0x2_vdf_hash_to_input"></a>

## Function `hash_to_input`

Hash an arbitrary binary <code>message</code> to a class group element to be used as input for <code>vdf_verify</code>.


<pre><code><b>public</b> <b>fun</b> <a href="vdf.md#0x2_vdf_hash_to_input">hash_to_input</a>(message: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="vdf.md#0x2_vdf_hash_to_input">hash_to_input</a>(message: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
<a href="vdf.md#0x2_vdf_hash_to_input_internal">hash_to_input_internal</a>(message)
}
</code></pre>



</details>

<a name="0x2_vdf_hash_to_input_internal"></a>

## Function `hash_to_input_internal`

The internal functions for <code>hash_to_input</code>.


<pre><code><b>fun</b> <a href="vdf.md#0x2_vdf_hash_to_input_internal">hash_to_input_internal</a>(message: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>native</b> <b>fun</b> <a href="vdf.md#0x2_vdf_hash_to_input_internal">hash_to_input_internal</a>(message: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;;
</code></pre>



</details>

<a name="0x2_vdf_vdf_verify"></a>

## Function `vdf_verify`

Verify the output and proof of a VDF with the given number of iterations. The <code>input</code>, <code>output</code> and <code>proof</code>
are all class group elements represented by triples <code>(a,b,c)</code> such that <code>b^2 - 4ac = discriminant</code>. The are expected
to be encoded as a BCS encoding of a triple of byte arrays, each being the big-endian twos-complement encoding of
a, b and c in that order.

This uses Wesolowski's VDF construction over imaginary class groups as described in Wesolowski (2020),
'Efficient Verifiable Delay Functions.', J. Cryptol. 33, and is compatible with the VDF implementation in
fastcrypto.

The discriminant for the class group is pre-computed and fixed. See how this was generated in the fastcrypto-vdf
crate. The final selection of the discriminant for Mainnet will be computed and announced under a nothing-up-my-sleeve
process.


<pre><code><b>public</b> <b>fun</b> <a href="vdf.md#0x2_vdf_vdf_verify">vdf_verify</a>(input: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, output: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, proof: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, iterations: u64): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="vdf.md#0x2_vdf_vdf_verify">vdf_verify</a>(input: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, output: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, proof: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, iterations: u64): bool {
<a href="vdf.md#0x2_vdf_vdf_verify_internal">vdf_verify_internal</a>(input, output, proof, iterations)
}
</code></pre>



</details>

<a name="0x2_vdf_vdf_verify_internal"></a>

## Function `vdf_verify_internal`

The internal functions for <code>vdf_verify_internal</code>.


<pre><code><b>fun</b> <a href="vdf.md#0x2_vdf_vdf_verify_internal">vdf_verify_internal</a>(input: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, output: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, proof: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, iterations: u64): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>native</b> <b>fun</b> <a href="vdf.md#0x2_vdf_vdf_verify_internal">vdf_verify_internal</a>(input: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, output: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, proof: &<a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;u8&gt;, iterations: u64): bool;
</code></pre>



</details>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module sui::vdf {

#[allow(unused_const)]
const EInvalidInput: u64 = 0;

/// Hash an arbitrary binary `message` to a class group element to be used as input for `vdf_verify`.
public fun hash_to_input(message: &vector<u8>): vector<u8> {
hash_to_input_internal(message)
}

/// The internal functions for `hash_to_input`.
native fun hash_to_input_internal(message: &vector<u8>): vector<u8>;

/// Verify the output and proof of a VDF with the given number of iterations. The `input`, `output` and `proof`
/// are all class group elements represented by triples `(a,b,c)` such that `b^2 - 4ac = discriminant`. The are expected
/// to be encoded as a BCS encoding of a triple of byte arrays, each being the big-endian twos-complement encoding of
/// a, b and c in that order.
///
/// This uses Wesolowski's VDF construction over imaginary class groups as described in Wesolowski (2020),
/// 'Efficient Verifiable Delay Functions.', J. Cryptol. 33, and is compatible with the VDF implementation in
/// fastcrypto.
///
/// The discriminant for the class group is pre-computed and fixed. See how this was generated in the fastcrypto-vdf
/// crate. The final selection of the discriminant for Mainnet will be computed and announced under a nothing-up-my-sleeve
/// process.
public fun vdf_verify(input: &vector<u8>, output: &vector<u8>, proof: &vector<u8>, iterations: u64): bool {
vdf_verify_internal(input, output, proof, iterations)
}

/// The internal functions for `vdf_verify_internal`.
native fun vdf_verify_internal(input: &vector<u8>, output: &vector<u8>, proof: &vector<u8>, iterations: u64): bool;
}
Loading

0 comments on commit 7b19a35

Please sign in to comment.