Skip to content

Commit 07951ab

Browse files
authored
Fix stack overflow in verifier (#112)
1 parent bdd52e7 commit 07951ab

File tree

1 file changed

+41
-31
lines changed

1 file changed

+41
-31
lines changed

lib/chiavdf/fast_vdf/verifier.h

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,24 @@
66
#include "proof_common.h"
77
#include "create_discriminant.h"
88

9-
const int kMaxBytesProof = 100000;
9+
void VerifyWesolowskiProof(integer &D, form x, form y, form proof, int iters, bool &is_valid)
10+
{
11+
PulmarkReducer reducer;
12+
int int_size = (D.num_bits() + 16) >> 4;
13+
integer L = root(-D, 4);
14+
integer B = GetB(D, x, y);
15+
integer r = FastPow(2, iters, B);
16+
form f1 = FastPowFormNucomp(proof, D, B, L, reducer);
17+
form f2 = FastPowFormNucomp(x, D, r, L, reducer);
18+
if (f1 * f2 == y)
19+
{
20+
is_valid = true;
21+
}
22+
else
23+
{
24+
is_valid = false;
25+
}
26+
}
1027

1128
integer ConvertBytesToInt(uint8_t *bytes, int start_index, int end_index)
1229
{
@@ -52,31 +69,12 @@ std::vector<form> DeserializeProof(uint8_t *proof_bytes, int proof_len, integer
5269
return proof;
5370
}
5471

55-
void VerifyWesolowskiProof(integer &D, form x, form y, form proof, int iters, bool &is_valid)
56-
{
57-
PulmarkReducer reducer;
58-
int int_size = (D.num_bits() + 16) >> 4;
59-
integer L = root(-D, 4);
60-
integer B = GetB(D, x, y);
61-
integer r = FastPow(2, iters, B);
62-
form f1 = FastPowFormNucomp(proof, D, B, L, reducer);
63-
form f2 = FastPowFormNucomp(x, D, r, L, reducer);
64-
if (f1 * f2 == y)
65-
{
66-
is_valid = true;
67-
}
68-
else
69-
{
70-
is_valid = false;
71-
}
72-
}
73-
7472
bool CheckProofOfTimeNWesolowskiInner(integer &D, form x, uint8_t *proof_blob,
7573
int blob_len, int iters, int int_size,
7674
std::vector<int> iter_list, int recursion)
7775
{
78-
uint8_t result_bytes[kMaxBytesProof];
79-
uint8_t proof_bytes[kMaxBytesProof];
76+
uint8_t* result_bytes = new uint8_t[2 * int_size];
77+
uint8_t* proof_bytes = new uint8_t[blob_len - 2 * int_size];
8078
memcpy(result_bytes, proof_blob, 2 * int_size);
8179
memcpy(proof_bytes, proof_blob + 2 * int_size, blob_len - 2 * int_size);
8280
form y = DeserializeForm(D, result_bytes, int_size);
@@ -87,32 +85,44 @@ bool CheckProofOfTimeNWesolowskiInner(integer &D, form x, uint8_t *proof_blob,
8785
{
8886
bool is_valid;
8987
VerifyWesolowskiProof(D, x, y, proof[0], iters, is_valid);
88+
delete[] result_bytes;
89+
delete[] proof_bytes;
9090
return is_valid;
9191
}
9292
else
9393
{
94-
if (!(proof.size() % 2 == 1 && proof.size() > 2))
94+
if (!(proof.size() % 2 == 1 && proof.size() > 2)) {
95+
delete[] result_bytes;
96+
delete[] proof_bytes;
9597
return false;
98+
}
9699
int iters1 = iter_list[iter_list.size() - 1];
97100
int iters2 = iters - iters1;
98101
bool ver_outer;
99-
std::thread t(VerifyWesolowskiProof, std::ref(D), x, proof[proof.size() - 2], proof[proof.size() - 1], iters1, std::ref(ver_outer));
100-
uint8_t new_proof_bytes[kMaxBytesProof];
102+
VerifyWesolowskiProof(D, x, proof[proof.size() - 2], proof[proof.size() - 1], iters1, ver_outer);
103+
if (!ver_outer) {
104+
delete[] result_bytes;
105+
delete[] proof_bytes;
106+
return false;
107+
}
108+
uint8_t* new_proof_bytes = new uint8_t[blob_len - 4 * int_size];
101109
for (int i = 0; i < blob_len - 4 * int_size; i++)
102110
new_proof_bytes[i] = proof_blob[i];
103111
iter_list.pop_back();
104112
bool ver_inner = CheckProofOfTimeNWesolowskiInner(D, proof[proof.size() - 2], new_proof_bytes, blob_len - 4 * int_size, iters2, int_size, iter_list, recursion - 1);
105-
t.join();
106-
if (ver_inner && ver_outer)
113+
delete[] result_bytes;
114+
delete[] proof_bytes;
115+
delete[] new_proof_bytes;
116+
if (ver_inner)
107117
return true;
108118
return false;
109119
}
110120
}
111121

112-
bool CheckProofOfTimeNWesolowski(integer &D, form x, uint8_t *proof_blob, int proof_blob_len, int iters, int recursion)
122+
bool CheckProofOfTimeNWesolowski(integer D, form x, uint8_t *proof_blob, int proof_blob_len, int iters, int recursion)
113123
{
114124
int int_size = (D.num_bits() + 16) >> 4;
115-
uint8_t new_proof_blob[kMaxBytesProof];
125+
uint8_t* new_proof_blob = new uint8_t[proof_blob_len];
116126
int new_cnt = 4 * int_size;
117127
memcpy(new_proof_blob, proof_blob, new_cnt);
118128
std::vector<int> iter_list;
@@ -126,7 +136,8 @@ bool CheckProofOfTimeNWesolowski(integer &D, form x, uint8_t *proof_blob, int pr
126136
new_cnt += 4 * int_size;
127137
}
128138
bool is_valid = CheckProofOfTimeNWesolowskiInner(D, x, new_proof_blob, new_cnt, iters, int_size, iter_list, recursion);
129-
return is_valid;
139+
delete[] new_proof_blob;
140+
return is_valid;
130141
}
131142

132143
std::vector<uint8_t> HexToBytes(char *hex_proof)
@@ -180,7 +191,6 @@ bool CheckProofOfTimeType(ProofOfTimeType &proof)
180191
form y = form::from_abd(proof.a, proof.b, discriminant);
181192
std::vector<uint8_t> proof_blob = SerializeForm(y, int_size);
182193
proof_blob.insert(proof_blob.end(), proof.witness.begin(), proof.witness.end());
183-
184194
result = CheckProofOfTimeNWesolowski(discriminant, x, proof_blob.data(), proof_blob.size(), proof.iterations_needed, proof.witness_type);
185195
}
186196
catch (std::exception &e)

0 commit comments

Comments
 (0)