1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! **pso-poseidon** is a [Poseidon](https://eprint.iacr.org/2019/458) hash
//! implementation in Rust created for [PSO](https://github.com/psonet) based on [light-poseidon](https://github.com/Lightprotocol/light-poseidon/) library.
//!
//! # Parameters
//!
//! The library provides pre-generated parameters over the BN254 curve, however
//! it can work with any parameters provided as long as developers take care
//! of generating the round constants.
//!
//! Parameters provided by the library are:
//!
//! * *x^5* S-boxes
//! * width - *2 ≤ t ≤ 13*
//! * inputs - *1 ≤ n ≤ 12*
//! * 8 full rounds and partial rounds depending on *t*: *[56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65]*
//!
//! # Output type
//!
//! `Poseidon` type implements two traits which serve the purpose
//! of returning the calculated hash in different representations:
//!
//! * `PoseidonHasher` with the `hash` method which returns
//! `ark_ff::PrimeField`. Might be useful if you want
//! to immediately process the result with an another library which works with
//! `ark_ff::PrimeField` types.
//!
//! # Examples
//!
//! With `PoseidonHasher` trait and `ark_ff::PrimeField` result:
//!
//! ```rust
//! use ark_bn254::Fr;
//! use ark_ff::PrimeField;
//! use pso_poseidon::{Poseidon, PoseidonHasher};
//!
//! let mut poseidon = Poseidon::<Fr>::new_circom(2).unwrap();
//!
//! let input1 = Fr::from_le_bytes_mod_order(&[1u8; 32]);
//! let input2 = Fr::from_le_bytes_mod_order(&[2u8; 32]);
//!
//! let hash = poseidon.hash(&[input1, input2]).unwrap();
//!
//! // Do something with `hash`.
//! ```
//!
//! # Poseidon2
//!
//! [`Poseidon2`] is a separate, generic BN254 **Poseidon2** hash, bit-compatible
//! with noir's in-circuit `poseidon2` (Barretenberg's permutation + sponge). Use
//! it for off-circuit hashing that must reproduce an in-circuit Poseidon2 result.
//! It shares no parameters with the circom-compatible `Poseidon` above —
//! Poseidon2 is a distinct construction. BN254 is built in via
//! `Poseidon2::<Fr>::new()`; other fields supply their own constants.
//!
//! ```rust
//! use ark_bn254::Fr;
//! use pso_poseidon::{Poseidon2, PoseidonHasher};
//!
//! let mut poseidon2 = Poseidon2::<Fr>::new();
//! let _hash = poseidon2.hash(&[Fr::from(1u64), Fr::from(2u64)]).unwrap();
//! ```
//!
//! # Field Arithmetic
//!
//! This library uses [ark-ff](https://github.com/arkworks-rs/algebra) for field arithmetic. While ark-ff carries an academic disclaimer, it is widely adopted in production by major projects including [Aleo](https://github.com/AleoNet/snarkVM), [Penumbra](https://github.com/penumbra-zone/penumbra), [Mina (Kimchi)](https://github.com/o1-labs/proof-systems), and [Espresso Systems](https://github.com/EspressoSystems).
//!
//! # Implementation
//!
//! The implementation is compatible with the
//! [original SageMath implementation](https://extgit.iaik.tugraz.at/krypto/hadeshash/-/tree/master/),
//! but it was also inspired by the following ones:
//!
//! * [circomlibjs](https://github.com/iden3/circomlibjs)
//! * [zero-knowledge-gadgets](https://github.com/webb-tools/zero-knowledge-gadgets)
//! * [light-poseidon](https://github.com/Lightprotocol/light-poseidon/)
//!
//! # Security
//!
//! This library has been audited by [Veridise](https://veridise.com/). You can
//! read the audit report [here](https://github.com/Lightprotocol/light-poseidon/blob/main/assets/audit.pdf).
use PrimeField;
use Error;
pub use ;
/// bb-compatible Poseidon2 (matches noir's in-circuit `poseidon2`).
pub use Poseidon2;
pub const HASH_LEN: usize = 32;
pub const MAX_X5_LEN: usize = 13;