Skip to content

Commit b428420

Browse files
committed
Merge branch 'vendor-hadeshash'
Code is vendored with git subtree.
2 parents 13d65f6 + a05e736 commit b428420

10 files changed

+1147
-0
lines changed

vendor/hadeshash/LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2019 Graz University of Technology
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the ""Software""), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

vendor/hadeshash/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Reference Implementations for Various Versions of Starkad and Poseidon
2+
This repository contains the source code of reference implementations for various versions of Poseidon [1]. The source code is available in Sage. Moreover, scripts to calculate the round numbers, the round constants, and the MDS matrices are also included.
3+
4+
### Update from 07/03/2021
5+
We fixed several bugs in the implementation. First, the linear layer was computed as `state = state * M` instead of `state = M * state`, and secondly the final matrix multiplication was missing. The test vectors were also changed accordingly.
6+
7+
[1] *Poseidon: A New Hash Function for Zero-Knowledge Proof Systems*. Cryptology ePrint Archive, Report 2019/458. https://eprint.iacr.org/2019/458. Accepted at USENIX'21.
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from math import *
2+
import sys
3+
import Crypto.Util.number
4+
5+
def sat_inequiv_alpha(p, t, R_F, R_P, alpha, M):
6+
n = ceil(log(p, 2))
7+
N = int(n * t)
8+
if alpha > 0:
9+
R_F_1 = 6 if M <= ((floor(log(p, 2) - ((alpha-1)/2.0))) * (t + 1)) else 10 # Statistical
10+
R_F_2 = 1 + ceil(log(2, alpha) * min(M, n)) + ceil(log(t, alpha)) - R_P # Interpolation
11+
#R_F_3 = ceil(min(n, M) / float(3*log(alpha, 2))) - R_P # Groebner 1
12+
#R_F_3 = ((log(2, alpha) / float(2)) * min(n, M)) - R_P # Groebner 1
13+
R_F_3 = 1 + (log(2, alpha) * min(M/float(3), log(p, 2)/float(2))) - R_P # Groebner 1
14+
R_F_4 = t - 1 + min((log(2, alpha) * M) / float(t+1), ((log(2, alpha)*log(p, 2)) / float(2))) - R_P # Groebner 2
15+
#R_F_5 = ((1.0/(2*log((alpha**alpha)/float((alpha-1)**(alpha-1)), 2))) * min(n, M) + t - 2 - R_P) / float(t - 1) # Groebner 3
16+
R_F_max = max(ceil(R_F_1), ceil(R_F_2), ceil(R_F_3), ceil(R_F_4))
17+
return (R_F >= R_F_max)
18+
elif alpha == (-1):
19+
R_F_1 = 6 if M <= ((floor(log(p, 2) - 2)) * (t + 1)) else 10 # Statistical
20+
R_P_1 = 1 + ceil(0.5 * min(M, n)) + ceil(log(t, 2)) - floor(R_F * log(t, 2)) # Interpolation
21+
R_P_2 = 1 + ceil(0.5 * min(M, n)) + ceil(log(t, 2)) - floor(R_F * log(t, 2))
22+
R_P_3 = t - 1 + ceil(log(t, 2)) + min(ceil(M / float(t+1)), ceil(0.5*log(p, 2))) - floor(R_F * log(t, 2)) # Groebner 2
23+
R_F_max = ceil(R_F_1)
24+
R_P_max = max(ceil(R_P_1), ceil(R_P_2), ceil(R_P_3))
25+
return (R_F >= R_F_max and R_P >= R_P_max)
26+
else:
27+
print("Invalid value for alpha!")
28+
exit(1)
29+
30+
def get_sbox_cost(R_F, R_P, N, t):
31+
return int(t * R_F + R_P)
32+
33+
def get_size_cost(R_F, R_P, N, t):
34+
n = ceil(float(N) / t)
35+
return int((N * R_F) + (n * R_P))
36+
37+
def get_depth_cost(R_F, R_P, N, t):
38+
return int(R_F + R_P)
39+
40+
def find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin):
41+
n = ceil(log(p, 2))
42+
N = int(n * t)
43+
44+
sat_inequiv = sat_inequiv_alpha
45+
46+
R_P = 0
47+
R_F = 0
48+
min_cost = float("inf")
49+
max_cost_rf = 0
50+
# Brute-force approach
51+
for R_P_t in range(1, 500):
52+
for R_F_t in range(4, 100):
53+
if R_F_t % 2 == 0:
54+
if (sat_inequiv(p, t, R_F_t, R_P_t, alpha, M) == True):
55+
if security_margin == True:
56+
R_F_t += 2
57+
R_P_t = int(ceil(float(R_P_t) * 1.075))
58+
cost = cost_function(R_F_t, R_P_t, N, t)
59+
if (cost < min_cost) or ((cost == min_cost) and (R_F_t < max_cost_rf)):
60+
R_P = ceil(R_P_t)
61+
R_F = ceil(R_F_t)
62+
min_cost = cost
63+
max_cost_rf = R_F
64+
return (int(R_F), int(R_P))
65+
66+
def calc_final_numbers_fixed(p, t, alpha, M, security_margin):
67+
# [Min. S-boxes] Find best possible for t and N
68+
n = ceil(log(p, 2))
69+
N = int(n * t)
70+
cost_function = get_sbox_cost
71+
ret_list = []
72+
(R_F, R_P) = find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin)
73+
min_sbox_cost = cost_function(R_F, R_P, N, t)
74+
ret_list.append(R_F)
75+
ret_list.append(R_P)
76+
ret_list.append(min_sbox_cost)
77+
78+
# [Min. Size] Find best possible for t and N
79+
# Minimum number of S-boxes for fixed n results in minimum size also (round numbers are the same)!
80+
min_size_cost = get_size_cost(R_F, R_P, N, t)
81+
ret_list.append(min_size_cost)
82+
83+
return ret_list # [R_F, R_P, min_sbox_cost, min_size_cost]
84+
85+
def print_latex_table_combinations(combinations, alpha, security_margin):
86+
for comb in combinations:
87+
N = comb[0]
88+
t = comb[1]
89+
M = comb[2]
90+
n = int(N / t)
91+
prime = Crypto.Util.number.getPrime(n)
92+
ret = calc_final_numbers_fixed(prime, t, alpha, M, security_margin)
93+
field_string = "\mathbb F_{p}"
94+
sbox_string = "x^{" + str(alpha) + "}"
95+
print("$" + str(M) + "$ & $" + str(N) + "$ & $" + str(n) + "$ & $" + str(t) + "$ & $" + str(ret[0]) + "$ & $" + str(ret[1]) + "$ & $" + field_string + "$ & $" + str(ret[2]) + "$ & $" + str(ret[3]) + "$ \\\\")
96+
97+
# Single tests
98+
# print calc_final_numbers_fixed(Crypto.Util.number.getPrime(64), 24, 3, 128, True)
99+
# print calc_final_numbers_fixed(Crypto.Util.number.getPrime(253), 6, -1, 128, True)
100+
print(calc_final_numbers_fixed(Crypto.Util.number.getPrime(255), 3, 5, 128, True))
101+
print(calc_final_numbers_fixed(Crypto.Util.number.getPrime(255), 6, 5, 128, True))
102+
print(calc_final_numbers_fixed(Crypto.Util.number.getPrime(254), 3, 5, 128, True))
103+
print(calc_final_numbers_fixed(Crypto.Util.number.getPrime(254), 6, 5, 128, True))
104+
print(calc_final_numbers_fixed(Crypto.Util.number.getPrime(64), 24, 3, 128, True))
105+
106+
# x^5 (254-bit prime number)
107+
#prime = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
108+
x_5_combinations = [
109+
[1536, 2, 128], [1536, 4, 128], [1536, 6, 128], [1536, 8, 128], [1536, 16, 128],
110+
[1536, 2, 256], [1536, 4, 256], [1536, 6, 256], [1536, 8, 256], [1536, 16, 256]
111+
]
112+
113+
# With security margin
114+
print("--- Table x^5 WITH security margin ---")
115+
print_latex_table_combinations(x_5_combinations, 5, True)
116+
117+
# Without security margin
118+
print("--- Table x^5 WITHOUT security margin ---")
119+
print_latex_table_combinations(x_5_combinations, 5, False)
120+
121+
x_3_combinations = [
122+
[1536, 2, 128], [1536, 4, 128], [1536, 6, 128], [1536, 8, 128], [1536, 16, 128],
123+
[1536, 2, 256], [1536, 4, 256], [1536, 6, 256], [1536, 8, 256], [1536, 16, 256]
124+
]
125+
126+
# With security margin
127+
print("--- Table x^3 WITH security margin ---")
128+
print_latex_table_combinations(x_3_combinations, 3, True)
129+
130+
# Without security margin
131+
print("--- Table x^3 WITHOUT security margin ---")
132+
print_latex_table_combinations(x_3_combinations, 3, False)
133+
134+
x_inv_combinations = [
135+
[1536, 2, 128], [1536, 4, 128], [1536, 6, 128], [1536, 8, 128], [1536, 16, 128],
136+
[1536, 2, 256], [1536, 4, 256], [1536, 6, 256], [1536, 8, 256], [1536, 16, 256]
137+
]
138+
139+
# With security margin
140+
print("--- Table x^(-1) WITH security margin ---")
141+
print_latex_table_combinations(x_inv_combinations, -1, True)
142+
143+
# Without security margin
144+
print("--- Table x^(-1) WITHOUT security margin ---")
145+
print_latex_table_combinations(x_inv_combinations, -1, False)

0 commit comments

Comments
 (0)