Skip to content

Commit

Permalink
Minimize secp256k1 precomputed table
Browse files Browse the repository at this point in the history
The size is reduced from more than 1M to 128 bytes only
The verification cycles is increased from 1.4M to 1.7M.
  • Loading branch information
XuJiandong committed Feb 5, 2024
1 parent f7988ed commit 8d20c61
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 52 deletions.
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ build/always_success: c/always_success.c
build/secp256k1_data_info_20210801.h: build/dump_secp256k1_data_20210801
$<

c/secp256k1_data_20210801.h: build/secp256k1_data_20210801
xxd -i -name ckb_secp256k1_data $< > $@

build/dump_secp256k1_data_20210801: c/dump_secp256k1_data_20210801.c $(SECP256K1_SRC_20210801)
mkdir -p build
gcc -I deps/secp256k1-20210801/src -I deps/secp256k1-20210801 -o $@ $<
Expand All @@ -46,13 +49,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=2 --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}

Expand Down
9 changes: 3 additions & 6 deletions c/ckb_identity.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, NULL);
if (ret != 0) {
return ret;
}
Expand Down Expand Up @@ -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, NULL);
if (ret != 0) {
return ret;
}
Expand Down Expand Up @@ -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, NULL);
if (ret != 0) return ret;

// We will perform *threshold* number of signature verifications here.
Expand Down
8 changes: 0 additions & 8 deletions c/dump_secp256k1_data_20210801.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ int main(int argc, char* argv[]) {
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);

Expand Down
14 changes: 14 additions & 0 deletions c/secp256k1_data_20210801.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
unsigned char ckb_secp256k1_data[] = {
0x98, 0x17, 0xf8, 0x16, 0x5b, 0x81, 0xf2, 0x59, 0xd9, 0x28, 0xce, 0x2d,
0xdb, 0xfc, 0x9b, 0x02, 0x07, 0x0b, 0x87, 0xce, 0x95, 0x62, 0xa0, 0x55,
0xac, 0xbb, 0xdc, 0xf9, 0x7e, 0x66, 0xbe, 0x79, 0xb8, 0xd4, 0x10, 0xfb,
0x8f, 0xd0, 0x47, 0x9c, 0x19, 0x54, 0x85, 0xa6, 0x48, 0xb4, 0x17, 0xfd,
0xa8, 0x08, 0x11, 0x0e, 0xfc, 0xfb, 0xa4, 0x5d, 0x65, 0xc4, 0xa3, 0x26,
0x77, 0xda, 0x3a, 0x48, 0xda, 0xc0, 0xc4, 0x9e, 0x4c, 0x44, 0x7b, 0x1b,
0x35, 0xa3, 0x3e, 0x72, 0x78, 0x56, 0x8c, 0xe8, 0x2e, 0x16, 0x1f, 0x98,
0xad, 0xc1, 0x39, 0x92, 0x33, 0x5f, 0x3b, 0xf6, 0xd2, 0xb9, 0x68, 0x8f,
0x82, 0xff, 0x1f, 0x50, 0x79, 0xbf, 0x3c, 0xf2, 0xfd, 0x0b, 0x51, 0x95,
0xfe, 0x2c, 0xea, 0xbb, 0x5d, 0x21, 0xbe, 0xb6, 0xc2, 0x90, 0x1d, 0xde,
0x86, 0x39, 0x06, 0xba, 0x2d, 0x9f, 0x2a, 0x66
};
unsigned int ckb_secp256k1_data_len = 128;
35 changes: 2 additions & 33 deletions c/secp256k1_helper_20210801.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define HAVE_CONFIG_H 1
#define USE_EXTERNAL_DEFAULT_CALLBACKS
#include <secp256k1.c>
#include "secp256k1_data_20210801.h"

void secp256k1_default_illegal_callback_fn(const char* str, void* data) {
(void)str;
Expand All @@ -35,38 +36,6 @@ void secp256k1_default_error_callback_fn(const char* str, void* 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;
Expand All @@ -75,7 +44,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]);
Expand Down
1 change: 1 addition & 0 deletions tests/omni_lock_rust/tests/test_secp256k1_compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
print!("cycles = {}", verify_result.clone().unwrap());
verify_result.expect("pass verification");
}

Expand Down

0 comments on commit 8d20c61

Please sign in to comment.