Crate dusk_poseidon

source ·
Expand description

Build Status Repository Documentation

§Dusk-Poseidon

Reference implementation for the Poseidon Hashing algorithm.

Reference: Starkad and Poseidon: New Hash Functions for Zero Knowledge Proof Systems

This repository has been created so there’s a unique library that holds the tools & functions required to perform Poseidon Hashes on field elements of the bls12-381 elliptic curve.

The hash uses the Hades design for its inner permutation and the SAFE framework for contstructing the sponge.

The library provides the two hashing techniques of Poseidon:

  • The ‘normal’ hashing functionalities operating on BlsScalar.
  • The ‘gadget’ hashing functionalities that build a circuit which outputs the hash.

§Examples

§Hash

use rand::rngs::StdRng;
use rand::SeedableRng;

use dusk_poseidon::{Domain, Hash};
use dusk_bls12_381::BlsScalar;
use ff::Field;

// generate random input
let mut rng = StdRng::seed_from_u64(0xbeef);
let mut input = [BlsScalar::zero(); 42];
for scalar in input.iter_mut() {
    *scalar = BlsScalar::random(&mut rng);
}

// digest the input all at once
let hash = Hash::digest(Domain::Other, &input);

// update the input gradually
let mut hasher = Hash::new(Domain::Other);
hasher.update(&input[..3]);
hasher.update(&input[3..]);
assert_eq!(hash, hasher.finalize());

// create a hash used for merkle tree hashing with arity = 4
let merkle_hash = Hash::digest(Domain::Merkle4, &input[..4]);

// which is different when another domain is used
assert_ne!(merkle_hash, Hash::digest(Domain::Other, &input[..4]));

§Encryption

#![cfg(feature = "encryption")]

use dusk_bls12_381::BlsScalar;
use dusk_jubjub::{JubJubScalar, GENERATOR_EXTENDED, dhke};
use dusk_poseidon::{decrypt, encrypt, Error};
use ff::Field;
use rand::rngs::StdRng;
use rand::SeedableRng;

// generate the keys and nonce needed for the encryption
let mut rng = StdRng::seed_from_u64(0x42424242);
let alice_secret = JubJubScalar::random(&mut rng);
let alice_public = GENERATOR_EXTENDED * &alice_secret;
let bob_secret = JubJubScalar::random(&mut rng);
let bob_public = GENERATOR_EXTENDED * &bob_secret;
let nonce = BlsScalar::random(&mut rng);

// Alice encrypts a message of 3 BlsScalar using Diffie-Hellman key exchange
// with Bob's public key
let message = vec![BlsScalar::from(10), BlsScalar::from(20), BlsScalar::from(30)];
let shared_secret = dhke(&alice_secret, &bob_public);
let cipher = encrypt(&message, &shared_secret, &nonce)
    .expect("Encryption should pass");

// Bob decrypts the cipher using Diffie-Hellman key exchange with Alice's public key
let shared_secret = dhke(&bob_secret, &alice_public);
let decrypted_message = decrypt(&cipher, &shared_secret, &nonce)
    .expect("Decryption should pass");

assert_eq!(decrypted_message, message);

§Benchmarks

There are benchmarks for hashing, encrypting and decrypting in their native form, operating on Scalar, and for a zero-knowledge circuit proof generation and verification.

To run all benchmarks on your machine, run

cargo bench --features=zk,encryption

in the repository.

§Licensing

This code is licensed under Mozilla Public License Version 2.0 (MPL-2.0). Please see LICENSE for further info.

§About

Implementation designed by the dusk team.

§Contributing

  • If you want to contribute to this repository/project please, check CONTRIBUTING.md
  • If you want to report a bug or request a new feature addition, please open an issue on this repository.

Structs§

  • Hash any given input into one or several scalar using the Hades permutation strategy. The Hash can absorb multiple chunks of input but will only call squeeze once at the finalization of the hash. The output length is set to 1 element per default, but this can be overridden with Hash::output_len.

Enums§

  • The Domain Separation for Poseidon
  • Defines all possible error variants for SAFE

Constants§

  • The amount of field elements that fit into the hades permutation container