risc0_zkp/core/hash/poseidon2/
consts.rs

1// Copyright 2025 RISC Zero, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use risc0_core::field::baby_bear::Elem;
16
17macro_rules! baby_bear_array {
18    [$($x:literal),* $(,)?] => {
19        [$(Elem::new($x)),* ]
20    }
21}
22
23/// The number of state elements (also known as "cells") used in the Poseidon2 hash function.
24///
25/// Poseidon2 operates over a fixed-width state, and `CELLS` defines that width. The value of 24
26/// means that the internal state of the hash function consists of 24 elements over the BabyBear field.
27/// This directly affects security level and performance.
28pub const CELLS: usize = 24;
29
30/// The number of full S-box rounds in the first and last half of the Poseidon2 permutation.
31///
32/// These are the rounds in which the S-box (nonlinear transformation) is applied to *all* state elements.
33/// The total number of full rounds is `2 * ROUNDS_HALF_FULL`.
34pub const ROUNDS_HALF_FULL: usize = 4;
35
36/// The number of partial S-box rounds in the middle of the Poseidon2 permutation.
37///
38/// During partial rounds, the S-box is applied only to a subset (often just one) of the state elements,
39/// improving performance while still maintaining security against known cryptanalytic attacks.
40pub const ROUNDS_PARTIAL: usize = 21;
41
42/// Round constants used in the Poseidon2 permutation.
43///
44/// These constants are added to the state during each round of the permutation.
45/// The number of constants must match the number of total rounds multiplied by the number of cells (`CELLS`).
46///
47/// These constants are derived from a trusted setup or generated via secure pseudorandom methods.
48/// See the Poseidon2 paper for details on round constants' role in cryptographic security.
49///
50/// This array is hidden from the public API but is essential to the internal functioning of the hash.
51pub const ROUND_CONSTANTS: &[Elem] = &baby_bear_array![
52    0x0FA20C37, 0x0795BB97, 0x12C60B9C, 0x0EABD88E, 0x096485CA, 0x07093527, 0x1B1D4E50, 0x30A01ACE,
53    0x3BD86F5A, 0x69AF7C28, 0x3F94775F, 0x731560E8, 0x465A0ECD, 0x574EF807, 0x62FD4870, 0x52CCFE44,
54    0x14772B14, 0x4DEDF371, 0x260ACD7C, 0x1F51DC58, 0x75125532, 0x686A4D7B, 0x54BAC179, 0x31947706,
55    0x29799D3B, 0x6E01AE90, 0x203A7A64, 0x4F7E25BE, 0x72503F77, 0x45BD3B69, 0x769BD6B4, 0x5A867F08,
56    0x4FDBA082, 0x251C4318, 0x28F06201, 0x6788C43A, 0x4C6D6A99, 0x357784A8, 0x2ABAF051, 0x770F7DE6,
57    0x1794B784, 0x4796C57A, 0x724B7A10, 0x449989A7, 0x64935CF1, 0x59E14AAC, 0x0E620BB8, 0x3AF5A33B,
58    0x4465CC0E, 0x019DF68F, 0x4AF8D068, 0x08784F82, 0x0CEFDEAE, 0x6337A467, 0x32FA7A16, 0x486F62D6,
59    0x386A7480, 0x20F17C4A, 0x54E50DA8, 0x2012CF03, 0x5FE52950, 0x09AFB6CD, 0x2523044E, 0x5C54D0EF,
60    0x71C01F3C, 0x60B2C4FB, 0x4050B379, 0x5E6A70A5, 0x418543F5, 0x71DEBE56, 0x1AAD2994, 0x3368A483,
61    0x07A86F3A, 0x5EA43FF1, 0x2443780E, 0x4CE444F7, 0x146F9882, 0x3132B089, 0x197EA856, 0x667030C3,
62    0x2317D5DC, 0x0C2C48A7, 0x56B2DF66, 0x67BD81E9, 0x4FCDFB19, 0x4BAAEF32, 0x0328D30A, 0x6235760D,
63    0x12432912, 0x0A49E258, 0x030E1B70, 0x48CAEB03, 0x49E4D9E9, 0x1051B5C6, 0x6A36DBBE, 0x4CFF27A5,
64    0x1DA78EC2, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
65    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
67    0x730B0924, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
68    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
69    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
70    0x3EB56CF3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
71    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
72    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
73    0x5BD93073, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
74    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
75    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
76    0x37204C97, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
77    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
78    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
79    0x51642D89, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
80    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
81    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
82    0x66E943E8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
83    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
84    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
85    0x1A3E72DE, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
86    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
87    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
88    0x70BEB1E9, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
89    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
90    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
91    0x30FF3B3F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
92    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
93    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
94    0x4240D1C4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
95    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
96    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
97    0x12647B8D, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
98    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
99    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
100    0x65D86965, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
101    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
102    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
103    0x49EF4D7C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
104    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
105    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
106    0x47785697, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
107    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
108    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
109    0x46B3969F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
110    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
111    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
112    0x5C7B7A0E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
113    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
114    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
115    0x7078FC60, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
116    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
117    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
118    0x4F22D482, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
119    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
120    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
121    0x482A9AEE, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
122    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
123    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
124    0x6BEB839D, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
125    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
126    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
127    0x032959AD, 0x2B18AF6A, 0x55D3DC8C, 0x43BD26C8, 0x0C41595F, 0x7048D2E2, 0x00DB8983, 0x2AF563D7,
128    0x6E84758F, 0x611D64E1, 0x1F9977E2, 0x64163A0A, 0x5C5FC27B, 0x02E22561, 0x3A2D75DB, 0x1BA7B71A,
129    0x34343F64, 0x7406B35D, 0x19DF8299, 0x6FF4480A, 0x514A81C8, 0x57AB52CE, 0x6AD69F52, 0x3E0C0E0D,
130    0x48126114, 0x2A9D62CC, 0x17441F23, 0x485762BB, 0x2F218674, 0x06FDC64A, 0x0861B7F2, 0x3B36EEE6,
131    0x70A11040, 0x04B31737, 0x3722A872, 0x2A351C63, 0x623560DC, 0x62584AB2, 0x382C7C04, 0x3BF9EDC7,
132    0x0E38FE51, 0x376F3B10, 0x5381E178, 0x3AFC61C7, 0x5C1BCB4D, 0x6643CE1F, 0x2D0AF1C1, 0x08F583CC,
133    0x5D6FF60F, 0x6324C1E5, 0x74412FB7, 0x70C0192E, 0x0B72F141, 0x4067A111, 0x57388C4F, 0x351009EC,
134    0x0974C159, 0x539A58B3, 0x038C0CFF, 0x476C0392, 0x3F7BC15F, 0x4491DD2C, 0x4D1FEF55, 0x04936AE3,
135    0x58214DD4, 0x683C6AAD, 0x1B42F16B, 0x6DC79135, 0x2D4E71EC, 0x3E2946EA, 0x59DCE8DB, 0x6CEE892A,
136    0x47F07350, 0x7106CE93, 0x3BD4A7A9, 0x2BFE636A, 0x430011E9, 0x001CD66A, 0x307FAF5B, 0x0D9EF3FE,
137    0x6D40043A, 0x2E8F470C, 0x1B6865E8, 0x0C0E6C01, 0x4D41981F, 0x423B9D3D, 0x410408CC, 0x263F0884,
138    0x5311BBD0, 0x4DAE58D8, 0x30401CEA, 0x09AFA575, 0x4B3D5B42, 0x63AC0B37, 0x5FE5BB14, 0x5244E9D4,
139];
140
141/// External matrix output by the Sage script in <https://github.com/HorizenLabs/poseidon2.git>
142/// External matrix chosen as per the recommendation in the original Poseidon2
143/// paper 6x6 M4
144///
145/// These parameters are not used.  See the definition of M_EXT_MONTGOMERY for
146/// further details.
147pub const _M_EXT: &[Elem] = &baby_bear_array![
148    10, 14, 2, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 8, 12, 2, 2, 4, 6, 1,
149    1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 2, 6, 10, 14, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3,
150    5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 2, 2, 8, 12, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1,
151    1, 4, 6, 5, 7, 1, 3, 10, 14, 2, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 4, 6, 1, 1,
152    8, 12, 2, 2, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 1, 3, 5, 7, 2, 6, 10, 14, 1, 3, 5,
153    7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 1, 4, 6, 2, 2, 8, 12, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1,
154    4, 6, 1, 1, 4, 6, 5, 7, 1, 3, 5, 7, 1, 3, 10, 14, 2, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 4,
155    6, 1, 1, 4, 6, 1, 1, 8, 12, 2, 2, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 1, 3, 5, 7, 1, 3, 5, 7,
156    2, 6, 10, 14, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 1, 4, 6, 1, 1, 4, 6, 2, 2, 8, 12, 1, 1, 4,
157    6, 1, 1, 4, 6, 1, 1, 4, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 10, 14, 2, 6, 5, 7, 1, 3, 5, 7,
158    1, 3, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 8, 12, 2, 2, 4, 6, 1, 1, 4, 6, 1, 1, 1, 3, 5, 7, 1,
159    3, 5, 7, 1, 3, 5, 7, 2, 6, 10, 14, 1, 3, 5, 7, 1, 3, 5, 7, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6,
160    2, 2, 8, 12, 1, 1, 4, 6, 1, 1, 4, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 10, 14, 2,
161    6, 5, 7, 1, 3, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 8, 12, 2, 2, 4, 6, 1, 1, 1, 3,
162    5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 2, 6, 10, 14, 1, 3, 5, 7, 1, 1, 4, 6, 1, 1, 4, 6, 1,
163    1, 4, 6, 1, 1, 4, 6, 2, 2, 8, 12, 1, 1, 4, 6, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3,
164    5, 7, 1, 3, 10, 14, 2, 6, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 8, 12, 2,
165    2, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 2, 6, 10, 14, 1, 1, 4, 6, 1, 1,
166    4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 2, 2, 8, 12,
167];
168
169/// Standardizing on the same coefficients as <https://github.com/HorizenLabs/poseidon2.git>
170/// (as used in its plain implementation of Poseidon2 for BabyBear)
171///
172/// These parameters are have been confirmed to pass the algorithms given in Grassi, Rechberger, and
173/// Schofnegger's paper "Proving Resistance Against Infinitely Long Subspace Trails: How to Choose
174/// the Linear Layer" by running a version of the code provided with the paper adapted to include
175/// these parameters in what's tested.
176///
177/// The full matrix can be constructed by as follows:
178/// - Initialize a matrix with all 1s.
179/// - Add these values along the diagonal.
180pub const M_INT_DIAG_HZN: &[Elem] = &baby_bear_array![
181    0x409133f0, 0x1667a8a1, 0x06a6c7b6, 0x6f53160e, 0x273b11d1, 0x03176c5d, 0x72f9bbf9, 0x73ceba91,
182    0x5cdef81d, 0x01393285, 0x46daee06, 0x065d7ba6, 0x52d72d6f, 0x05dd05e0, 0x3bab4b63, 0x6ada3842,
183    0x2fc5fbec, 0x770d61b0, 0x5715aae9, 0x03ef0e90, 0x75b6c770, 0x242adf5f, 0x00d0ca4c, 0x36c0e388,
184];