1
+ // Copyright 2025 @yangjucai.
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
+
15
+ #pragma once
16
+
17
+ #include < optional>
18
+ #include < stdexcept>
19
+ #include < string>
20
+ #include < variant>
21
+ #include < vector>
22
+
23
+ namespace examples ::zkp {
24
+
25
+ // Represents an error in proof creation, verification, or parsing.
26
+ class ProofError : public std ::runtime_error {
27
+ public:
28
+ enum class ErrorType {
29
+ // This error occurs when a proof failed to verify.
30
+ VerificationError,
31
+ // This error occurs when the proof encoding is malformed.
32
+ FormatError,
33
+ // This error occurs during proving if the number of blinding
34
+ // factors does not match the number of values.
35
+ WrongNumBlindingFactors,
36
+ // This error occurs when attempting to create a proof with
37
+ // bitsize other than 8, 16, 32, or 64.
38
+ InvalidBitsize,
39
+ // This error occurs when attempting to create an aggregated
40
+ // proof with non-power-of-two aggregation size.
41
+ InvalidAggregation,
42
+ // This error occurs when there are insufficient generators for the proof.
43
+ InvalidGeneratorsLength,
44
+ // This error occurs when inputs are the incorrect length for the proof.
45
+ InvalidInputLength,
46
+ // This error results from an internal error during proving.
47
+ ProvingError
48
+ };
49
+
50
+ explicit ProofError (ErrorType type, const std::string& msg = " " )
51
+ : std::runtime_error(GetErrorMessage(type, msg)), type_(type) {}
52
+
53
+ ErrorType GetType () const { return type_; }
54
+
55
+ private:
56
+ static std::string GetErrorMessage (ErrorType type, const std::string& msg) {
57
+ switch (type) {
58
+ case ErrorType::VerificationError:
59
+ return " Proof verification failed." ;
60
+ case ErrorType::FormatError:
61
+ return " Proof data could not be parsed." ;
62
+ case ErrorType::WrongNumBlindingFactors:
63
+ return " Wrong number of blinding factors supplied." ;
64
+ case ErrorType::InvalidBitsize:
65
+ return " Invalid bitsize, must have n = 8,16,32,64." ;
66
+ case ErrorType::InvalidAggregation:
67
+ return " Invalid aggregation size, m must be a power of 2." ;
68
+ case ErrorType::InvalidGeneratorsLength:
69
+ return " Invalid generators size, too few generators for proof" ;
70
+ case ErrorType::InvalidInputLength:
71
+ return " Invalid input size, incorrect input length for proof" ;
72
+ case ErrorType::ProvingError:
73
+ return " Internal error during proof creation: " + msg;
74
+ }
75
+ return " Unknown error" ;
76
+ }
77
+
78
+ ErrorType type_;
79
+ };
80
+
81
+ // Result type for operations that can fail
82
+ template <typename T = void >
83
+ class Result {
84
+ public:
85
+ // Construct a successful result
86
+ static Result<T> Ok (const T& value) { return Result<T>(value); }
87
+
88
+ static Result<T> Ok (T&& value) { return Result<T>(std::move (value)); }
89
+
90
+ // Construct an error result
91
+ static Result<T> Err (const ProofError& error) { return Result<T>(error); }
92
+
93
+ // Check if result is successful
94
+ bool IsOk () const { return !error_.has_value (); }
95
+
96
+ // Get the value (must check IsOk() first)
97
+ const T& Value () const {
98
+ if (!IsOk ()) {
99
+ throw std::runtime_error (" Attempted to get value from error result" );
100
+ }
101
+ return value_;
102
+ }
103
+
104
+ T&& TakeValue() && {
105
+ if (!IsOk ()) {
106
+ throw std::runtime_error (" Attempted to take value from error result" );
107
+ }
108
+ return std::move (value_);
109
+ }
110
+
111
+ // Get the error (must check !IsOk() first)
112
+ const ProofError& Error () const {
113
+ if (IsOk ()) {
114
+ throw std::runtime_error (" Attempted to get error from successful result" );
115
+ }
116
+ return *error_;
117
+ }
118
+
119
+ private:
120
+ explicit Result (const T& value) : value_(value) {}
121
+ explicit Result (T&& value) : value_(std::move(value)) {}
122
+ explicit Result (const ProofError& error) : error_(error) {}
123
+
124
+ T value_;
125
+ std::optional<ProofError> error_;
126
+ };
127
+
128
+ // Specialization for void
129
+ template <>
130
+ class Result <void > {
131
+ public:
132
+ static Result<void > Ok () { return Result<void >(); }
133
+
134
+ static Result<void > Err (const ProofError& error) {
135
+ return Result<void >(error);
136
+ }
137
+
138
+ bool IsOk () const { return !error_.has_value (); }
139
+
140
+ const ProofError& Error () const {
141
+ if (IsOk ()) {
142
+ throw std::runtime_error (" Attempted to get error from successful result" );
143
+ }
144
+ return *error_;
145
+ }
146
+
147
+ private:
148
+ Result () = default ;
149
+ explicit Result (const ProofError& error) : error_(error) {}
150
+
151
+ std::optional<ProofError> error_;
152
+ };
153
+
154
+ } // namespace examples::zkp
0 commit comments