Skip to content

Commit e2e3079

Browse files
authored
Merge pull request #248 from Chia-Network/add-checks
add checks
2 parents 7adb58a + 8d81ad0 commit e2e3079

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

src/verifier.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p
4545
{
4646
int form_size = BQFC_FORM_SIZE;
4747
int segment_len = 8 + B_bytes + form_size;
48+
// Enforce all invariants and bounds before the loop
49+
if (form_size <= 0) return false;
50+
if (depth < 0 || proof_blob_len != 2 * form_size + depth * segment_len)
51+
return false;
52+
if (x_s == nullptr || proof_blob == nullptr)
53+
return false;
54+
55+
// All accesses in the loop are now safe
4856
int i = proof_blob_len - segment_len;
4957
form x = DeserializeForm(D, x_s, form_size);
5058

51-
if (proof_blob_len != 2 * form_size + depth * segment_len)
52-
return false;
53-
54-
// Loop depth times
5559
bool is_valid = false;
5660
for (; i >= 2 * form_size; i -= segment_len) {
5761
uint64_t segment_iters = BytesToInt64(&proof_blob[i]);
@@ -68,6 +72,7 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p
6872
iterations -= segment_iters;
6973
}
7074

75+
// Final forms are guaranteed to be in-bounds
7176
VerifyWesolowskiProof(D, x,
7277
DeserializeForm(D, proof_blob, form_size),
7378
DeserializeForm(D, &proof_blob[form_size], form_size),
@@ -79,6 +84,11 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p
7984
bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t& iterations, int last_segment, bool skip_check = false) {
8085
int form_size = BQFC_FORM_SIZE;
8186
int segment_len = 8 + B_bytes + form_size;
87+
if (proof_blob == nullptr) return false;
88+
if (last_segment < 0 || proof_blob_len < 0) return false;
89+
if (proof_blob_len < last_segment) return false;
90+
if ((proof_blob_len - last_segment) % segment_len != 0)
91+
return false;
8292
int i = proof_blob_len - segment_len;
8393
PulmarkReducer reducer;
8494

@@ -110,6 +120,7 @@ bool CheckProofOfTimeNWesolowskiCommon(integer& D, form& x, const uint8_t* proof
110120
std::pair<bool, std::vector<uint8_t>> CheckProofOfTimeNWesolowskiWithB(integer D, integer B, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) {
111121
int form_size = BQFC_FORM_SIZE;
112122
int segment_len = 8 + B_bytes + form_size;
123+
if (x_s == nullptr || proof_blob == nullptr) return {false, {}};
113124
form x = DeserializeForm(D, x_s, form_size);
114125
std::vector<uint8_t> result;
115126
if (proof_blob_len != form_size + depth * segment_len) {
@@ -119,6 +130,7 @@ std::pair<bool, std::vector<uint8_t>> CheckProofOfTimeNWesolowskiWithB(integer D
119130
if (is_valid == false) {
120131
return {false, result};
121132
}
133+
if (form_size > proof_blob_len) return {false, result};
122134
form proof = DeserializeForm(D, proof_blob, form_size);
123135
form y_result;
124136
if (VerifyWesoSegment(D, x, proof, B, iterations, y_result) == -1) {
@@ -129,10 +141,10 @@ std::pair<bool, std::vector<uint8_t>> CheckProofOfTimeNWesolowskiWithB(integer D
129141
return {true, result};
130142
}
131143

132-
// TODO: Perhaps move?
133144
integer GetBFromProof(integer D, const uint8_t* x_s, const uint8_t* proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) {
134145
int form_size = BQFC_FORM_SIZE;
135146
int segment_len = 8 + B_bytes + form_size;
147+
if (x_s == nullptr || proof_blob == nullptr) throw std::runtime_error("Invalid proof.");
136148
form x = DeserializeForm(D, x_s, form_size);
137149
if (proof_blob_len != 2 * form_size + depth * segment_len) {
138150
throw std::runtime_error("Invalid proof.");
@@ -141,6 +153,7 @@ integer GetBFromProof(integer D, const uint8_t* x_s, const uint8_t* proof_blob,
141153
if (is_valid == false) {
142154
throw std::runtime_error("Invalid proof.");
143155
}
156+
if (form_size > proof_blob_len) throw std::runtime_error("Invalid proof.");
144157
form y = DeserializeForm(D, proof_blob, form_size);
145158
return GetB(D, x, y);
146159
}

0 commit comments

Comments
 (0)