Skip to content

Commit da890c7

Browse files
danny-shtermandanny-shtermanLeonHibnikyshekel
authored
feat: Poseidon2 hash function (#673)
- Lacks support for sponge hash - Lacks support for t>4 cases for large fields (>4B) Co-authored-by: danny-shterman <[email protected]> Co-authored-by: Leon Hibnik <[email protected]> Co-authored-by: LeonHibnik <[email protected]> Co-authored-by: Yuval Shekel <[email protected]>
1 parent 9a10b49 commit da890c7

File tree

94 files changed

+7917
-41
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+7917
-41
lines changed

docs/docs/icicle/golang-bindings/hash.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Using the Hash package requires `go` version 1.22
1616

1717
The ICICLE library provides Golang bindings for hashing using a variety of cryptographic hash functions. These hash functions are optimized for both general-purpose data and cryptographic operations such as multi-scalar multiplication, commitment generation, and Merkle tree construction.
1818

19-
This guide will show you how to use the ICICLE hashing API in Golang with examples for common hash algorithms, such as Keccak-256, Keccak-512, SHA3-256, SHA3-512, Blake2s, and Poseidon.
19+
This guide will show you how to use the ICICLE hashing API in Golang with examples for common hash algorithms, such as Keccak-256, Keccak-512, SHA3-256, SHA3-512, Blake2s, Poseidon.
2020

2121
## Importing Hash Functions
2222

docs/docs/icicle/primitives/hash.md

+26-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
ICICLE’s hashing system is designed to be flexible, efficient, and optimized for both general-purpose and cryptographic operations. Hash functions are essential in operations such as generating commitments, constructing Merkle trees, executing the Sumcheck protocol, and more.
66

7-
ICICLE provides an easy-to-use interface for hashing on both CPU and GPU, with transparent backend selection. You can choose between several hash algorithms such as Keccak-256, Keccak-512, SHA3-256, SHA3-512, Blake2s, Poseidon and more, which are optimized for processing both general data and cryptographic field elements or elliptic curve points.
7+
ICICLE provides an easy-to-use interface for hashing on both CPU and GPU, with transparent backend selection. You can choose between several hash algorithms such as Keccak-256, Keccak-512, SHA3-256, SHA3-512, Blake2s, Poseidon, Poseidon2 and more, which are optimized for processing both general data and cryptographic field elements or elliptic curve points.
88

99
## Hashing Logic
1010

@@ -24,6 +24,7 @@ ICICLE supports the following hash functions:
2424
4. **SHA3-512**
2525
5. **Blake2s**
2626
6. **Poseidon**
27+
7. **Poseidon2**
2728

2829
:::info
2930
Additional hash functions might be added in the future. Stay tuned!
@@ -50,6 +51,15 @@ Currently the Poseidon implementation is the Optimized Poseidon (https://hackmd.
5051

5152
The optional `domain_tag` pointer parameter enables domain separation, allowing isolation of hash outputs across different contexts or applications.
5253

54+
55+
### Poseidon2
56+
57+
[Poseidon2](https://eprint.iacr.org/2023/323.pdf) is a cryptographic hash function designed specifically for field elements.
58+
It is an improved version of the original [Poseidon](https://eprint.iacr.org/2019/458) hash, offering better performance on modern hardware. Poseidon2 is optimized for use with elliptic curve cryptography and finite fields, making it ideal for decentralized systems like blockchain. Its main advantage is balancing strong security with efficient computation, which is crucial for applications that require fast, reliable hashing.
59+
60+
The optional `domain_tag` pointer parameter enables domain separation, allowing isolation of hash outputs across different contexts or applications.
61+
62+
5363
## Using Hash API
5464

5565
### 1. Creating a Hasher Object
@@ -60,6 +70,7 @@ First, you need to create a hasher object for the specific hash function you wan
6070
#include "icicle/hash/keccak.h"
6171
#include "icicle/hash/blake2s.h"
6272
#include "icicle/hash/poseidon.h"
73+
#include "icicle/hash/poseidon2.h"
6374

6475
// Create hasher instances for different algorithms
6576
auto keccak256 = Keccak256::create();
@@ -74,6 +85,14 @@ auto poseidon = Poseidon::create<scalar_t>(t);
7485
scalar_t domain_tag = scalar_t::zero(); // Example using zero; this can be set to any valid field element.
7586
auto poseidon_with_domain_tag = Poseidon::create<scalar_t>(t, &domain_tag);
7687
// This version of the hasher with a domain tag expects t-1 additional inputs for hashing.
88+
// Poseidon2 requires specifying the field-type and t parameter (supported 2, 3, 4, 8, 12, 16, 20, 24) as defined by
89+
// the Poseidon2 paper. For large fields (field width >= 254) the supported values of t are 2, 3, 4.
90+
auto poseidon2 = Poseidon2::create<scalar_t>(t);
91+
// Optionally, Poseidon2 can accept a domain-tag, which is a field element used to separate applications or contexts.
92+
// The domain tag acts as the first input to the hash function, with the remaining t-1 inputs following it.
93+
scalar_t domain_tag = scalar_t::zero(); // Example using zero; this can be set to any valid field element.
94+
auto poseidon2_with_domain_tag = Poseidon2::create<scalar_t>(t, &domain_tag);
95+
// This version of the hasher with a domain tag expects t-1 additional inputs for hashing.
7796
```
7897

7998
### 2. Hashing Data
@@ -139,9 +158,13 @@ auto output = std::make_unique<std::byte[]>(32 * config.batch); // Allocate outp
139158
eIcicleErr err = keccak256.hash(input.data(), input.size() / config.batch, config, output.get());
140159
```
141160

142-
### 4. Posidon sponge function
161+
### 4. Poseidon sponge function
162+
163+
Currently the poseidon sponge function (sponge function description could be found in Sec 2.1 of https://eprint.iacr.org/2019/458.pdf ) isn't implemented.
164+
165+
### 5. Poseidon2 sponge function
143166

144-
Currently the poseidon sponge function (Sec 2.1 of https://eprint.iacr.org/2019/458.pdf ) isn't implemented.
167+
Currently the poseidon2 sponge function (sponge function description could be found in Sec 2.1 of https://eprint.iacr.org/2019/458.pdf ) isn't implemented.
145168

146169
### Supported Bindings
147170

docs/docs/icicle/primitives/poseidon.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ So for Poseidon of arity 2 and input of size 1024 * 2, we would expect 1024 elem
6262

6363
Poseidon is extremely customizable and using different constants will produce different hashes, security levels and performance results.
6464

65-
We support pre-calculated and optimized constants for each of the [supported curves](../libraries#supported-curves-and-operations).The constants can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/icicle/hash/poseidon_constants) and are labeled clearly per curve `<curve_name>_poseidon.h`.
65+
We support pre-calculated and optimized constants for each of the [supported curves](../libraries#supported-curves-and-operations).The constants can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/poseidon/constants) and are labeled clearly per curve `<curve_name>_poseidon.h`.
6666

67-
If you wish to generate your own constants you can use our python script which can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/icicle/hash/poseidon_constants/generate_parameters.py).
67+
If you wish to generate your own constants you can use our python script which can be found [here](https://github.com/ingonyama-zk/icicle/tree/main/icicle/include/poseidon/constants/generate_parameters.py).
6868

6969
Prerequisites:
7070

docs/docs/icicle/primitives/poseidon2.md

+1
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,4 @@ Bn254TreeBuilder::build_merkle_tree(
8888
)
8989
.unwrap();
9090
```
91+

icicle/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ option(G2 "Build G2 MSM" ON)
6969
option(EXT_FIELD "Build extension field" ON)
7070
option(HASH "Build hashes and tree builders" ON)
7171
option(POSEIDON "Build poseidon hash" ON)
72+
option(POSEIDON2 "Build poseidon2 hash" ON)
7273
option(SANITIZE "Enable memory address sanitizer" OFF)
7374

7475
# address sanitizer
@@ -179,4 +180,5 @@ endif()
179180

180181
if (BUILD_TESTS)
181182
add_subdirectory(tests)
182-
endif()
183+
endif()
184+

icicle/backend/cpu/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ if (FIELD)
1515
if (POSEIDON)
1616
target_sources(icicle_field PRIVATE src/hash/cpu_poseidon.cpp)
1717
endif()
18+
if (POSEIDON2)
19+
target_sources(icicle_field PRIVATE src/hash/cpu_poseidon2.cpp)
20+
endif()
1821
target_include_directories(icicle_field PRIVATE include)
1922
endif() # FIELD
2023

icicle/backend/cpu/src/hash/cpu_poseidon.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@
44
#include <vector>
55

66
#if FIELD_ID == BN254
7-
#include "icicle/hash/poseidon_constants/bn254_poseidon.h"
7+
#include "icicle/hash/poseidon_constants/constants/bn254_poseidon.h"
88
using namespace poseidon_constants_bn254;
99
#elif FIELD_ID == BLS12_381
10-
#include "icicle/hash/poseidon_constants/bls12_381_poseidon.h"
10+
#include "icicle/hash/poseidon_constants/constants/bls12_381_poseidon.h"
1111
using namespace poseidon_constants_bls12_381;
1212
#elif FIELD_ID == BLS12_377
13-
#include "icicle/hash/poseidon_constants/bls12_377_poseidon.h"
13+
#include "icicle/hash/poseidon_constants/constants/bls12_377_poseidon.h"
1414
using namespace poseidon_constants_bls12_377;
1515
#elif FIELD_ID == BW6_761
16-
#include "icicle/hash/poseidon_constants/bw6_761_poseidon.h"
16+
#include "icicle/hash/poseidon_constants/constants/bw6_761_poseidon.h"
1717
using namespace poseidon_constants_bw6_761;
1818
#elif FIELD_ID == GRUMPKIN
19-
#include "icicle/hash/poseidon_constants/grumpkin_poseidon.h"
19+
#include "icicle/hash/poseidon_constants/constants/grumpkin_poseidon.h"
2020
using namespace poseidon_constants_grumpkin;
2121
#elif FIELD_ID == M31
22-
#include "icicle/hash/poseidon_constants/m31_poseidon.h"
22+
#include "icicle/hash/poseidon_constants/constants/m31_poseidon.h"
2323
using namespace poseidon_constants_m31;
2424
#elif FIELD_ID == BABY_BEAR
25-
#include "icicle/hash/poseidon_constants/babybear_poseidon.h"
25+
#include "icicle/hash/poseidon_constants/constants/babybear_poseidon.h"
2626
using namespace poseidon_constants_babybear;
2727
#elif FIELD_ID == STARK_252
28-
#include "icicle/hash/poseidon_constants/stark252_poseidon.h"
28+
#include "icicle/hash/poseidon_constants/constants/stark252_poseidon.h"
2929
using namespace poseidon_constants_stark252;
3030
#endif
3131

@@ -292,4 +292,4 @@ namespace icicle {
292292

293293
REGISTER_CREATE_POSEIDON_BACKEND("CPU", create_cpu_poseidon_hash_backend);
294294

295-
} // namespace icicle
295+
} // namespace icicle

0 commit comments

Comments
 (0)