37 releases (19 breaking)
new 0.37.0 | Mar 27, 2024 |
---|---|
0.36.0 | Mar 13, 2024 |
0.32.0 | Dec 13, 2023 |
0.31.0 | Oct 11, 2023 |
0.20.0-pre.1 | Mar 31, 2021 |
#107 in Cryptography
929 downloads per month
Used in 13 crates
(11 directly)
66KB
832 lines
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.
Dependencies
~4MB
~88K SLoC