11
11
12
12
const uint8_t DEFAULT_ELEMENT[] = { 0x08 };
13
13
14
- int VerifyWesoSegment (integer & D , form x , form proof , integer & B , uint64_t iters , form & out_y )
14
+ int VerifyWesoSegment (integer &D, form x, form proof, integer &B, uint64_t iters, bool skip_check, form &out_y)
15
15
{
16
16
PulmarkReducer reducer;
17
17
integer L = root (-D, 4 );
18
18
integer r = FastPow (2 , iters, B);
19
19
form f1 = FastPowFormNucomp (proof, D, B, L, reducer);
20
20
form f2 = FastPowFormNucomp (x, D, r, L, reducer);
21
21
out_y = f1 * f2;
22
-
22
+ // Optimize to only get `out_y` without verification, when not needed.
23
+ if (skip_check) {
24
+ return 0 ;
25
+ }
23
26
return B == GetB (D, x, out_y) ? 0 : -1 ;
24
27
}
25
28
@@ -41,30 +44,39 @@ void VerifyWesolowskiProof(integer &D, form x, form y, form proof, uint64_t iter
41
44
}
42
45
}
43
46
44
- bool CheckProofOfTimeNWesolowski (integer D , const uint8_t * x_s , const uint8_t * proof_blob , int32_t proof_blob_len , uint64_t iterations , uint64 disc_size_bits , int32_t depth )
45
- {
47
+ 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 ) {
46
48
int form_size = BQFC_FORM_SIZE;
47
49
int segment_len = 8 + B_bytes + form_size;
48
50
int i = proof_blob_len - segment_len;
49
- form x = DeserializeForm (D , x_s , form_size );
50
51
51
- if (proof_blob_len != 2 * form_size + depth * segment_len )
52
- return false;
53
-
54
- // Loop depth times
55
- bool is_valid = false;
56
- for (; i >= 2 * form_size ; i -= segment_len ) {
52
+ for (; i >= last_segment; i -= segment_len) {
57
53
uint64_t segment_iters = BytesToInt64 (&proof_blob[i]);
58
54
form proof = DeserializeForm (D, &proof_blob[i + 8 + B_bytes], form_size);
59
55
integer B (&proof_blob[i + 8 ], B_bytes);
60
56
form xnew;
61
- if (VerifyWesoSegment (D , x , proof , B , segment_iters , xnew ))
57
+ if (VerifyWesoSegment (D, x, proof, B, segment_iters, skip_check, xnew))
62
58
return false ;
63
59
64
60
x = xnew;
61
+ if (segment_iters > iterations) {
62
+ return false ;
63
+ }
65
64
iterations -= segment_iters;
66
65
}
66
+ return true ;
67
+ }
67
68
69
+ bool CheckProofOfTimeNWesolowski (integer D, const uint8_t * x_s, const uint8_t * proof_blob, int32_t proof_blob_len, uint64_t iterations, int32_t depth) {
70
+ int form_size = BQFC_FORM_SIZE;
71
+ int segment_len = 8 + B_bytes + form_size;
72
+ form x = DeserializeForm (D, x_s, form_size);
73
+ if (proof_blob_len != 2 * form_size + depth * segment_len) {
74
+ return false ;
75
+ }
76
+ bool is_valid = CheckProofOfTimeNWesolowskiCommon (D, x, proof_blob, proof_blob_len, iterations, 2 * form_size);
77
+ if (is_valid == false ) {
78
+ return false ;
79
+ }
68
80
VerifyWesolowskiProof (D, x,
69
81
DeserializeForm (D, proof_blob, form_size),
70
82
DeserializeForm (D, &proof_blob[form_size], form_size),
@@ -73,4 +85,42 @@ bool CheckProofOfTimeNWesolowski(integer D, const uint8_t* x_s, const uint8_t* p
73
85
return is_valid;
74
86
}
75
87
88
+ 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) {
89
+ int form_size = BQFC_FORM_SIZE;
90
+ int segment_len = 8 + B_bytes + form_size;
91
+ form x = DeserializeForm (D, x_s, form_size);
92
+ std::vector<uint8_t > result;
93
+ if (proof_blob_len != form_size + depth * segment_len) {
94
+ return {false , result};
95
+ }
96
+ bool is_valid = CheckProofOfTimeNWesolowskiCommon (D, x, proof_blob, proof_blob_len, iterations, form_size);
97
+ if (is_valid == false ) {
98
+ return {false , result};
99
+ }
100
+ form proof = DeserializeForm (D, proof_blob, form_size);
101
+ form y_result;
102
+ if (VerifyWesoSegment (D, x, proof, B, iterations, /* skip_check=*/ false , y_result) == -1 ) {
103
+ return {false , result};
104
+ }
105
+ int d_bits = D.num_bits ();
106
+ result = SerializeForm (y_result, d_bits);
107
+ return {true , result};
108
+ }
109
+
110
+ // TODO: Perhaps move?
111
+ 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) {
112
+ int form_size = BQFC_FORM_SIZE;
113
+ int segment_len = 8 + B_bytes + form_size;
114
+ form x = DeserializeForm (D, x_s, form_size);
115
+ if (proof_blob_len != 2 * form_size + depth * segment_len) {
116
+ throw std::runtime_error (" Invalid proof." );
117
+ }
118
+ bool is_valid = CheckProofOfTimeNWesolowskiCommon (D, x, proof_blob, proof_blob_len, iterations, 2 * form_size, true );
119
+ if (is_valid == false ) {
120
+ throw std::runtime_error (" Invalid proof." );
121
+ }
122
+ form y = DeserializeForm (D, proof_blob, form_size);
123
+ return GetB (D, x, y);
124
+ }
125
+
76
126
#endif // VERIFIER_H
0 commit comments