All Projects → dusk-network → Poseidon252

dusk-network / Poseidon252

Licence: MPL-2.0 license
Reference implementation for the Poseidon Snark-friendly Hash algorithm.

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Poseidon252

h2c-rust-ref
Hash to curves - Rust reference implementation
Stars: ✭ 21 (-77.89%)
Mutual labels:  hash
xxHash-Swift
xxHash framework in Swift.
Stars: ✭ 22 (-76.84%)
Mutual labels:  hash
telfhash
Symbol hash for ELF files
Stars: ✭ 75 (-21.05%)
Mutual labels:  hash
enigma
A fast, native, cryptographic engine for the web
Stars: ✭ 101 (+6.32%)
Mutual labels:  hash
BruteForce
A simple brute forcer written in GO for SHA1, SHA256, SHA512, MD5 and bcrypt
Stars: ✭ 49 (-48.42%)
Mutual labels:  hash
BlockHashLoc
Recover files using lists of blocks hashes, bypassing the File System entirely
Stars: ✭ 45 (-52.63%)
Mutual labels:  hash
Mercury
Mercury is a hacking tool used to collect information and use the information to further hurt the target
Stars: ✭ 236 (+148.42%)
Mutual labels:  hash
MM.Hash
Profit Switching Miner For HiveOS/Linux- OLD VERSION: Project Moved To SWARM! https://github.com/MaynardMiner/SWARM
Stars: ✭ 17 (-82.11%)
Mutual labels:  hash
hash-avatar
🌈 Hash avatar algorithm
Stars: ✭ 33 (-65.26%)
Mutual labels:  hash
go-merkle
A fixed Merkle Tree implementation in Go
Stars: ✭ 36 (-62.11%)
Mutual labels:  hash
Dictionary
A dictionary data type with a fast b-tree based search
Stars: ✭ 39 (-58.95%)
Mutual labels:  hash
bookshelf-secure-password
A Bookshelf.js plugin for handling secure passwords
Stars: ✭ 24 (-74.74%)
Mutual labels:  hash
haiti
🔑 A CLI tool to identify the hash type of a given hash.
Stars: ✭ 95 (+0%)
Mutual labels:  hash
patchmap
A fast and memory efficient hashmap using sorting to resolve collisions
Stars: ✭ 41 (-56.84%)
Mutual labels:  hash
space-router
Framework agnostic router for single page apps
Stars: ✭ 36 (-62.11%)
Mutual labels:  hash
Scrypt
A .NET implementation of scrypt password hash algorithm.
Stars: ✭ 90 (-5.26%)
Mutual labels:  hash
sha3
SHA3 for Ruby is a XKCP based native (C) binding to SHA3 (FIPS 202) cryptographic hashing algorithm
Stars: ✭ 35 (-63.16%)
Mutual labels:  hash
hashids.pm
Hashids, ported for Perl
Stars: ✭ 15 (-84.21%)
Mutual labels:  hash
py-cryptonight
Python Cryptonight binding / extension. Monero hash function, proof-of-work, cn_slow_hash()
Stars: ✭ 20 (-78.95%)
Mutual labels:  hash
ipld-explorer-cli
🔎 Explore the IPLD directed acyclic graph with your keyboard
Stars: ✭ 22 (-76.84%)
Mutual labels:  hash

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.

This hashes heavily rely on the Hades permutation, which is one of the key parts that Poseidon needs in order to work. This library uses the reference implementation of Dusk-Hades which has been designed & build by the Dusk-Network team.

The library provides the two hashing techniques of Poseidon:

Sponge Hash

The Sponge technique in Poseidon allows to hash an unlimited amount of data into a single Scalar. The sponge hash technique requires a padding to be applied before the data can be hashed.

This is done to avoid hash collisions as stated in the paper of the Poseidon Hash algorithm. See: https://eprint.iacr.org/2019/458.pdf. The inputs of the sponge_hash are always Scalar or need to be capable of being represented as it.

The module provides two sponge hash implementations:

  • Sponge hash using Scalar as backend. Which hashes the inputted Scalars and returns a single Scalar.

  • Sponge hash gadget using dusk_plonk::Witness as a backend. This technique is used/required when you want to proof pre-images of unconstrained data inside Zero-Knowledge PLONK circuits.

Merkle Hash

The Merkle Level Hashing is a technique that Poseidon is optimized-by-design to perform. This technique allows us to perform hashes of an entire Merkle Tree using Dusk-Hades as backend.

The technique requires the computation of a bitflags element which is always positioned as the first item of the level when we hash it, and it basically generated in respect of the presence or absence of a leaf in the tree level. This allows to prevent hashing collisions.

At the moment, this library is designed and optimized to work only with trees of ARITY up to 4. That means that trees with a bigger ARITY SHOULD NEVER be used with this lib. The module contains the implementation of 4 variants of the same algorithm to support the majority of the configurations that the user may need:

  • Scalar backend for hashing Merkle Tree levels outside ZK-Circuits with two variants: One of them computes the bitflags item while the other assumes that it has already been computed and placed in the first Level position.

  • dusk_plonk::Witness backend for hashing Merkle Tree levels inside ZK-Circuits, specifically, PLONK circuits. This implementation comes also with two variants; One of them computes the bitflags item while the other assumes that it has already been computed and placed in the first Level position.

Zero Knowledge Merkle Opening Proof example:

use dusk_plonk::error::Error as PlonkError;
use dusk_poseidon::tree::{self, PoseidonBranch, PoseidonLeaf, PoseidonTree};
use rand::rngs::OsRng;
use rand::{CryptoRng, RngCore};


use dusk_plonk::prelude::*;
use nstack::annotation::Keyed;

// Depth of the merkle tree
const DEPTH: usize = 17;

// Capacity of the circuit
const CAPACITY: usize = 15;

// Alias for the default tree implementation
type Tree = PoseidonTree<DataLeaf, (), DEPTH>;

// Leaf representation
#[derive(Debug, Default, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub struct DataLeaf {
    data: BlsScalar,
    pos: u64,
}

// Keyed needs to be implemented for a leaf type and the tree key.
impl Keyed<()> for DataLeaf {
    fn key(&self) -> &() {
        &()
    }
}

impl DataLeaf {
    pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
        let data = BlsScalar::random(rng);
        let pos = 0;

        Self { data, pos }
    }
}

// Any leaf of the poseidon tree must implement `PoseidonLeaf`
impl PoseidonLeaf for DataLeaf {
    // Cryptographic hash of the data leaf
    fn poseidon_hash(&self) -> BlsScalar {
        self.data
    }

    // Position on the tree
    fn pos(&self) -> &u64 {
        &self.pos
    }

    // Method used to set the position on the tree after the
    // `PoseidonTree::push` call.
    fn set_pos(&mut self, pos: u64) {
        self.pos = pos;
    }
}

#[derive(Default)]
struct MerkleOpeningCircuit {
    branch: PoseidonBranch<DEPTH>,
}

impl MerkleOpeningCircuit {
    /// Generate N random leaves and append them to the tree
    pub fn random<R: RngCore + CryptoRng>(
        rng: &mut R,
        tree: &mut Tree,
    ) -> Self {
        const N: u64 = 1024;

        // Append 1024 elements to the tree
        for _ in 0..N {
            let leaf = DataLeaf::random(rng);
            tree.push(leaf);
        }

        let branch = tree.branch(N - 1).expect(
            "Failed to fetch the branch of the created leaf from the tree",
        );

        Self { branch }
    }
}

impl Circuit for MerkleOpeningCircuit {
    fn circuit<C>(&self, composer: &mut C) -> Result<(), PlonkError> 
    where 
        C: Composer,
    {
      let leaf: BlsScalar = *self.branch;
      let leaf = composer.append_witness(leaf);
  
      let root = self.branch.root();
      let root = composer.append_witness(*root);
  
      let root_p =
              tree::merkle_opening::<C, DEPTH>(composer, &self.branch, leaf);
  
      composer.assert_equal(root_p, root);
  
      Ok(())
    }
}

// Create a prover and a verifier
let label = b"dusk-network";
let pp = PublicParameters::setup(1 << CAPACITY, &mut OsRng).unwrap();

let (prover, verifier) =
    Compiler::compile(&pp, label).expect("failed to compile circuit");

// Instantiate a new tree
let mut tree = Tree::default();
let circuit = MerkleOpeningCircuit::random(&mut OsRng, &mut tree);

// Generate a ZK opening proof
let (proof, public_inputs) = prover.prove(&mut OsRng, &circuit)
            .expect("proving the circuit should succeed");

// Verify the proof
verifier.verify(&proof, &public_inputs)
    .expect("verifying the proof should succeed");

Documentation

This crate contains info about all the functions that the library provides as well as the documentation regarding the data structures that it exports. To check it, please feel free to go to the documentation page

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].