CDT  v4.2.0
инструменты разработчика
crypto_ext.hpp
См. документацию.
1
5#pragma once
6
7#include "check.hpp"
8#include "fixed_bytes.hpp"
9#include "varint.hpp"
10#include "serialize.hpp"
11
12#include <array>
13
14namespace eosio {
15
16 namespace internal_use_do_not_use {
17 extern "C" {
18
19 struct __attribute__((aligned (16))) capi_checksum256_ext { uint8_t hash[32]; };
20
21 __attribute__((eosio_wasm_import))
22 int32_t alt_bn128_add( const char* op1, uint32_t op1_len, const char* op2, uint32_t op2_len, char* result, uint32_t result_len);
23
24 __attribute__((eosio_wasm_import))
25 int32_t alt_bn128_mul( const char* g1, uint32_t g1_len, const char* scalar, uint32_t scalar_len, char* result, uint32_t result_len);
26
27 __attribute__((eosio_wasm_import))
28 int32_t alt_bn128_pair( const char* pairs, uint32_t pairs_len);
29
30 __attribute__((eosio_wasm_import))
31 int32_t mod_exp( const char* base, uint32_t base_len, const char* exp, uint32_t exp_len, const char* mod, uint32_t mod_len, char* result, uint32_t result_len);
32
33 __attribute__((eosio_wasm_import))
34 int32_t blake2_f( uint32_t rounds, const char* state, uint32_t state_len, const char* msg, uint32_t msg_len, const char* t0_offset, uint32_t t0_len, const char* t1_offset, uint32_t t1_len, int32_t final, char* result, uint32_t result_len);
35
36 __attribute__((eosio_wasm_import))
37 int32_t k1_recover( const char* sig, uint32_t sig_len, const char* dig, uint32_t dig_len, char* pub, uint32_t pub_len);
38
39 __attribute__((eosio_wasm_import))
40 void sha3( const char* data, uint32_t data_len, char* hash, uint32_t hash_len, int32_t keccak );
41 }
42
43 static inline auto sha3_helper(const char* data, uint32_t length, bool keccak) {
44 internal_use_do_not_use::capi_checksum256_ext hash;
45 internal_use_do_not_use::sha3( data, length, (char*)&hash, sizeof(hash), keccak);
46 eosio::checksum256 dg;
47 eosio::datastream<uint8_t*> ds = {&hash.hash[0], sizeof(hash)};
48 ds >> dg;
49 return dg;
50 }
51 }
52
65 template <std::size_t Size = 32>
66 struct ec_point {
70 std::vector<char> x;
71
75 std::vector<char> y;
76
83 ec_point(std::vector<char>& x_, std::vector<char>& y_)
84 :x(x_), y(y_)
85 {
86 eosio::check( x_.size() == y_.size(), "x's size must be equal to y's" );
87 eosio::check ( x_.size() == Size, "point size must match");
88 };
89
95 ec_point(std::vector<char>& p)
96 :x(p.data(), p.data() + Size), y(p.data() + Size, p.data() + p.size())
97 {
98 eosio::check ( p.size() == Size * 2, "point size must match");
99 };
100
104 std::vector<char> serialized() const {
105 std::vector<char> x_and_y( x );
106 x_and_y.insert( x_and_y.end(), y.begin(), y.end() );
107 return x_and_y;
108 }
109 };
110
116 template <std::size_t Size = 32>
121 const char* x;
122
126 const char* y;
127
132
141 ec_point_view(const char* x_, uint32_t x_size, const char* y_, uint32_t y_size)
142 :x(x_), y(y_), size(x_size)
143 {
144 eosio::check ( x_size == y_size, "x's size must be equal to y's");
145 eosio::check ( size == Size, "point size must match");
146 };
147
153 ec_point_view(const std::vector<char>& p)
154 :x(p.data()), y(p.data() + Size), size(Size)
155 {
156 eosio::check ( p.size() == Size * 2, "point size must match");
157 };
158
165 :x(p.x.data()), y(p.y.data()), size(Size)
166 {
167 };
168
172 std::vector<char> serialized() const {
173 std::vector<char> x_and_y( x, x + size );
174 x_and_y.insert( x_and_y.end(), y, y + size );
175 return x_and_y;
176 }
177 };
178
179 static constexpr size_t g1_coordinate_size = 32;
180 static constexpr size_t g2_coordinate_size = 64;
181
186
192 using bigint = std::vector<char>;
193
202 template <typename T>
203 inline g1_point alt_bn128_add( const T& op1, const T& op2 ) {
204 auto op_1 = op1.serialized();
205 auto op_2 = op2.serialized();
206 std::vector<char> buf ( 2 * g1_coordinate_size ); // buffer storing x and y
207 auto ret = internal_use_do_not_use::alt_bn128_add( op_1.data(), op_1.size(), op_2.data(), op_2.size(), buf.data(), buf.size());
208 eosio::check ( ret == 0, "internal_use_do_not_use::alt_bn128_add failed" );
209 return g1_point { buf };
210 }
211
224 inline int32_t alt_bn128_add( const char* op1, uint32_t op1_len, const char* op2, uint32_t op2_len, char* result, uint32_t result_len ) {
226 }
227
236 template <typename T>
237 inline g1_point alt_bn128_mul( const T& g1, const bigint& scalar) {
238 auto g1_bin = g1.serialized();
239 std::vector<char> buf( 2 * g1_coordinate_size ); // buffer storing x and y
240 auto ret = internal_use_do_not_use::alt_bn128_mul( g1_bin.data(), g1_bin.size(), scalar.data(), scalar.size(), buf.data(), buf.size());
241 eosio::check ( ret == 0, "internal_use_do_not_use::alt_bn128_mul failed");
242 return g1_point { buf };
243 }
244
257 inline int32_t alt_bn128_mul( const char* g1, uint32_t g1_len, const char* scalar, uint32_t scalar_len, char* result, uint32_t result_len ) {
259 }
260
268 template <typename G1_T, typename G2_T>
269 inline int32_t alt_bn128_pair( const std::vector<std::pair<G1_T, G2_T>>& pairs ) {
270 std::vector<char> g1_g2_pairs;
271 for ( const auto& pair: pairs ) {
272 auto g1_bin = pair.first.serialized();
273 auto g2_bin = pair.second.serialized();
274 g1_g2_pairs.insert( g1_g2_pairs.end(), g1_bin.begin(), g1_bin.end() );
275 g1_g2_pairs.insert( g1_g2_pairs.end(), g2_bin.begin(), g2_bin.end() );
276 }
277 return internal_use_do_not_use::alt_bn128_pair( g1_g2_pairs.data(), g1_g2_pairs.size() );
278 }
279
288 inline int32_t alt_bn128_pair( const char* pairs, uint32_t pairs_len ) {
290 }
291
304 inline int32_t mod_exp( const bigint& base, const bigint& exp, const bigint& mod, bigint& result) {
305 eosio::check( result.size() >= mod.size(), "mod_exp result parameter's size must be >= mod's size" );
306 auto ret = internal_use_do_not_use::mod_exp( base.data(), base.size(), exp.data(), exp.size(), mod.data(), mod.size(), result.data(), result.size());
307 return ret;
308 }
309
326 inline int32_t mod_exp( const char* base, uint32_t base_len, const char* exp, uint32_t exp_len, const char* mod, uint32_t mod_len, char* result, uint32_t result_len ) {
328 }
329
330 static constexpr size_t blake2f_result_size = 64;
331
346 inline int32_t blake2_f( uint32_t rounds, const std::vector<char>& state, const std::vector<char>& msg, const std::vector<char>& t0_offset, const std::vector<char>& t1_offset, bool final, std::vector<char>& result) {
347 eosio::check( result.size() >= blake2f_result_size, "blake2_f result parameter's size must be >= 64" );
348 return internal_use_do_not_use::blake2_f( rounds, state.data(), state.size(), msg.data(), msg.size(), t0_offset.data(), t0_offset.size(), t1_offset.data(), t1_offset.size(), final, result.data(), result.size());
349 }
350
370 inline int32_t blake2_f( uint32_t rounds, const char* state, uint32_t state_len, const char* msg, uint32_t msg_len,
371 const char* t0_offset, uint32_t t0_len, const char* t1_offset, uint32_t t1_len, int32_t final, char* result, uint32_t result_len) {
373 }
374
383 inline eosio::checksum256 sha3(const char* data, uint32_t length) {
384 return internal_use_do_not_use::sha3_helper(data, length, false);
385 }
386
396 inline void assert_sha3(const char* data, uint32_t length, const eosio::checksum256& hash) {
397 const auto& res = internal_use_do_not_use::sha3_helper(data, length, false);
398 check( hash == res, "SHA3 hash of `data` does not match given `hash`");
399 }
400
409 inline eosio::checksum256 keccak(const char* data, uint32_t length) {
410 return internal_use_do_not_use::sha3_helper(data, length, true);
411 }
412
422 inline void assert_keccak(const char* data, uint32_t length, const eosio::checksum256& hash) {
423 const auto& res = internal_use_do_not_use::sha3_helper(data, length, true);
424 check( hash == res, "Keccak hash of `data` does not match given `hash`");
425 }
426
440 inline int32_t k1_recover( const char* sig, uint32_t sig_len, const char* dig, uint32_t dig_len, char* pub, uint32_t pub_len ) {
442 }
443}