From bfc04c053814c281dcd35b9330e9c653dd0b0abd Mon Sep 17 00:00:00 2001 From: xjd Date: Tue, 6 Feb 2024 10:53:16 +0800 Subject: [PATCH] Minimize secp256k1 precomputed table (#30) * Minimize secp256k1 precomputed table * Choose ecmult-window = 6 for better performance * Remove not used code and files --- Makefile | 19 +- c/ckb_identity.h | 9 +- c/dump_secp256k1_data.c | 57 ----- c/dump_secp256k1_data_20210801.c | 25 +- c/secp256k1_helper.h | 88 ------- c/secp256k1_helper_20210801.h | 37 +-- c/secp256k1_lock.h | 224 ------------------ .../tests/test_secp256k1_compatibility.rs | 1 + 8 files changed, 28 insertions(+), 432 deletions(-) delete mode 100644 c/dump_secp256k1_data.c delete mode 100644 c/secp256k1_helper.h delete mode 100644 c/secp256k1_lock.h diff --git a/Makefile b/Makefile index 1b7cab3..d4f62ca 100644 --- a/Makefile +++ b/Makefile @@ -46,13 +46,9 @@ build/dump_secp256k1_data_20210801: c/dump_secp256k1_data_20210801.c $(SECP256K1 $(SECP256K1_SRC_20210801): cd deps/secp256k1-20210801 && \ ./autogen.sh && \ - CC=$(CC) LD=$(LD) ./configure --with-bignum=no --enable-ecmult-static-precomputation --enable-endomorphism --enable-module-recovery --host=$(TARGET) && \ + CC=$(CC) LD=$(LD) ./configure --enable-ecmult-static-precomputation --with-ecmult-window=6 --enable-module-recovery --host=$(TARGET) && \ make src/ecmult_static_pre_context.h src/ecmult_static_context.h - -build/impl.o: deps/ckb-c-std-lib/libc/src/impl.c - $(CC) -c $(filter-out -DCKB_DECLARATION_ONLY, $(CFLAGS_MBEDTLS)) $(LDFLAGS_MBEDTLS) -o $@ $^ - ${PROTOCOL_SCHEMA}: curl -L -o $@ ${PROTOCOL_URL} @@ -84,7 +80,7 @@ omni_lock_mol: build/cobuild.o: c/cobuild.c c/cobuild.h $(CC) -c $(OMNI_LOCK_CFLAGS) -o $@ $< -build/omni_lock.o: c/omni_lock.c c/omni_lock_supply.h c/omni_lock_acp.h c/secp256k1_lock.h build/secp256k1_data_info_20210801.h $(SECP256K1_SRC_20210801) c/ckb_identity.h +build/omni_lock.o: c/omni_lock.c c/omni_lock_supply.h c/omni_lock_acp.h build/secp256k1_data_info_20210801.h $(SECP256K1_SRC_20210801) c/ckb_identity.h $(CC) -c $(OMNI_LOCK_CFLAGS) -o $@ $< build/omni_lock: build/omni_lock.o build/cobuild.o @@ -98,14 +94,17 @@ cobuild_mol: ${MOLC} --language - --schema-file c/basic.mol --format json > build/cobuild_basic_mol2.json moleculec-c2 --input build/cobuild_basic_mol2.json | clang-format -style=Google > c/cobuild_basic_mol2.h -clean: +clean: clean2 rm -rf build/secp256k1_data_info_20210801.h build/dump_secp256k1_data_20210801 - rm -rf build/secp256k1_data_20210801 + rm -f build/secp256k1_data_20210801 + cd deps/secp256k1-20210801 && [ -f "Makefile" ] && make clean + +clean2: rm -rf build/*.debug rm -f build/omni_lock rm -f build/*.o - cd deps/secp256k1-20210801 && [ -f "Makefile" ] && make clean - + rm -f build/always_success + install-tools: if [ ! -x "$$(command -v "${MOLC}")" ] \ || [ "$$(${MOLC} --version | awk '{ print $$2 }' | tr -d ' ')" != "${MOLC_VERSION}" ]; then \ diff --git a/c/ckb_identity.h b/c/ckb_identity.h index 950d8e5..d017f81 100644 --- a/c/ckb_identity.h +++ b/c/ckb_identity.h @@ -163,8 +163,7 @@ static int _ckb_recover_secp256k1_pubkey(const uint8_t *sig, size_t sig_len, /* Load signature */ secp256k1_context context; - uint8_t secp_data[CKB_SECP256K1_DATA_SIZE]; - ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data); + ret = ckb_secp256k1_custom_verify_only_initialize(&context); if (ret != 0) { return ret; } @@ -285,8 +284,7 @@ static int _recover_secp256k1_pubkey_btc(const uint8_t *sig, size_t sig_len, } secp256k1_context context; - uint8_t secp_data[CKB_SECP256K1_DATA_SIZE]; - ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data); + ret = ckb_secp256k1_custom_verify_only_initialize(&context); if (ret != 0) { return ret; } @@ -823,8 +821,7 @@ int verify_multisig(const uint8_t *lock_bytes, size_t lock_bytes_len, // contract, you don't have to wait for the foundation to ship a new // cryptographic algorithm. You can just build and ship your own. secp256k1_context context; - uint8_t secp_data[CKB_SECP256K1_DATA_SIZE]; - ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data); + ret = ckb_secp256k1_custom_verify_only_initialize(&context); if (ret != 0) return ret; // We will perform *threshold* number of signature verifications here. diff --git a/c/dump_secp256k1_data.c b/c/dump_secp256k1_data.c deleted file mode 100644 index 83f6065..0000000 --- a/c/dump_secp256k1_data.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include "blake2b.h" - -/* - * We are including secp256k1 implementation directly so gcc can strip - * unused functions. For some unknown reasons, if we link in libsecp256k1.a - * directly, the final binary will include all functions rather than those used. - */ -#define HAVE_CONFIG_H 1 -#include - -#define ERROR_IO -1 - -int main(int argc, char* argv[]) { - size_t pre_size = sizeof(secp256k1_ecmult_static_pre_context); - size_t pre128_size = sizeof(secp256k1_ecmult_static_pre128_context); - - FILE* fp_data = fopen("build/secp256k1_data", "wb"); - if (!fp_data) { - return ERROR_IO; - } - fwrite(secp256k1_ecmult_static_pre_context, pre_size, 1, fp_data); - fwrite(secp256k1_ecmult_static_pre128_context, pre128_size, 1, fp_data); - fclose(fp_data); - - FILE* fp = fopen("build/secp256k1_data_info.h", "w"); - if (!fp) { - return ERROR_IO; - } - - fprintf(fp, "#ifndef CKB_SECP256K1_DATA_INFO_H_\n"); - fprintf(fp, "#define CKB_SECP256K1_DATA_INFO_H_\n"); - fprintf(fp, "#define CKB_SECP256K1_DATA_SIZE %ld\n", pre_size + pre128_size); - fprintf(fp, "#define CKB_SECP256K1_DATA_PRE_SIZE %ld\n", pre_size); - fprintf(fp, "#define CKB_SECP256K1_DATA_PRE128_SIZE %ld\n", pre128_size); - - blake2b_state blake2b_ctx; - uint8_t hash[32]; - blake2b_init(&blake2b_ctx, 32); - blake2b_update(&blake2b_ctx, secp256k1_ecmult_static_pre_context, pre_size); - blake2b_update(&blake2b_ctx, secp256k1_ecmult_static_pre128_context, - pre128_size); - blake2b_final(&blake2b_ctx, hash, 32); - - fprintf(fp, "static uint8_t ckb_secp256k1_data_hash[32] = {\n "); - for (int i = 0; i < 32; i++) { - fprintf(fp, "%u", hash[i]); - if (i != 31) { - fprintf(fp, ", "); - } - } - fprintf(fp, "\n};\n"); - fprintf(fp, "#endif\n"); - fclose(fp); - - return 0; -} diff --git a/c/dump_secp256k1_data_20210801.c b/c/dump_secp256k1_data_20210801.c index 10f4236..5cd23a3 100644 --- a/c/dump_secp256k1_data_20210801.c +++ b/c/dump_secp256k1_data_20210801.c @@ -34,22 +34,23 @@ int main(int argc, char* argv[]) { fprintf(fp, "#define CKB_SECP256K1_DATA_PRE_SIZE %ld\n", pre_size); fprintf(fp, "#define CKB_SECP256K1_DATA_PRE128_SIZE %ld\n", pre128_size); - blake2b_state blake2b_ctx; - uint8_t hash[32]; - blake2b_init(&blake2b_ctx, 32); - blake2b_update(&blake2b_ctx, secp256k1_ecmult_static_pre_context, pre_size); - blake2b_update(&blake2b_ctx, secp256k1_ecmult_static_pre128_context, - pre128_size); - blake2b_final(&blake2b_ctx, hash, 32); - - fprintf(fp, "static uint8_t ckb_secp256k1_data_hash[32] = {\n "); - for (int i = 0; i < 32; i++) { - fprintf(fp, "%u", hash[i]); - if (i != 31) { + fprintf(fp, "static uint8_t ckb_secp256k1_data[] = {\n "); + unsigned char* p = (unsigned char*)secp256k1_ecmult_static_pre_context; + for (int i = 0; i < pre_size; i++) { + fprintf(fp, "0x%02x", p[i]); + fprintf(fp, ", "); + } + fprintf(fp, "\n"); + p = (unsigned char*)secp256k1_ecmult_static_pre128_context; + for (int i = 0; i < pre128_size; i++) { + fprintf(fp, "0x%02x", p[i]); + if (i != (pre128_size -1)) { fprintf(fp, ", "); } } + fprintf(fp, "\n};\n"); + fprintf(fp, "#endif\n"); fclose(fp); diff --git a/c/secp256k1_helper.h b/c/secp256k1_helper.h deleted file mode 100644 index 0f858ce..0000000 --- a/c/secp256k1_helper.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef CKB_SECP256K1_HELPER_H_ -#define CKB_SECP256K1_HELPER_H_ - -#include "ckb_syscalls.h" -#include "secp256k1_data_info.h" - -#define CKB_SECP256K1_HELPER_ERROR_LOADING_DATA -101 -#define CKB_SECP256K1_HELPER_ERROR_ILLEGAL_CALLBACK -102 -#define CKB_SECP256K1_HELPER_ERROR_ERROR_CALLBACK -103 - -/* - * We are including secp256k1 implementation directly so gcc can strip - * unused functions. For some unknown reasons, if we link in libsecp256k1.a - * directly, the final binary will include all functions rather than those used. - */ -#define HAVE_CONFIG_H 1 -#define USE_EXTERNAL_DEFAULT_CALLBACKS -#include - -void secp256k1_default_illegal_callback_fn(const char* str, void* data) { - (void)str; - (void)data; - ckb_exit(CKB_SECP256K1_HELPER_ERROR_ILLEGAL_CALLBACK); -} - -void secp256k1_default_error_callback_fn(const char* str, void* data) { - (void)str; - (void)data; - ckb_exit(CKB_SECP256K1_HELPER_ERROR_ERROR_CALLBACK); -} - -/* - * data should at least be CKB_SECP256K1_DATA_SIZE big - * so as to hold all loaded data. - */ -int ckb_secp256k1_custom_verify_only_initialize(secp256k1_context* context, - void* data) { - size_t index = 0; - int running = 1; - while (running && index < SIZE_MAX) { - uint64_t len = 32; - uint8_t hash[32]; - - int ret = ckb_load_cell_by_field(hash, &len, 0, index, CKB_SOURCE_CELL_DEP, - CKB_CELL_FIELD_DATA_HASH); - switch (ret) { - case CKB_ITEM_MISSING: - break; - case CKB_SUCCESS: - if (memcmp(ckb_secp256k1_data_hash, hash, 32) == 0) { - /* Found a match, load data here */ - len = CKB_SECP256K1_DATA_SIZE; - ret = ckb_load_cell_data(data, &len, 0, index, CKB_SOURCE_CELL_DEP); - if (ret != CKB_SUCCESS || len != CKB_SECP256K1_DATA_SIZE) { - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } - running = 0; - } - break; - default: - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } - if (running) { - index++; - } - } - if (index == SIZE_MAX) { - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } - - context->illegal_callback = default_illegal_callback; - context->error_callback = default_error_callback; - - secp256k1_ecmult_context_init(&context->ecmult_ctx); - secp256k1_ecmult_gen_context_init(&context->ecmult_gen_ctx); - - /* Recasting data to (uint8_t*) for pointer math */ - uint8_t* p = data; - secp256k1_ge_storage(*pre_g)[] = (secp256k1_ge_storage(*)[])p; - secp256k1_ge_storage(*pre_g_128)[] = - (secp256k1_ge_storage(*)[])(&p[CKB_SECP256K1_DATA_PRE_SIZE]); - context->ecmult_ctx.pre_g = pre_g; - context->ecmult_ctx.pre_g_128 = pre_g_128; - - return 0; -} - -#endif diff --git a/c/secp256k1_helper_20210801.h b/c/secp256k1_helper_20210801.h index 3b1e9f4..4c4a6d3 100644 --- a/c/secp256k1_helper_20210801.h +++ b/c/secp256k1_helper_20210801.h @@ -33,40 +33,7 @@ void secp256k1_default_error_callback_fn(const char* str, void* data) { * data should at least be CKB_SECP256K1_DATA_SIZE big * so as to hold all loaded data. */ -int ckb_secp256k1_custom_verify_only_initialize(secp256k1_context* context, - void* data) { - size_t index = 0; - int running = 1; - while (running && index < SIZE_MAX) { - uint64_t len = 32; - uint8_t hash[32]; - - int ret = ckb_load_cell_by_field(hash, &len, 0, index, CKB_SOURCE_CELL_DEP, - CKB_CELL_FIELD_DATA_HASH); - switch (ret) { - case CKB_ITEM_MISSING: - break; - case CKB_SUCCESS: - if (memcmp(ckb_secp256k1_data_hash, hash, 32) == 0) { - /* Found a match, load data here */ - len = CKB_SECP256K1_DATA_SIZE; - ret = ckb_load_cell_data(data, &len, 0, index, CKB_SOURCE_CELL_DEP); - if (ret != CKB_SUCCESS || len != CKB_SECP256K1_DATA_SIZE) { - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } - running = 0; - } - break; - default: - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } - if (running) { - index++; - } - } - if (index == SIZE_MAX) { - return CKB_SECP256K1_HELPER_ERROR_LOADING_DATA; - } +int ckb_secp256k1_custom_verify_only_initialize(secp256k1_context* context) { context->illegal_callback = default_illegal_callback; context->error_callback = default_error_callback; @@ -75,7 +42,7 @@ int ckb_secp256k1_custom_verify_only_initialize(secp256k1_context* context, secp256k1_ecmult_gen_context_init(&context->ecmult_gen_ctx); /* Recasting data to (uint8_t*) for pointer math */ - uint8_t* p = data; + uint8_t* p = ckb_secp256k1_data; secp256k1_ge_storage(*pre_g)[] = (secp256k1_ge_storage(*)[])p; secp256k1_ge_storage(*pre_g_128)[] = (secp256k1_ge_storage(*)[])(&p[CKB_SECP256K1_DATA_PRE_SIZE]); diff --git a/c/secp256k1_lock.h b/c/secp256k1_lock.h deleted file mode 100644 index 83f6caf..0000000 --- a/c/secp256k1_lock.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef CKB_LOCK_UTILS_H_ -#define CKB_LOCK_UTILS_H_ - -#define BLAKE2B_BLOCK_SIZE 32 -#define BLAKE160_SIZE 20 -#define PUBKEY_SIZE 33 -#define TEMP_SIZE 32768 -#define RECID_INDEX 64 -/* 32 KB */ -#define MAX_WITNESS_SIZE 32768 -#define SCRIPT_SIZE 32768 -#define SIGNATURE_SIZE 65 - -/* secp256k1 unlock errors */ -#define ERROR_ARGUMENTS_LEN -1 -#define ERROR_ENCODING -2 -#define ERROR_SYSCALL -3 -#define ERROR_SECP_RECOVER_PUBKEY -11 -#define ERROR_SECP_VERIFICATION -12 -#define ERROR_SECP_PARSE_PUBKEY -13 -#define ERROR_SECP_PARSE_SIGNATURE -14 -#define ERROR_SECP_SERIALIZE_PUBKEY -15 -#define ERROR_SCRIPT_TOO_LONG -21 -#define ERROR_WITNESS_SIZE -22 -#define ERROR_INCORRECT_SINCE_FLAGS -23 -#define ERROR_INCORRECT_SINCE_VALUE -24 -#define ERROR_PUBKEY_BLAKE160_HASH -31 - -#if (MAX_WITNESS_SIZE > TEMP_SIZE) || (SCRIPT_SIZE > TEMP_SIZE) -#error "Temp buffer is not big enough!" -#endif - -/* Extract lock from WitnessArgs */ -int extract_witness_lock(uint8_t *witness, uint64_t len, - mol_seg_t *lock_bytes_seg) { - mol_seg_t witness_seg; - witness_seg.ptr = witness; - witness_seg.size = len; - - if (MolReader_WitnessArgs_verify(&witness_seg, false) != MOL_OK) { - return ERROR_ENCODING; - } - mol_seg_t lock_seg = MolReader_WitnessArgs_get_lock(&witness_seg); - - if (MolReader_BytesOpt_is_none(&lock_seg)) { - return ERROR_ENCODING; - } - *lock_bytes_seg = MolReader_Bytes_raw_bytes(&lock_seg); - return CKB_SUCCESS; -} - -/* - * Load secp256k1 first witness and check the signature - * - * This function return CKB_SUCCESS if the witness is a valid WitnessArgs - * and the length of WitnessArgs#lock field is exactly the SIGNATURE_SIZE - * - * Arguments: - * * witness bytes, a buffer to receive the first witness bytes of the input - * cell group - * * witness len, a pointer to receive the first witness length - * - * Witness: - * WitnessArgs with a signature in lock field used to present ownership. - */ -int load_secp256k1_first_witness_and_check_signature( - unsigned char witness_bytes[MAX_WITNESS_SIZE], uint64_t *witness_len) { - int ret; - /* Load witness of first input */ - *witness_len = MAX_WITNESS_SIZE; - ret = ckb_load_witness(witness_bytes, witness_len, 0, 0, - CKB_SOURCE_GROUP_INPUT); - if (ret != CKB_SUCCESS) { - return ERROR_SYSCALL; - } - - if (*witness_len > MAX_WITNESS_SIZE) { - return ERROR_WITNESS_SIZE; - } - - /* load signature */ - mol_seg_t witness_lock_seg; - ret = extract_witness_lock(witness_bytes, *witness_len, &witness_lock_seg); - if (ret != 0) { - return ERROR_ENCODING; - } - - if (witness_lock_seg.size != SIGNATURE_SIZE) { - return ERROR_ARGUMENTS_LEN; - } - return CKB_SUCCESS; -} - -/* - * Arguments: - * * pubkey blake160 hash, blake2b hash of pubkey first 20 bytes, used to - * shield the real pubkey. - * * first witness bytes, the first witness bytes of the input cell group - * * first witness len, length of first witness bytes - */ -int verify_secp256k1_blake160_sighash_all_with_witness( - unsigned char pubkey_hash[BLAKE160_SIZE], - unsigned char first_witness_bytes[MAX_WITNESS_SIZE], - uint64_t first_witness_len) { - int ret; - unsigned char temp[MAX_WITNESS_SIZE]; - unsigned char lock_bytes[SIGNATURE_SIZE]; - - /* copy first witness to temp, we keep the first_witness_bytes untouched in - * this function */ - uint64_t len = first_witness_len; - memcpy(temp, first_witness_bytes, len); - - /* load signature */ - mol_seg_t lock_bytes_seg; - ret = extract_witness_lock(temp, first_witness_len, &lock_bytes_seg); - if (ret != 0) { - return ERROR_ENCODING; - } - - if (lock_bytes_seg.size != SIGNATURE_SIZE) { - return ERROR_ARGUMENTS_LEN; - } - memcpy(lock_bytes, lock_bytes_seg.ptr, lock_bytes_seg.size); - - /* Load tx hash */ - unsigned char tx_hash[BLAKE2B_BLOCK_SIZE]; - len = BLAKE2B_BLOCK_SIZE; - ret = ckb_load_tx_hash(tx_hash, &len, 0); - if (ret != CKB_SUCCESS) { - return ret; - } - if (len != BLAKE2B_BLOCK_SIZE) { - return ERROR_SYSCALL; - } - - /* Prepare sign message */ - unsigned char message[BLAKE2B_BLOCK_SIZE]; - blake2b_state blake2b_ctx; - blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE); - blake2b_update(&blake2b_ctx, tx_hash, BLAKE2B_BLOCK_SIZE); - - /* Clear lock field to zero, then digest the first witness */ - memset((void *)lock_bytes_seg.ptr, 0, lock_bytes_seg.size); - blake2b_update(&blake2b_ctx, (char *)&first_witness_len, sizeof(uint64_t)); - blake2b_update(&blake2b_ctx, temp, first_witness_len); - - /* Digest same group witnesses */ - size_t i = 1; - while (1) { - len = MAX_WITNESS_SIZE; - ret = ckb_load_witness(temp, &len, 0, i, CKB_SOURCE_GROUP_INPUT); - if (ret == CKB_INDEX_OUT_OF_BOUND) { - break; - } - if (ret != CKB_SUCCESS) { - return ERROR_SYSCALL; - } - if (len > MAX_WITNESS_SIZE) { - return ERROR_WITNESS_SIZE; - } - blake2b_update(&blake2b_ctx, (char *)&len, sizeof(uint64_t)); - blake2b_update(&blake2b_ctx, temp, len); - i += 1; - } - /* Digest witnesses that not covered by inputs */ - i = ckb_calculate_inputs_len(); - while (1) { - len = MAX_WITNESS_SIZE; - ret = ckb_load_witness(temp, &len, 0, i, CKB_SOURCE_INPUT); - if (ret == CKB_INDEX_OUT_OF_BOUND) { - break; - } - if (ret != CKB_SUCCESS) { - return ERROR_SYSCALL; - } - if (len > MAX_WITNESS_SIZE) { - return ERROR_WITNESS_SIZE; - } - blake2b_update(&blake2b_ctx, (char *)&len, sizeof(uint64_t)); - blake2b_update(&blake2b_ctx, temp, len); - i += 1; - } - blake2b_final(&blake2b_ctx, message, BLAKE2B_BLOCK_SIZE); - - /* Load signature */ - secp256k1_context context; - uint8_t secp_data[CKB_SECP256K1_DATA_SIZE]; - ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data); - if (ret != 0) { - return ret; - } - - secp256k1_ecdsa_recoverable_signature signature; - if (secp256k1_ecdsa_recoverable_signature_parse_compact( - &context, &signature, lock_bytes, lock_bytes[RECID_INDEX]) == 0) { - return ERROR_SECP_PARSE_SIGNATURE; - } - - /* Recover pubkey */ - secp256k1_pubkey pubkey; - if (secp256k1_ecdsa_recover(&context, &pubkey, &signature, message) != 1) { - return ERROR_SECP_RECOVER_PUBKEY; - } - - /* Check pubkey hash */ - size_t pubkey_size = PUBKEY_SIZE; - if (secp256k1_ec_pubkey_serialize(&context, temp, &pubkey_size, &pubkey, - SECP256K1_EC_COMPRESSED) != 1) { - return ERROR_SECP_SERIALIZE_PUBKEY; - } - - blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE); - blake2b_update(&blake2b_ctx, temp, pubkey_size); - blake2b_final(&blake2b_ctx, temp, BLAKE2B_BLOCK_SIZE); - - if (memcmp(pubkey_hash, temp, BLAKE160_SIZE) != 0) { - return ERROR_PUBKEY_BLAKE160_HASH; - } - - return 0; -} - -#endif /* CKB_LOCK_UTILS_H_ */ diff --git a/tests/omni_lock_rust/tests/test_secp256k1_compatibility.rs b/tests/omni_lock_rust/tests/test_secp256k1_compatibility.rs index 80919c4..4580049 100644 --- a/tests/omni_lock_rust/tests/test_secp256k1_compatibility.rs +++ b/tests/omni_lock_rust/tests/test_secp256k1_compatibility.rs @@ -39,6 +39,7 @@ fn test_sighash_all_unlock() { let mut verifier = verify_tx(resolved_tx, data_loader.clone()); verifier.set_debug_printer(debug_printer); let verify_result = verifier.verify(MAX_CYCLES); + println!("cycles = {}", verify_result.clone().unwrap()); verify_result.expect("pass verification"); }