mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'testnet' into accelerator
This commit is contained in:
commit
6df6f182bf
56 changed files with 2112 additions and 502 deletions
|
@ -318,20 +318,20 @@ endif()
|
|||
target_include_directories(ton_crypto SYSTEM PUBLIC $<BUILD_INTERFACE:${OPENSSL_INCLUDE_DIR}>)
|
||||
|
||||
add_dependencies(ton_crypto blst)
|
||||
add_dependencies(ton_crypto_core secp256k1)
|
||||
|
||||
target_include_directories(ton_crypto PRIVATE ${BLST_INCLUDE_DIR})
|
||||
target_link_libraries(ton_crypto PRIVATE ${BLST_LIB})
|
||||
|
||||
if (NOT USE_EMSCRIPTEN)
|
||||
find_package(Secp256k1 REQUIRED)
|
||||
endif()
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
|
||||
if (MSVC)
|
||||
find_package(Sodium REQUIRED)
|
||||
target_compile_definitions(ton_crypto PUBLIC SODIUM_STATIC)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_link_libraries(ton_crypto PUBLIC ${SECP256K1_LIBRARY})
|
||||
elseif (ANDROID OR EMSCRIPTEN)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
elseif (EMSCRIPTEN)
|
||||
target_link_libraries(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_LIBRARY}>)
|
||||
target_link_libraries(ton_crypto PUBLIC $<BUILD_INTERFACE:${SECP256K1_LIBRARY}>)
|
||||
else()
|
||||
if (NOT SODIUM_FOUND)
|
||||
|
@ -340,11 +340,10 @@ else()
|
|||
message(STATUS "Using Sodium ${SODIUM_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
target_compile_definitions(ton_crypto PUBLIC SODIUM_STATIC)
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SECP256K1_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_link_libraries(ton_crypto PUBLIC ${SECP256K1_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_link_libraries(ton_crypto_core PUBLIC ${SECP256K1_LIBRARY})
|
||||
target_include_directories(ton_crypto_core PUBLIC $<BUILD_INTERFACE:${SODIUM_INCLUDE_DIR}>)
|
||||
target_link_libraries(ton_crypto PUBLIC ${SODIUM_LIBRARY_RELEASE})
|
||||
|
||||
|
|
|
@ -17,13 +17,22 @@
|
|||
|
||||
#include "secp256k1.h"
|
||||
#include "td/utils/check.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include <secp256k1_recovery.h>
|
||||
#include <secp256k1_extrakeys.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace td {
|
||||
namespace td::secp256k1 {
|
||||
|
||||
static const secp256k1_context* get_context() {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
LOG_CHECK(ctx) << "Failed to create secp256k1_context";
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsigned char* public_key) {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
const secp256k1_context* ctx = get_context();
|
||||
secp256k1_ecdsa_recoverable_signature ecdsa_signature;
|
||||
if (signature[64] > 3 ||
|
||||
!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &ecdsa_signature, signature, signature[64])) {
|
||||
|
@ -39,4 +48,22 @@ bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsign
|
|||
return true;
|
||||
}
|
||||
|
||||
bool xonly_pubkey_tweak_add(const unsigned char* xonly_pubkey_bytes, const unsigned char* tweak,
|
||||
unsigned char* output_pubkey_bytes) {
|
||||
const secp256k1_context* ctx = get_context();
|
||||
|
||||
secp256k1_xonly_pubkey xonly_pubkey;
|
||||
secp256k1_pubkey output_pubkey;
|
||||
if (!secp256k1_xonly_pubkey_parse(ctx, &xonly_pubkey, xonly_pubkey_bytes)) {
|
||||
return false;
|
||||
}
|
||||
if (!secp256k1_xonly_pubkey_tweak_add(ctx, &output_pubkey, &xonly_pubkey, tweak)) {
|
||||
return false;
|
||||
}
|
||||
size_t len = 65;
|
||||
secp256k1_ec_pubkey_serialize(ctx, output_pubkey_bytes, &len, &output_pubkey, SECP256K1_EC_UNCOMPRESSED);
|
||||
CHECK(len == 65);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace td::secp256k1
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace td {
|
||||
namespace td::secp256k1 {
|
||||
|
||||
bool ecrecover(const unsigned char* hash, const unsigned char* signature, unsigned char* public_key);
|
||||
bool xonly_pubkey_tweak_add(const unsigned char* xonly_pubkey_bytes, const unsigned char* tweak,
|
||||
unsigned char* output_pubkey_bytes);
|
||||
|
||||
}
|
||||
} // namespace td::secp256k1
|
||||
|
|
|
@ -1015,6 +1015,10 @@ x{EDC} dup @Defop(c) SAVEBOTH @Defop(c) SAVEBOTHCTR
|
|||
x{EDE0} @Defop PUSHCTRX
|
||||
x{EDE1} @Defop POPCTRX
|
||||
x{EDE2} @Defop SETCONTCTRX
|
||||
x{EDE3} @Defop(8u) SETCONTCTRMANY
|
||||
x{EDE3} @Defop(8u) SETCONTMANY
|
||||
x{EDE4} @Defop SETCONTCTRMANYX
|
||||
x{EDE4} @Defop SETCONTMANYX
|
||||
x{EDF0} dup @Defop BOOLAND @Defop COMPOS
|
||||
x{EDF1} dup @Defop BOOLOR @Defop COMPOSALT
|
||||
x{EDF2} @Defop COMPOSBOTH
|
||||
|
@ -1354,6 +1358,7 @@ x{F90704} @Defop HASHEXTAR_KECCAK512
|
|||
x{F910} @Defop CHKSIGNU
|
||||
x{F911} @Defop CHKSIGNS
|
||||
x{F912} @Defop ECRECOVER
|
||||
x{F913} @Defop SECP256K1_XONLY_PUBKEY_TWEAK_ADD
|
||||
x{F914} @Defop P256_CHKSIGNU
|
||||
x{F915} @Defop P256_CHKSIGNS
|
||||
|
||||
|
|
|
@ -167,3 +167,7 @@ TEST(Fift, test_bls_ops) {
|
|||
TEST(Fift, test_levels) {
|
||||
run_fift("levels.fif");
|
||||
}
|
||||
|
||||
TEST(Fift, test_secp256k1) {
|
||||
run_fift("secp256k1.fif");
|
||||
}
|
||||
|
|
82
crypto/test/fift/secp256k1.fif
Normal file
82
crypto/test/fift/secp256k1.fif
Normal file
|
@ -0,0 +1,82 @@
|
|||
"Asm.fif" include
|
||||
"FiftExt.fif" include
|
||||
|
||||
{
|
||||
=: expected_result
|
||||
=: tweak
|
||||
=: pubkey
|
||||
B{e80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9e80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9}
|
||||
@' pubkey 256 u>B @' tweak 256 u>B B+ B+ Bhashu =: tweak2
|
||||
@' pubkey @' tweak2
|
||||
[[ <{ SECP256K1_XONLY_PUBKEY_TWEAK_ADD }>s ]] 0 runvmx
|
||||
abort"exitcode != 0" -1 <> abort"xonly_pubkey_tweak_add failed"
|
||||
drop
|
||||
=: result
|
||||
."Pubkey = " @' pubkey x. cr
|
||||
."Tweak = " @' tweak x. cr
|
||||
."Tweak2 = " @' tweak2 x. cr
|
||||
@' expected_result @' result <> { ."Expected = " @' expected_result x. cr ."Found = " @' result x. cr -1 abort"result mismatch" } if
|
||||
."Result = " @' result x. cr
|
||||
4 <> abort"first byte is expected to be 4"
|
||||
cr
|
||||
} : run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x7eeda5cc8b219363ffc29a77d170f923dbb939ea5164b71db862d4a192f2680f
|
||||
0x5a001d32f9fc59c2965ef36d9ff154469a3ba87f00b95879f3b5198bb557494d
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0x3f339347d8b1dde7edade3dc59fc63d18cb21fc2326ffbd30f0711a02d25075a
|
||||
0xc621ca417b8915474020c0c9471a13918b6a02fd20d48a0e526c896923457fcd
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x3197d6b03d78ebbe694d2b89945a21a5a671ca78393481d44739b7351767adef
|
||||
0xcbf0da3bbb498fd575506060d04db426164cb9d1477f07481fc6e3a2f84b01ea
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0xcf9bfedc7251c2f8e233ae1e2c8b7a6cbe25d96a46a38b79e45d5684d026b64c
|
||||
0x19b1aa4551bf08363b2533c146c02fa61e26941336aaa16cdd4393a5440392ea
|
||||
run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x1762cbfa935318fb1395b50c64f961baab3ecaed4afad3068ba2f7f3a9d15cec
|
||||
0x38be4b9791c0cb4952b9fb944eb0fe9256ce0d48be7b92129caafdf2f521248a
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0x099ec2e6ee1c40f533a61abca2860733727204c2f31d078297194d5e93e148f7
|
||||
0x8e9d15851e9aeb652216378f6bc0b88fb66b491697c9b9588f37c11d0b0fbced
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x63494cee8217ca2a10076e2031534fdda39f132dbdf91606aa65021709cb3116
|
||||
0x5dd1aa62a438469f4934e1ab9ada9ba3945651a2641316ec91d0780ca71891f8
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0x36e26133dc62474040eae511ce89610dae6bb0359aa80738baf812ecfa03d2a1
|
||||
0xf9ab8bbbee0ad1e90492c952b362d43d56412debdd1224e9729dc79aff931943
|
||||
run-test
|
||||
|
||||
0x4be5f2020ebe2f37b65fb1bcd8aecf2ab0a333427208a5e6dd3dc691f1fb6ae2
|
||||
0x94f8fb43dd6001bb8acd2c53d094f9c919766dad596498d3d582cebdb39c63da
|
||||
0xf7b4c76d79925f62e7969cb0e4af0673808f646add78563f711dc33a2687dc1b
|
||||
run-test
|
||||
|
||||
0x3ad84c3844e66aa255a121ed46d0e69e7b98f31233941c5197917c97c7aeaec5
|
||||
0xa2f55c34c4eee5881584714bd5c7a63c397ef38ff1afedd04ada10fdeb541cef
|
||||
0x73f9a15b76612ca4254e6c2758508589c0112eb724f42dbb4c65ff8b025d2103
|
||||
run-test
|
||||
|
||||
0x57bb69f0d446ee2cf9f77a2bdca7a3a462a61d85997a1154f2321a2717951b02
|
||||
0x05130a68853e5e4aff579fa21ff10010410a3be47b94d908e203f69ec9dc7d00
|
||||
0x4ce6b5b1bd77b1666d33a0c9fd37b98952078bcc451d6de2d0bff65e8f2b46ed
|
||||
run-test
|
||||
|
||||
0x4af537be1a1ae11770eef23e6087f83ce1019fbee7a5876837107f84929a1d19
|
||||
0x9765369cb4467bebc8a468d44aa60f0154f04ee32fbcf1c8bdf646d4840163d1
|
||||
0x118953c642b8f25fea3519bcaab3ae6cea25402088e11a8efdc2e0bd222958ad
|
||||
run-test
|
|
@ -923,6 +923,41 @@ int exec_setcont_ctr_var(VmState* st) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int exec_setcont_ctr_many(VmState* st, unsigned args) {
|
||||
unsigned mask = args & 255;
|
||||
VM_LOG(st) << "execute SETCONTCTRMANY " << mask;
|
||||
if (mask & (1 << 6)) {
|
||||
throw VmError{Excno::range_chk, "no control register c6"};
|
||||
}
|
||||
Stack& stack = st->get_stack();
|
||||
auto cont = stack.pop_cont();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (mask & (1 << i)) {
|
||||
throw_typechk(force_cregs(cont)->define(i, st->get(i)));
|
||||
}
|
||||
}
|
||||
st->get_stack().push_cont(std::move(cont));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_setcont_ctr_many_var(VmState* st) {
|
||||
VM_LOG(st) << "execute SETCONTCTRMANYX";
|
||||
Stack& stack = st->get_stack();
|
||||
stack.check_underflow(2);
|
||||
int mask = stack.pop_smallint_range(255);
|
||||
if (mask & (1 << 6)) {
|
||||
throw VmError{Excno::range_chk, "no control register c6"};
|
||||
}
|
||||
auto cont = stack.pop_cont();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (mask & (1 << i)) {
|
||||
throw_typechk(force_cregs(cont)->define(i, st->get(i)));
|
||||
}
|
||||
}
|
||||
st->get_stack().push_cont(std::move(cont));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_compos(VmState* st, unsigned mask, const char* name) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute " << name;
|
||||
|
@ -1037,6 +1072,8 @@ void register_continuation_change_ops(OpcodeTable& cp0) {
|
|||
cp0.insert(OpcodeInstr::mksimple(0xede0, 16, "PUSHCTRX", exec_push_ctr_var))
|
||||
.insert(OpcodeInstr::mksimple(0xede1, 16, "POPCTRX", exec_pop_ctr_var))
|
||||
.insert(OpcodeInstr::mksimple(0xede2, 16, "SETCONTCTRX", exec_setcont_ctr_var))
|
||||
.insert(OpcodeInstr::mkfixed(0xede3, 16, 8, instr::dump_1c_l_add(1, "SETCONTCTRMANY "), exec_setcont_ctr_many)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xede4, 16, "SETCONTCTRMANYX", exec_setcont_ctr_many_var)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xedf0, 16, "BOOLAND", std::bind(exec_compos, _1, 1, "BOOLAND")))
|
||||
.insert(OpcodeInstr::mksimple(0xedf1, 16, "BOOLOR", std::bind(exec_compos, _1, 2, "BOOLOR")))
|
||||
.insert(OpcodeInstr::mksimple(0xedf2, 16, "COMPOSBOTH", std::bind(exec_compos, _1, 3, "COMPOSBOTH")))
|
||||
|
|
|
@ -661,7 +661,38 @@ int exec_ecrecover(VmState* st) {
|
|||
}
|
||||
st->consume_gas(VmState::ecrecover_gas_price);
|
||||
unsigned char public_key[65];
|
||||
if (td::ecrecover(hash_bytes, signature, public_key)) {
|
||||
if (td::secp256k1::ecrecover(hash_bytes, signature, public_key)) {
|
||||
td::uint8 h = public_key[0];
|
||||
td::RefInt256 x1{true}, x2{true};
|
||||
CHECK(x1.write().import_bytes(public_key + 1, 32, false));
|
||||
CHECK(x2.write().import_bytes(public_key + 33, 32, false));
|
||||
stack.push_smallint(h);
|
||||
stack.push_int(std::move(x1));
|
||||
stack.push_int(std::move(x2));
|
||||
stack.push_bool(true);
|
||||
} else {
|
||||
stack.push_bool(false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_secp256k1_xonly_pubkey_tweak_add(VmState* st) {
|
||||
VM_LOG(st) << "execute SECP256K1_XONLY_PUBKEY_TWEAK_ADD";
|
||||
Stack& stack = st->get_stack();
|
||||
stack.check_underflow(2);
|
||||
auto tweak_int = stack.pop_int();
|
||||
auto key_int = stack.pop_int();
|
||||
|
||||
unsigned char key[32], tweak[32];
|
||||
if (!key_int->export_bytes(key, 32, false)) {
|
||||
throw VmError{Excno::range_chk, "key must fit in an unsigned 256-bit integer"};
|
||||
}
|
||||
if (!tweak_int->export_bytes(tweak, 32, false)) {
|
||||
throw VmError{Excno::range_chk, "tweak must fit in an unsigned 256-bit integer"};
|
||||
}
|
||||
st->consume_gas(VmState::secp256k1_xonly_pubkey_tweak_add_gas_price);
|
||||
unsigned char public_key[65];
|
||||
if (td::secp256k1::xonly_pubkey_tweak_add(key, tweak, public_key)) {
|
||||
td::uint8 h = public_key[0];
|
||||
td::RefInt256 x1{true}, x2{true};
|
||||
CHECK(x1.write().import_bytes(public_key + 1, 32, false));
|
||||
|
@ -1214,6 +1245,7 @@ void register_ton_crypto_ops(OpcodeTable& cp0) {
|
|||
.insert(OpcodeInstr::mksimple(0xf910, 16, "CHKSIGNU", std::bind(exec_ed25519_check_signature, _1, false)))
|
||||
.insert(OpcodeInstr::mksimple(0xf911, 16, "CHKSIGNS", std::bind(exec_ed25519_check_signature, _1, true)))
|
||||
.insert(OpcodeInstr::mksimple(0xf912, 16, "ECRECOVER", exec_ecrecover)->require_version(4))
|
||||
.insert(OpcodeInstr::mksimple(0xf913, 16, "SECP256K1_XONLY_PUBKEY_TWEAK_ADD", exec_secp256k1_xonly_pubkey_tweak_add)->require_version(9))
|
||||
.insert(OpcodeInstr::mksimple(0xf914, 16, "P256_CHKSIGNU", std::bind(exec_p256_chksign, _1, false))->require_version(4))
|
||||
.insert(OpcodeInstr::mksimple(0xf915, 16, "P256_CHKSIGNS", std::bind(exec_p256_chksign, _1, true))->require_version(4))
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ class VmState final : public VmStateInterface {
|
|||
rist255_validate_gas_price = 200,
|
||||
|
||||
ecrecover_gas_price = 1500,
|
||||
secp256k1_xonly_pubkey_tweak_add_gas_price = 1250,
|
||||
chksgn_free_count = 10,
|
||||
chksgn_gas_price = 4000,
|
||||
p256_chksgn_gas_price = 3500,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue