Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
crypto.cpp
Go to the documentation of this file.
8#include <fc/crypto/sha3.hpp>
10
11namespace {
12 uint32_t ceil_log2(uint32_t n)
13 {
14 if (n <= 1) {
15 return 0;
16 }
17 return 32 - __builtin_clz(n - 1);
18 };
19}
20
21namespace sysio { namespace chain { namespace webassembly {
22
25 legacy_span<const char> pub ) const {
28 datastream<const char*> ds( sig.data(), sig.size() );
29 datastream<const char*> pubds ( pub.data(), pub.size() );
30
31 fc::raw::unpack( ds, s );
32 fc::raw::unpack( pubds, p );
33
34 SYS_ASSERT(s.which() < context.db.get<protocol_state_object>().num_supported_key_types, unactivated_signature_type,
35 "Unactivated signature type used during assert_recover_key");
36 SYS_ASSERT(p.which() < context.db.get<protocol_state_object>().num_supported_key_types, unactivated_key_type,
37 "Unactivated key type used when creating assert_recover_key");
38
39 if(context.control.is_producing_block())
40 SYS_ASSERT(s.variable_size() <= context.control.configured_subjective_signature_length_limit(),
41 sig_variable_size_limit_exception, "signature variable length component size greater than subjective maximum");
42
43 auto check = fc::crypto::public_key( s, *digest, false );
44 SYS_ASSERT( check == p, crypto_api_exception, "Error expected key different than recovered key" );
45 }
46
49 legacy_span<char> pub ) const {
51 datastream<const char*> ds( sig.data(), sig.size() );
52 fc::raw::unpack(ds, s);
53
54 SYS_ASSERT(s.which() < context.db.get<protocol_state_object>().num_supported_key_types, unactivated_signature_type,
55 "Unactivated signature type used during recover_key");
56
57 if(context.control.is_producing_block())
58 SYS_ASSERT(s.variable_size() <= context.control.configured_subjective_signature_length_limit(),
59 sig_variable_size_limit_exception, "signature variable length component size greater than subjective maximum");
60
61
62 auto recovered = fc::crypto::public_key(s, *digest, false);
63
64 // the key types newer than the first 2 may be varible in length
65 if (s.which() >= config::genesis_num_supported_key_types ) {
66 SYS_ASSERT(pub.size() >= 33, wasm_execution_error,
67 "destination buffer must at least be able to hold an ECC public key");
68 auto packed_pubkey = fc::raw::pack(recovered);
69 auto copy_size = std::min<size_t>(pub.size(), packed_pubkey.size());
70 std::memcpy(pub.data(), packed_pubkey.data(), copy_size);
71 return packed_pubkey.size();
72 } else {
73 // legacy behavior, key types 0 and 1 always pack to 33 bytes.
74 // this will do one less copy for those keys while maintaining the rules of
75 // [0..33) dest sizes: assert (asserts in fc::raw::pack)
76 // [33..inf) dest sizes: return packed size (always 33)
77 datastream<char*> out_ds( pub.data(), pub.size() );
78 fc::raw::pack(out_ds, recovered);
79 return out_ds.tellp();
80 }
81 }
82
84 auto result = context.trx_context.hash_with_checktime<fc::sha256>( data.data(), data.size() );
85 SYS_ASSERT( result == *hash_val, crypto_api_exception, "hash mismatch" );
86 }
87
89 auto result = context.trx_context.hash_with_checktime<fc::sha1>( data.data(), data.size() );
90 SYS_ASSERT( result == *hash_val, crypto_api_exception, "hash mismatch" );
91 }
92
94 auto result = context.trx_context.hash_with_checktime<fc::sha512>( data.data(), data.size() );
95 SYS_ASSERT( result == *hash_val, crypto_api_exception, "hash mismatch" );
96 }
97
99 auto result = context.trx_context.hash_with_checktime<fc::ripemd160>( data.data(), data.size() );
100 SYS_ASSERT( result == *hash_val, crypto_api_exception, "hash mismatch" );
101 }
102
104 *hash_val = context.trx_context.hash_with_checktime<fc::sha1>( data.data(), data.size() );
105 }
106
108 *hash_val = context.trx_context.hash_with_checktime<fc::sha256>( data.data(), data.size() );
109 }
110
112 *hash_val = context.trx_context.hash_with_checktime<fc::sha512>( data.data(), data.size() );
113 }
114
116 *hash_val = context.trx_context.hash_with_checktime<fc::ripemd160>( data.data(), data.size() );
117 }
118
120 bytes bop1(op1.data(), op1.data() + op1.size());
121 bytes bop2(op2.data(), op2.data() + op2.size());
122
123 auto maybe_err = fc::alt_bn128_add(bop1, bop2);
124 if(std::holds_alternative<fc::alt_bn128_error>(maybe_err)) {
126 }
127
128 const auto& res = std::get<bytes>(maybe_err);
129
130 if( result.size() < res.size() )
132
133 std::memcpy( result.data(), res.data(), res.size() );
135 }
136
138 bytes bg1_point(g1_point.data(), g1_point.data() + g1_point.size());
139 bytes bscalar(scalar.data(), scalar.data() + scalar.size());
140
141 auto maybe_err = fc::alt_bn128_mul(bg1_point, bscalar);
142 if(std::holds_alternative<fc::alt_bn128_error>(maybe_err)) {
144 }
145
146 const auto& res = std::get<bytes>(maybe_err);
147
148 if( result.size() < res.size() )
150
151 std::memcpy( result.data(), res.data(), res.size() );
153 }
154
156 bytes bg1_g2_pairs(g1_g2_pairs.data(), g1_g2_pairs.data() + g1_g2_pairs.size());
157
158 auto checktime = [this]() { context.trx_context.checktime(); };
159 auto res = fc::alt_bn128_pair(bg1_g2_pairs, checktime);
160 if(std::holds_alternative<fc::alt_bn128_error>(res)) {
162 }
163
164 return !std::get<bool>(res);
165 }
166
169 span<const char> modulus,
170 span<char> out) const {
171 if (context.control.is_producing_block()) {
172 unsigned int base_modulus_size = std::max(base.size(), modulus.size());
173
174 if (base_modulus_size < exp.size()) {
175 SYS_THROW(subjective_block_production_exception,
176 "mod_exp restriction: exponent bit size cannot exceed bit size of either base or modulus");
177 }
178
179 static constexpr uint64_t bit_calc_limit = 106;
180
181 uint64_t bit_calc = 5 * ceil_log2(exp.size()) + 8 * ceil_log2(base_modulus_size);
182
183 if (bit_calc_limit < bit_calc) {
184 SYS_THROW(subjective_block_production_exception,
185 "mod_exp restriction: bit size too large for input arguments");
186 }
187 }
188
189 bytes bbase(base.data(), base.data() + base.size());
190 bytes bexp(exp.data(), exp.data() + exp.size());
191 bytes bmod(modulus.data(), modulus.data() + modulus.size());
192
193 auto maybe_err = fc::modexp(bbase, bexp, bmod);
194 if(std::holds_alternative<fc::modular_arithmetic_error>(maybe_err)) {
196 }
197
198 const auto& res = std::get<bytes>(maybe_err);
199
200 if( out.size() < res.size() )
202
203 std::memcpy( out.data(), res.data(), res.size() );
205 }
206
209 span<const char> message,
210 span<const char> t0_offset,
211 span<const char> t1_offset,
212 int32_t final,
213 span<char> out) const {
214
215 bool _final = final == 1;
216 bytes bstate(state.data(), state.data() + state.size());
217 bytes bmessage(message.data(), message.data() + message.size());
218 bytes bt0_offset(t0_offset.data(), t0_offset.data() + t0_offset.size());
219 bytes bt1_offset(t1_offset.data(), t1_offset.data() + t1_offset.size());
220
221 auto checktime = [this]() { context.trx_context.checktime(); };
222
223 auto maybe_err = fc::blake2b(rounds, bstate, bmessage, bt0_offset, bt1_offset, _final, checktime);
224 if(std::holds_alternative<fc::blake2b_error>(maybe_err)) {
226 }
227
228 const auto& res = std::get<bytes>(maybe_err);
229
230 if( out.size() < res.size() )
232
233 std::memcpy( out.data(), res.data(), res.size() );
235 }
236
237 void interface::sha3( span<const char> input, span<char> output, int32_t keccak ) const {
238 bool _keccak = keccak == 1;
239 const size_t bs = sysio::chain::config::hashing_checktime_block_size;
240 const char* data = input.data();
241 uint32_t datalen = input.size();
243 while ( datalen > bs ) {
244 enc.write( data, bs);
245 data += bs;
246 datalen -= bs;
247 context.trx_context.checktime();
248 }
249 enc.write( data, datalen);
250 auto res = enc.result(!_keccak);
251
252 auto copy_size = std::min( output.size(), res.data_size() );
253 std::memcpy( output.data(), res.data(), copy_size );
254 }
255
257 bytes bsignature(signature.data(), signature.data() + signature.size());
258 bytes bdigest(digest.data(), digest.data() + digest.size());
259
260 auto maybe_err = fc::k1_recover(bsignature, bdigest);
261 if( std::holds_alternative<fc::k1_recover_error>(maybe_err)) {
263 }
264
265 const auto& res = std::get<bytes>(maybe_err);
266
267 if( pub.size() < res.size() )
269
270 std::memcpy( pub.data(), res.data(), res.size() );
272 }
273
274}}} // ns sysio::chain::webassembly
const mie::Vuint & p
Definition bn.cpp:27
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
const char * data() const
Definition sha256.cpp:31
sha3 result(bool is_nist=true)
Definition sha3.cpp:217
void write(const char *d, uint32_t dlen)
Definition sha3.cpp:213
Maintains global state information about consensus protocol rules.
void assert_recover_key(legacy_ptr< const fc::sha256 > digest, legacy_span< const char > sig, legacy_span< const char > pub) const
Definition crypto.cpp:23
int32_t recover_key(legacy_ptr< const fc::sha256 > digest, legacy_span< const char > sig, legacy_span< char > pub) const
Definition crypto.cpp:47
void sha3(span< const char > data, span< char > hash_val, int32_t keccak) const
Definition crypto.cpp:237
void sha1(legacy_span< const char > data, legacy_ptr< fc::sha1 > hash_val) const
Definition crypto.cpp:103
void sha256(legacy_span< const char > data, legacy_ptr< fc::sha256 > hash_val) const
Definition crypto.cpp:107
int32_t alt_bn128_mul(span< const char > g1_point, span< const char > scalar, span< char > result) const
Definition crypto.cpp:137
int32_t alt_bn128_add(span< const char > op1, span< const char > op2, span< char > result) const
Definition crypto.cpp:119
void sha512(legacy_span< const char > data, legacy_ptr< fc::sha512 > hash_val) const
Definition crypto.cpp:111
int32_t blake2_f(uint32_t rounds, span< const char > state, span< const char > message, span< const char > t0_offset, span< const char > t1_offset, int32_t final, span< char > result) const
Definition crypto.cpp:207
void assert_sha512(legacy_span< const char > data, legacy_ptr< const fc::sha512 > hash_val) const
Definition crypto.cpp:93
int32_t k1_recover(span< const char > signature, span< const char > digest, span< char > pub) const
Definition crypto.cpp:256
void assert_sha1(legacy_span< const char > data, legacy_ptr< const fc::sha1 > hash_val) const
Definition crypto.cpp:88
void assert_ripemd160(legacy_span< const char > data, legacy_ptr< const fc::ripemd160 > hash_val) const
Definition crypto.cpp:98
void ripemd160(legacy_span< const char > data, legacy_ptr< fc::ripemd160 > hash_val) const
Definition crypto.cpp:115
int32_t mod_exp(span< const char > base, span< const char > exp, span< const char > modulus, span< char > out) const
Definition crypto.cpp:167
int32_t alt_bn128_pair(span< const char > g1_g2_pairs) const
Definition crypto.cpp:155
void assert_sha256(legacy_span< const char > data, legacy_ptr< const fc::sha256 > hash_val) const
Definition crypto.cpp:83
constexpr std::size_t size() const noexcept
Definition span.hpp:73
constexpr T * data() const noexcept
Definition span.hpp:72
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
fc::sha256 digest(const T &value)
Definition digest.hpp:9
std::variant< modular_arithmetic_error, bytes > modexp(const bytes &_base, const bytes &_exponent, const bytes &_modulus)
std::variant< blake2b_error, bytes > blake2b(uint32_t _rounds, const bytes &_h, const bytes &_m, const bytes &_t0_offset, const bytes &_t1_offset, bool _f, const yield_function_t &yield)
Definition blake2.cpp:105
bytes signature
Definition pke.hpp:17
std::variant< alt_bn128_error, bytes > alt_bn128_add(const bytes &op1, const bytes &op2)
std::variant< k1_recover_error, bytes > k1_recover(const bytes &signature, const bytes &digest)
std::variant< alt_bn128_error, bytes > alt_bn128_mul(const bytes &g1_point, const bytes &scalar)
std::variant< alt_bn128_error, bool > alt_bn128_pair(const bytes &g1_g2_pairs, const yield_function_t &yield)
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
unsigned __int64 uint64_t
Definition stdint.h:136
CK_ULONG datalen
bool pub
char * s