Skip to content

Commit

Permalink
Merge pull request #3290 from dusk-network/mocello/doc_vm
Browse files Browse the repository at this point in the history
vm: Add documentation
  • Loading branch information
moCello authored Dec 28, 2024
2 parents 4023421 + df203e4 commit 47f9556
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 44 deletions.
27 changes: 25 additions & 2 deletions vm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,31 @@
[![Repository](https://img.shields.io/badge/github-rusk--abi-blueviolet?logo=github)](https://github.com/dusk-network/dusk-vm)
[![Documentation](https://img.shields.io/badge/docs-rusk--abi-blue?logo=rust)](https://docs.rs/dusk-vm/)

## Dusk VM
# Dusk VM

The VM to execute smart contracts on the Dusk network.
The Dusk VM is a virtual machine designed for **Dusk**, enabling secure and efficient execution of smart contracts, state transitions, and cryptographic operations tailored for zero-knowledge-based applications.

It serves as the execution engine of the Dusk Blockchain, leveraging advanced cryptographic primitives and frameworks to support privacy-preserving, compliant and scalable decentralized applications.

## Features

- **State Management**: Manage blockchain state using sessions for isolated transaction execution and finalization.
- **Cryptographic Support**: Offers built-in support for hashing (Poseidon), signature verification (BLS, Schnorr), and proof validation (PLONK, Groth16).
- **Virtual Machine for zk-SNARK Applications**: Optimized for privacy-preserving computations.

## Installation

Add `dusk-vm` to your `Cargo.toml`:

```toml
[dependencies]
dusk-vm = "0.x" # Replace with the latest version
```

## Documentation

For detailed usage and API examples, refer to the [crate documentation on docs.rs](https://docs.rs/dusk-vm/).

## License

License: MPL-2.0
34 changes: 28 additions & 6 deletions vm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ use dusk_core::transfer::{
};
use piecrust::{CallReceipt, Error, Session};

/// Executes a transaction, returning the receipt of the call and the gas spent.
/// The following steps are performed:
/// Executes a transaction in the provided session.
///
/// This function processes the transaction, invoking smart contracts or
/// updating state.
///
/// During the execution the following steps are performed:
///
/// 1. Check if the transaction contains contract deployment data, and if so,
/// verifies if gas limit is enough for deployment and if the gas price is
Expand Down Expand Up @@ -45,6 +49,19 @@ use piecrust::{CallReceipt, Error, Session};
/// related to deployment, as it is either discarded or it charges the
/// full gas limit. It might be re-executed only if some other transaction
/// failed to fit the block.
///
/// # Arguments
/// * `session` - A mutable reference to the session executing the transaction.
/// * `tx` - The transaction to execute.
/// * `gas_per_deploy_byte` - The amount of gas points charged for each byte in
/// a contract-deployment bytecode.
/// * `min_deploy_points` - The minimum gas points charged for a contract
/// deployment.
/// * `min_deploy_gas_price` - The minimum gas price set for a contract
/// deployment
///
/// # Returns
/// A result indicating success or failure.
pub fn execute(
session: &mut Session,
tx: &Transaction,
Expand Down Expand Up @@ -176,10 +193,15 @@ fn verify_bytecode_hash(bytecode: &ContractBytecode) -> bool {
bytecode.hash == computed
}

/// Generate a [`ContractId`] address from:
/// - slice of bytes,
/// - nonce
/// - owner
/// Generates a unique identifier for a smart contract.
///
/// # Arguments
/// * 'bytes` - The contract bytecode.
/// * `nonce` - A unique nonce.
/// * `owner` - The contract-owner.
///
/// # Returns
/// A unique [`ContractId`].
///
/// # Panics
/// Panics if [blake2b-hasher] doesn't produce a [`CONTRACT_ID_BYTES`]
Expand Down
138 changes: 123 additions & 15 deletions vm/src/host_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,66 @@ use rkyv::{Archive, Deserialize, Serialize};

use crate::cache;

/// Compute the blake2b hash of the given scalars, returning the resulting
/// scalar. The hash is computed in such a way that it will always return a
/// valid scalar.
/// Computes a cryptographic hash of a byte vector.
///
/// This function uses the BLS12-381 scalar field to generate a deterministic
/// hash from the provided byte array. The result is a [`BlsScalar`], making it
/// suitable for cryptographic operations like zero-knowledge proofs and digital
/// signatures.
///
/// # Arguments
/// * `bytes` - A vector of bytes representing the input data to be hashed.
///
/// # Returns
/// A [`BlsScalar`] representing the cryptographic hash of the input bytes.
///
/// # References
/// For more details about BLS12-381 and its scalar operations, refer to:
/// <https://github.com/dusk-network/bls12_381>.
pub fn hash(bytes: Vec<u8>) -> BlsScalar {
BlsScalar::hash_to_scalar(&bytes[..])
}

/// Compute the poseidon hash of the given scalars
/// Computes the Poseidon hash of a vector of scalar values.
///
/// This function uses the Poseidon252 hashing algorithm to produce a
/// cryptographic hash. Poseidon is designed for efficiency in zk-SNARK
/// applications and operates over finite fields, making it well-suited for
/// blockchain and cryptographic use cases.
///
/// # Arguments
/// * `scalars` - A vector of [`BlsScalar`] values to be hashed. The input
/// values represent the data to be hashed into a single scalar output.
///
/// # Returns
/// A [`BlsScalar`] representing the Poseidon hash of the input values.
///
/// # References
/// For more details about Poseidon and its implementation, refer to:
/// <https://github.com/dusk-network/Poseidon252>.
pub fn poseidon_hash(scalars: Vec<BlsScalar>) -> BlsScalar {
PoseidonHash::digest(Domain::Other, &scalars)[0]
}

/// Verify a Plonk proof is valid for a given circuit type and public inputs
/// Verifies a PLONK zero-knowledge proof.
///
/// This function verifies a proof generated by a PLONK proving system. It takes
/// in the verifier's key data, the proof itself, and the public inputs required
/// for verification. PLONK is a highly-efficient proof system used in
/// zk-SNARKs.
///
/// # Arguments
/// * `verifier_data` - A serialized representation of the verifier key.
/// * `proof` - A serialized representation of the proof to be verified.
/// * `public_inputs` - A vector of [`BlsScalar`] representing the public inputs
/// for the proof.
///
/// # Panics
/// This will panic if `verifier_data` or `proof` are not valid.
/// # Returns
/// A boolean indicating whether the proof is valid (`true`) or invalid
/// (`false`).
///
/// # References
/// <https://github.com/dusk-network/plonk>.
pub fn verify_plonk(
verifier_data: Vec<u8>,
proof: Vec<u8>,
Expand All @@ -57,13 +101,24 @@ pub fn verify_plonk(
verifier.verify(&proof, &public_inputs[..]).is_ok()
}

/// Verify that a Groth16 proof in the BN254 pairing is valid for a given
/// circuit and inputs.
/// Verifies a Groth16 zk-SNARK proof over the BN254 curve.
///
/// This function verifies a proof generated using the Groth16 proving system.
/// It takes in the prepared verifying key, the proof itself, and the public
/// inputs.
///
/// # Arguments
/// * `pvk` - A serialized representation of the prepared verifying key.
/// * `proof` - A serialized representation of the Groth16 proof.
/// * `inputs` - A serialized vector of public inputs for the proof.
///
/// `proof` and `inputs` should be in compressed form, while `pvk` uncompressed.
/// # Returns
/// A boolean indicating whether the proof is valid (`true`) or invalid
/// (`false`).
///
/// # Panics
/// This will panic if `pvk`, `proof` or `inputs` are not valid.
/// # References
/// For more details about Groth16 and its implementation, refer to:
/// <https://docs.rs/ark-groth16/latest/ark_groth16/>.
pub fn verify_groth16_bn254(
pvk: Vec<u8>,
proof: Vec<u8>,
Expand All @@ -80,7 +135,24 @@ pub fn verify_groth16_bn254(
.expect("verifying proof should succeed")
}

/// Verify a schnorr signature is valid for the given public key and message
/// Verifies a Schnorr signature.
///
/// This function verifies a Schnorr signature using the Jubjub elliptic curve.
/// It takes in the message, the public key of the signer, and the signature to
/// verify the validity of the signature.
///
/// # Arguments
/// * `msg` - A [`BlsScalar`] representing the hashed message.
/// * `pk` - A [`SchnorrPublicKey`] representing the signer's public key.
/// * `sig` - A [`SchnorrSignature`] representing the signature to be verified.
///
/// # Returns
/// A boolean indicating whether the signature is valid (`true`) or invalid
/// (`false`).
///
/// # References
/// For more details about Schnorr signatures and their implementation, refer
/// to: <https://github.com/dusk-network/jubjub-schnorr>.
pub fn verify_schnorr(
msg: BlsScalar,
pk: SchnorrPublicKey,
Expand All @@ -89,12 +161,48 @@ pub fn verify_schnorr(
pk.verify(&sig, msg).is_ok()
}

/// Verify a BLS signature is valid for the given public key and message
/// Verifies a BLS signature.
///
/// This function verifies a BLS signature using the BLS12-381 elliptic curve.
/// It takes in the message, the signer's public key, and the signature to
/// validate the integrity of the signed data.
///
/// # Arguments
/// * `msg` - A vector of bytes representing the original message.
/// * `pk` - A [`BlsPublicKey`] representing the signer's public key.
/// * `sig` - A [`BlsSignature`] representing the signature to be verified.
///
/// # Returns
/// A boolean indicating whether the signature is valid (`true`) or invalid
/// (`false`).
///
/// # References
/// For more details about BLS signatures and their implementation, refer to:
/// <https://github.com/dusk-network/bls12_381-bls>.
pub fn verify_bls(msg: Vec<u8>, pk: BlsPublicKey, sig: BlsSignature) -> bool {
pk.verify(&sig, &msg).is_ok()
}

/// Verify a BLS signature is valid for the given public key and message
/// Verifies a BLS multi-signature.
///
/// This function verifies a multi-signature created using the BLS signature
/// scheme over the BLS12-381 elliptic curve. It validates the integrity of the
/// message signed by multiple participants.
///
/// # Arguments
/// * `msg` - A vector of bytes representing the original message.
/// * `keys` - A vector of [`BlsPublicKey`] instances representing the
/// participants' public keys.
/// * `sig` - A [`MultisigSignature`] representing the combined multi-signature
/// to be verified.
///
/// # Returns
/// A boolean indicating whether the multi-signature is valid (`true`) or
/// invalid (`false`).
///
/// # References
/// For more details about BLS multi-signatures and their implementation, refer
/// to: <https://github.com/dusk-network/bls12_381-bls>.
pub fn verify_bls_multisig(
msg: Vec<u8>,
keys: Vec<BlsPublicKey>,
Expand Down
Loading

0 comments on commit 47f9556

Please sign in to comment.