#poseidon2 #hash-functions #quantus-network

no-std bin+lib qp-poseidon-core

Poseidon2 hash core over Goldilocks with a Plonky2/Plonky3-agnostic compatibility layer

14 releases (stable)

new 1.5.0 Apr 10, 2026
1.4.0 Mar 30, 2026
1.1.0 Feb 27, 2026
1.0.7 Jan 19, 2026
0.9.5 Sep 24, 2025

#2 in #hash-functions

Download history 72/week @ 2025-12-19 8/week @ 2025-12-26 143/week @ 2026-01-02 94/week @ 2026-01-09 171/week @ 2026-01-16 218/week @ 2026-01-23 92/week @ 2026-01-30 185/week @ 2026-02-06 234/week @ 2026-02-13 91/week @ 2026-02-20 186/week @ 2026-02-27 318/week @ 2026-03-06 215/week @ 2026-03-13 94/week @ 2026-03-20 354/week @ 2026-03-27 322/week @ 2026-04-03

1,065 downloads per month
Used in 11 crates (6 directly)

MIT-0 license

67KB
1.5K SLoC

qp-poseidon-core

A pure Rust implementation of the Poseidon hash function using plonky3 field arithmetic. This crate provides the core cryptographic functionality without any external dependencies beyond plonky3.

Features

  • No-std compatible: Works in embedded and constrained environments
  • Pure cryptography: No blockchain or external dependencies
  • Circuit-compatible: Padding behavior matches zero-knowledge circuit implementations
  • Field arithmetic: Built on battle-tested plonky3 Goldilocks field

Basic Usage

use qp_poseidon_core::PoseidonCore;

// Hash some bytes with padding (recommended for circuit compatibility)
let data = b"hello world";
let hash = PoseidonCore::hash_for_circuit(data);
println!("Hash: {:?}", hash);

// Hash without padding
let hash_no_pad = PoseidonCore::hash_no_pad_bytes(data);

Working with Field Elements

use qp_poseidon_core::{PoseidonCore, injective_bytes_to_felts};
use plonky3::field::goldilocks_field::GoldilocksField;

// Convert bytes to field elements
let data = b"test data";
let felts = injective_bytes_to_felts(data);

// Hash field elements directly
let hash = PoseidonCore::hash_padded_felts(felts);

Utility Functions

The crate provides several utility functions for converting between different data types and field elements:

use qp_poseidon_core::{u64_to_felts, u128_to_felts, injective_string_to_felts};

// Convert numbers to field elements
let num_felts = u64_to_felts(12345);
let large_num_felts = u128_to_felts(123456789012345);

// Convert strings to field elements (max 8 bytes)
let string_felts = injective_string_to_felts("hello");

Constants

  • FIELD_ELEMENT_PREIMAGE_PADDING_LEN: usize = 160 - Minimum field elements for circuit-compatible padding

Padding Behavior

  • Padded functions: Automatically pad input to FIELD_ELEMENT_PREIMAGE_PADDING_LEN field elements
  • Unpadded functions: Hash input as-is without modification
  • Field element conversion: Uses injective mapping to preserve input uniqueness

Performance

  • Optimized for deterministic behavior across platforms
  • Memory efficient for constrained environments
  • Uses plonky3's optimized field arithmetic
  • No heap allocations in core hashing (only in utility functions)

Security

  • Built on battle-tested plonky3 field arithmetic
  • Implements standard Poseidon permutation
  • Circuit-compatible padding prevents length extension attacks
  • Extensive test coverage with known test vectors
  • qp-poseidon - Substrate-compatible wrapper around this core implementation
  • plonky3 - The underlying field arithmetic and Poseidon implementation

Dependencies

~8–13MB
~171K SLoC