Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BN254 groth16 verifier #9196

Merged
merged 18 commits into from
Mar 14, 2023
128 changes: 122 additions & 6 deletions crates/sui-framework/docs/groth16.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@



- [Struct `Curve`](#0x2_groth16_Curve)
- [Struct `PreparedVerifyingKey`](#0x2_groth16_PreparedVerifyingKey)
- [Struct `PublicProofInputs`](#0x2_groth16_PublicProofInputs)
- [Struct `ProofPoints`](#0x2_groth16_ProofPoints)
- [Constants](#@Constants_0)
- [Function `bls12381`](#0x2_groth16_bls12381)
- [Function `bn254`](#0x2_groth16_bn254)
- [Function `pvk_from_bytes`](#0x2_groth16_pvk_from_bytes)
- [Function `pvk_to_bytes`](#0x2_groth16_pvk_to_bytes)
- [Function `public_proof_inputs_from_bytes`](#0x2_groth16_public_proof_inputs_from_bytes)
- [Function `proof_points_from_bytes`](#0x2_groth16_proof_points_from_bytes)
- [Function `prepare_verifying_key`](#0x2_groth16_prepare_verifying_key)
- [Function `prepare_verifying_key_internal`](#0x2_groth16_prepare_verifying_key_internal)
- [Function `verify_groth16_proof`](#0x2_groth16_verify_groth16_proof)
- [Function `verify_groth16_proof_internal`](#0x2_groth16_verify_groth16_proof_internal)

Expand All @@ -22,6 +26,35 @@



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

## Struct `Curve`

Represents an elliptic curve construction to be used in the verifier. Currently we support BLS12-381 and BN254.
This should be given as the first parameter to <code>prepare_verifying_key</code> or <code>verify_groth16_proof</code>.


<pre><code><b>struct</b> <a href="groth16.md#0x2_groth16_Curve">Curve</a> <b>has</b> <b>copy</b>, drop, store
</code></pre>



<details>
<summary>Fields</summary>


<dl>
<dt>
<code>id: u8</code>
</dt>
<dd>

</dd>
</dl>


</details>

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

## Struct `PreparedVerifyingKey`
Expand Down Expand Up @@ -129,6 +162,15 @@ A <code><a href="groth16.md#0x2_groth16_ProofPoints">ProofPoints</a></code> wrap
## Constants


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



<pre><code><b>const</b> <a href="groth16.md#0x2_groth16_EInvalidCurve">EInvalidCurve</a>: u64 = 1;
</code></pre>



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


Expand All @@ -138,6 +180,52 @@ A <code><a href="groth16.md#0x2_groth16_ProofPoints">ProofPoints</a></code> wrap



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

## Function `bls12381`

Return the <code><a href="groth16.md#0x2_groth16_Curve">Curve</a></code> value indicating that the BLS12-381 construction should be used in a given function.


<pre><code><b>public</b> <b>fun</b> <a href="bls12381.md#0x2_bls12381">bls12381</a>(): <a href="groth16.md#0x2_groth16_Curve">groth16::Curve</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="bls12381.md#0x2_bls12381">bls12381</a>(): <a href="groth16.md#0x2_groth16_Curve">Curve</a> { <a href="groth16.md#0x2_groth16_Curve">Curve</a> { id: 0 } }
</code></pre>



</details>

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

## Function `bn254`

Return the <code><a href="groth16.md#0x2_groth16_Curve">Curve</a></code> value indicating that the BN254 construction should be used in a given function.


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_bn254">bn254</a>(): <a href="groth16.md#0x2_groth16_Curve">groth16::Curve</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_bn254">bn254</a>(): <a href="groth16.md#0x2_groth16_Curve">Curve</a> { <a href="groth16.md#0x2_groth16_Curve">Curve</a> { id: 1 } }
</code></pre>



</details>

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

## Function `pvk_from_bytes`
Expand Down Expand Up @@ -252,14 +340,40 @@ Creates a Groth16 <code><a href="groth16.md#0x2_groth16_ProofPoints">ProofPoints

## Function `prepare_verifying_key`

@param curve: What elliptic curve construction to use. See <code><a href="bls12381.md#0x2_bls12381">bls12381</a></code> and <code>bn254</code>.
@param veriyfing_key: An Arkworks canonical compressed serialization of a verifying key.

Returns four vectors of bytes representing the four components of a prepared verifying key.
This step computes one pairing e(P, Q), and binds the verification to one particular proof statement.
This can be used as inputs for the <code>verify_groth16_proof</code> function.


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key">prepare_verifying_key</a>(verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">groth16::PreparedVerifyingKey</a>
<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key">prepare_verifying_key</a>(curve: &<a href="groth16.md#0x2_groth16_Curve">groth16::Curve</a>, verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">groth16::PreparedVerifyingKey</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key">prepare_verifying_key</a>(curve: &<a href="groth16.md#0x2_groth16_Curve">Curve</a>, verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">PreparedVerifyingKey</a> {
<a href="groth16.md#0x2_groth16_prepare_verifying_key_internal">prepare_verifying_key_internal</a>(curve.id, verifying_key)
}
</code></pre>



</details>

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

## Function `prepare_verifying_key_internal`

Native functions that flattens the inputs into an array and passes to the Rust native function.


<pre><code><b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key_internal">prepare_verifying_key_internal</a>(curve: u8, verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">groth16::PreparedVerifyingKey</a>
</code></pre>


Expand All @@ -268,7 +382,7 @@ This can be used as inputs for the <code>verify_groth16_proof</code> function.
<summary>Implementation</summary>


<pre><code><b>public</b> <b>native</b> <b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key">prepare_verifying_key</a>(verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">PreparedVerifyingKey</a>;
<pre><code><b>native</b> <b>fun</b> <a href="groth16.md#0x2_groth16_prepare_verifying_key_internal">prepare_verifying_key_internal</a>(curve: u8, verifying_key: &<a href="">vector</a>&lt;u8&gt;): <a href="groth16.md#0x2_groth16_PreparedVerifyingKey">PreparedVerifyingKey</a>;
</code></pre>


Expand All @@ -292,14 +406,15 @@ This can be used as inputs for the <code>verify_groth16_proof</code> function.

## Function `verify_groth16_proof`

@param curve: What elliptic curve construction to use. See the <code><a href="bls12381.md#0x2_bls12381">bls12381</a></code> and <code>bn254</code> functions.
@param prepared_verifying_key: Consists of four vectors of bytes representing the four components of a prepared verifying key.
@param public_proof_inputs: Represent inputs that are public.
@param proof_points: Represent three proof points.

Returns a boolean indicating whether the proof is valid.


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof">verify_groth16_proof</a>(prepared_verifying_key: &<a href="groth16.md#0x2_groth16_PreparedVerifyingKey">groth16::PreparedVerifyingKey</a>, public_proof_inputs: &<a href="groth16.md#0x2_groth16_PublicProofInputs">groth16::PublicProofInputs</a>, proof_points: &<a href="groth16.md#0x2_groth16_ProofPoints">groth16::ProofPoints</a>): bool
<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof">verify_groth16_proof</a>(curve: &<a href="groth16.md#0x2_groth16_Curve">groth16::Curve</a>, prepared_verifying_key: &<a href="groth16.md#0x2_groth16_PreparedVerifyingKey">groth16::PreparedVerifyingKey</a>, public_proof_inputs: &<a href="groth16.md#0x2_groth16_PublicProofInputs">groth16::PublicProofInputs</a>, proof_points: &<a href="groth16.md#0x2_groth16_ProofPoints">groth16::ProofPoints</a>): bool
</code></pre>


Expand All @@ -308,8 +423,9 @@ Returns a boolean indicating whether the proof is valid.
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof">verify_groth16_proof</a>(prepared_verifying_key: &<a href="groth16.md#0x2_groth16_PreparedVerifyingKey">PreparedVerifyingKey</a>, public_proof_inputs: &<a href="groth16.md#0x2_groth16_PublicProofInputs">PublicProofInputs</a>, proof_points: &<a href="groth16.md#0x2_groth16_ProofPoints">ProofPoints</a>): bool {
<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof">verify_groth16_proof</a>(curve: &<a href="groth16.md#0x2_groth16_Curve">Curve</a>, prepared_verifying_key: &<a href="groth16.md#0x2_groth16_PreparedVerifyingKey">PreparedVerifyingKey</a>, public_proof_inputs: &<a href="groth16.md#0x2_groth16_PublicProofInputs">PublicProofInputs</a>, proof_points: &<a href="groth16.md#0x2_groth16_ProofPoints">ProofPoints</a>): bool {
<a href="groth16.md#0x2_groth16_verify_groth16_proof_internal">verify_groth16_proof_internal</a>(
curve.id,
&prepared_verifying_key.vk_gamma_abc_g1_bytes,
&prepared_verifying_key.alpha_g1_beta_g2_bytes,
&prepared_verifying_key.gamma_g2_neg_pc_bytes,
Expand All @@ -331,7 +447,7 @@ Returns a boolean indicating whether the proof is valid.
Native functions that flattens the inputs into arrays of vectors and passed to the Rust native function.


<pre><code><b>public</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof_internal">verify_groth16_proof_internal</a>(vk_gamma_abc_g1_bytes: &<a href="">vector</a>&lt;u8&gt;, alpha_g1_beta_g2_bytes: &<a href="">vector</a>&lt;u8&gt;, gamma_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, delta_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, public_proof_inputs: &<a href="">vector</a>&lt;u8&gt;, proof_points: &<a href="">vector</a>&lt;u8&gt;): bool
<pre><code><b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof_internal">verify_groth16_proof_internal</a>(curve: u8, vk_gamma_abc_g1_bytes: &<a href="">vector</a>&lt;u8&gt;, alpha_g1_beta_g2_bytes: &<a href="">vector</a>&lt;u8&gt;, gamma_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, delta_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, public_proof_inputs: &<a href="">vector</a>&lt;u8&gt;, proof_points: &<a href="">vector</a>&lt;u8&gt;): bool
</code></pre>


Expand All @@ -340,7 +456,7 @@ Native functions that flattens the inputs into arrays of vectors and passed to t
<summary>Implementation</summary>


<pre><code><b>public</b> <b>native</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof_internal">verify_groth16_proof_internal</a>(vk_gamma_abc_g1_bytes: &<a href="">vector</a>&lt;u8&gt;, alpha_g1_beta_g2_bytes: &<a href="">vector</a>&lt;u8&gt;, gamma_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, delta_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, public_proof_inputs: &<a href="">vector</a>&lt;u8&gt;, proof_points: &<a href="">vector</a>&lt;u8&gt;): bool;
<pre><code><b>native</b> <b>fun</b> <a href="groth16.md#0x2_groth16_verify_groth16_proof_internal">verify_groth16_proof_internal</a>(curve: u8, vk_gamma_abc_g1_bytes: &<a href="">vector</a>&lt;u8&gt;, alpha_g1_beta_g2_bytes: &<a href="">vector</a>&lt;u8&gt;, gamma_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, delta_g2_neg_pc_bytes: &<a href="">vector</a>&lt;u8&gt;, public_proof_inputs: &<a href="">vector</a>&lt;u8&gt;, proof_points: &<a href="">vector</a>&lt;u8&gt;): bool;
</code></pre>


Expand Down
29 changes: 26 additions & 3 deletions crates/sui-framework/sources/crypto/groth16.move
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ module sui::groth16 {
// Error for input is not a valid Arkwork representation of a verifying key.
const EInvalidVerifyingKey: u64 = 0;

// Error if the given curve is not supported
const EInvalidCurve: u64 = 1;

/// Represents an elliptic curve construction to be used in the verifier. Currently we support BLS12-381 and BN254.
/// This should be given as the first parameter to `prepare_verifying_key` or `verify_groth16_proof`.
struct Curve has store, copy, drop {
id: u8,
}

/// Return the `Curve` value indicating that the BLS12-381 construction should be used in a given function.
public fun bls12381(): Curve { Curve { id: 0 } }

/// Return the `Curve` value indicating that the BN254 construction should be used in a given function.
public fun bn254(): Curve { Curve { id: 1 } }

/// A `PreparedVerifyingKey` consisting of four components in serialized form.
struct PreparedVerifyingKey has store, copy, drop {
vk_gamma_abc_g1_bytes: vector<u8>,
Expand Down Expand Up @@ -55,20 +70,28 @@ module sui::groth16 {
ProofPoints { bytes }
}

jonas-lj marked this conversation as resolved.
Show resolved Hide resolved
/// @param curve: What elliptic curve construction to use. See `bls12381` and `bn254`.
/// @param veriyfing_key: An Arkworks canonical compressed serialization of a verifying key.
///
/// Returns four vectors of bytes representing the four components of a prepared verifying key.
/// This step computes one pairing e(P, Q), and binds the verification to one particular proof statement.
/// This can be used as inputs for the `verify_groth16_proof` function.
public native fun prepare_verifying_key(verifying_key: &vector<u8>): PreparedVerifyingKey;
public fun prepare_verifying_key(curve: &Curve, verifying_key: &vector<u8>): PreparedVerifyingKey {
prepare_verifying_key_internal(curve.id, verifying_key)
}

/// Native functions that flattens the inputs into an array and passes to the Rust native function.
native fun prepare_verifying_key_internal(curve: u8, verifying_key: &vector<u8>): PreparedVerifyingKey;

/// @param curve: What elliptic curve construction to use. See the `bls12381` and `bn254` functions.
/// @param prepared_verifying_key: Consists of four vectors of bytes representing the four components of a prepared verifying key.
/// @param public_proof_inputs: Represent inputs that are public.
/// @param proof_points: Represent three proof points.
///
/// Returns a boolean indicating whether the proof is valid.
public fun verify_groth16_proof(prepared_verifying_key: &PreparedVerifyingKey, public_proof_inputs: &PublicProofInputs, proof_points: &ProofPoints): bool {
public fun verify_groth16_proof(curve: &Curve, prepared_verifying_key: &PreparedVerifyingKey, public_proof_inputs: &PublicProofInputs, proof_points: &ProofPoints): bool {
verify_groth16_proof_internal(
curve.id,
&prepared_verifying_key.vk_gamma_abc_g1_bytes,
&prepared_verifying_key.alpha_g1_beta_g2_bytes,
&prepared_verifying_key.gamma_g2_neg_pc_bytes,
Expand All @@ -79,5 +102,5 @@ module sui::groth16 {
}

/// Native functions that flattens the inputs into arrays of vectors and passed to the Rust native function.
public native fun verify_groth16_proof_internal(vk_gamma_abc_g1_bytes: &vector<u8>, alpha_g1_beta_g2_bytes: &vector<u8>, gamma_g2_neg_pc_bytes: &vector<u8>, delta_g2_neg_pc_bytes: &vector<u8>, public_proof_inputs: &vector<u8>, proof_points: &vector<u8>): bool;
native fun verify_groth16_proof_internal(curve: u8, vk_gamma_abc_g1_bytes: &vector<u8>, alpha_g1_beta_g2_bytes: &vector<u8>, gamma_g2_neg_pc_bytes: &vector<u8>, delta_g2_neg_pc_bytes: &vector<u8>, public_proof_inputs: &vector<u8>, proof_points: &vector<u8>): bool;
}
2 changes: 1 addition & 1 deletion crates/sui-framework/sources/crypto/groth16.spec.move
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

spec sui::groth16 {
spec prepare_verifying_key {
spec prepare_verifying_key_internal {
pragma opaque;
// TODO: stub to be replaced by actual abort conditions if any
aborts_if [abstract] true;
Expand Down
Loading