Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Support prefilled data in dynamic library" #42

Merged
merged 1 commit into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 20 additions & 81 deletions c/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ int md_string(const mbedtls_md_info_t *md_info, const uint8_t *buf, size_t n,
return err;
}

static int _recover_secp256k1_pubkey(uint8_t *prefilled_data,
const uint8_t *sig, size_t sig_len,
static int _recover_secp256k1_pubkey(const uint8_t *sig, size_t sig_len,
const uint8_t *msg, size_t msg_len,
uint8_t *out_pubkey,
size_t *out_pubkey_size, int recid,
Expand All @@ -99,7 +98,8 @@ static int _recover_secp256k1_pubkey(uint8_t *prefilled_data,

/* Load signature */
secp256k1_context context;
ret = ckb_secp256k1_custom_verify_only_initialize(&context, prefilled_data);
uint8_t secp_data[CKB_SECP256K1_DATA_SIZE];
ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data);
if (ret != 0) {
return ret;
}
Expand Down Expand Up @@ -164,8 +164,7 @@ int bitcoin_hash160(const uint8_t *data, size_t size, uint8_t *output) {
return 0;
}

static int _recover_secp256k1_pubkey_btc(uint8_t *prefilled_data,
const uint8_t *sig, size_t sig_len,
static int _recover_secp256k1_pubkey_btc(const uint8_t *sig, size_t sig_len,
const uint8_t *msg, size_t msg_len,
uint8_t *out_pubkey,
size_t *out_pubkey_size) {
Expand All @@ -183,9 +182,10 @@ static int _recover_secp256k1_pubkey_btc(uint8_t *prefilled_data,
if (recid == -1) {
return ERROR_INVALID_ARG;
}
secp256k1_context context;

ret = ckb_secp256k1_custom_verify_only_initialize(&context, prefilled_data);
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;
}
Expand Down Expand Up @@ -243,9 +243,8 @@ int validate_signature_ckb(uint8_t *prefilled_data, uint8_t algorithm_id,
uint8_t out_pubkey[SECP256K1_PUBKEY_SIZE];
size_t out_pubkey_size = SECP256K1_PUBKEY_SIZE;

ret = _recover_secp256k1_pubkey(prefilled_data, sig, sig_len, msg, msg_len,
out_pubkey, &out_pubkey_size,
sig[RECID_INDEX], true);
ret = _recover_secp256k1_pubkey(sig, sig_len, msg, msg_len, out_pubkey,
&out_pubkey_size, sig[RECID_INDEX], true);
if (ret != 0) return ret;

blake2b_state ctx;
Expand Down Expand Up @@ -287,8 +286,8 @@ int validate_signature_eth(uint8_t *prefilled_data, uint8_t algorithm_id,
return ERROR_INVALID_ARG;
}

ret = _recover_secp256k1_pubkey(prefilled_data, sig, sig_len, msg, msg_len,
out_pubkey, &out_pubkey_size, recid, false);
ret = _recover_secp256k1_pubkey(sig, sig_len, msg, msg_len, out_pubkey,
&out_pubkey_size, recid, false);
if (ret != 0) return ret;

// here are the 2 differences than validate_signature_secp256k1
Expand All @@ -312,8 +311,8 @@ int validate_signature_eos(uint8_t *prefilled_data, uint8_t algorithm_id,
}
uint8_t out_pubkey[UNCOMPRESSED_SECP256K1_PUBKEY_SIZE];
size_t out_pubkey_size = UNCOMPRESSED_SECP256K1_PUBKEY_SIZE;
err = _recover_secp256k1_pubkey_btc(prefilled_data, sig, sig_len, msg,
msg_len, out_pubkey, &out_pubkey_size);
err = _recover_secp256k1_pubkey_btc(sig, sig_len, msg, msg_len, out_pubkey,
&out_pubkey_size);
CHECK(err);

blake2b_state ctx;
Expand All @@ -336,8 +335,8 @@ int validate_signature_btc(uint8_t *prefilled_data, uint8_t algorithm_id,
}
uint8_t out_pubkey[UNCOMPRESSED_SECP256K1_PUBKEY_SIZE];
size_t out_pubkey_size = UNCOMPRESSED_SECP256K1_PUBKEY_SIZE;
err = _recover_secp256k1_pubkey_btc(prefilled_data, sig, sig_len, msg,
msg_len, out_pubkey, &out_pubkey_size);
err = _recover_secp256k1_pubkey_btc(sig, sig_len, msg, msg_len, out_pubkey,
&out_pubkey_size);
CHECK(err);

unsigned char temp[AUTH160_SIZE];
Expand All @@ -364,7 +363,8 @@ int validate_signature_schnorr(uint8_t *prefilled_data, uint8_t algorithm_id,
return ERROR_INVALID_ARG;
}
secp256k1_context ctx;
err = ckb_secp256k1_custom_verify_only_initialize(&ctx, prefilled_data);
uint8_t secp_data[CKB_SECP256K1_DATA_SIZE];
err = ckb_secp256k1_custom_verify_only_initialize(&ctx, secp_data);
if (err != 0) return err;

secp256k1_xonly_pubkey pk;
Expand Down Expand Up @@ -440,7 +440,7 @@ int validate_signature_ripple(uint8_t *prefilled_data, uint8_t algorithm_id,
CHECK2(memcmp(sign_data.ckb_msg, msg, RIPPLE_ACCOUNT_ID_SIZE) == 0,
ERROR_INVALID_ARG);

CHECK(verify_ripple(prefilled_data, &sign_data));
CHECK(verify_ripple(&sign_data));
get_ripple_pubkey_hash(sign_data.public_key, out_pubkey_hash);
exit:
return err;
Expand Down Expand Up @@ -1034,7 +1034,8 @@ int verify_multisig(uint8_t *prefilled_data, const uint8_t *lock_bytes,
// 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;
ret = ckb_secp256k1_custom_verify_only_initialize(&context, prefilled_data);
uint8_t secp_data[CKB_SECP256K1_DATA_SIZE];
ret = ckb_secp256k1_custom_verify_only_initialize(&context, secp_data);
if (ret != 0) return ret;

// We will perform *threshold* number of signature verifications here.
Expand Down Expand Up @@ -1106,69 +1107,7 @@ int verify_multisig(uint8_t *prefilled_data, const uint8_t *lock_bytes,
return 0;
}

static bool require_secp256k1_data(uint8_t algorithm_id) {
switch (algorithm_id) {
case AuthAlgorithmIdCkb:
case AuthAlgorithmIdEthereum:
case AuthAlgorithmIdEos:
case AuthAlgorithmIdTron:
case AuthAlgorithmIdBitcoin:
case AuthAlgorithmIdDogecoin:
case AuthAlgorithmIdCkbMultisig:
case AuthAlgorithmIdSchnorr:
case AuthAlgorithmIdLitecoin:
case AuthAlgorithmIdRipple:
return true;
default:
return false;
}
return false;
}

// dynamic linking entry
__attribute__((visibility("default"))) int ckb_auth_load_prefilled_data(
uint8_t algorithm_id, uint8_t *prefilled_data, size_t *len) {
if (require_secp256k1_data(algorithm_id)) {
if (prefilled_data == NULL) {
if (*len == 0) {
*len = CKB_AUTH_RECOMMEND_PREFILLED_LEN;
return 0;
} else {
return ERROR_PREFILLED;
}
} else {
if (*len >= CKB_AUTH_RECOMMEND_PREFILLED_LEN) {
size_t index = SIZE_MAX;
int err =
ckb_look_for_dep_with_hash(ckb_secp256k1_data_hash, &index);
if (err) {
return err;
}
uint64_t len = CKB_AUTH_RECOMMEND_PREFILLED_LEN;
err = ckb_load_cell_data(prefilled_data, &len, 0, index,
CKB_SOURCE_CELL_DEP);
if (err || len != CKB_AUTH_RECOMMEND_PREFILLED_LEN) {
return ERROR_PREFILLED;
}
return 0;
} else {
return ERROR_PREFILLED;
}
}
} else {
if (prefilled_data == NULL) {
if (*len == 0) {
return 0;
} else {
return ERROR_PREFILLED;
}
} else {
*len = 0;
return 0;
}
}
}

__attribute__((visibility("default"))) int ckb_auth_validate(
uint8_t *prefilled_data, uint8_t algorithm_id, const uint8_t *sig,
size_t sig_len, const uint8_t *msg, size_t msg_len, uint8_t *pubkey_hash,
Expand Down
1 change: 0 additions & 1 deletion c/auth.syms
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{
ckb_auth_validate;
ckb_auth_load_prefilled_data;
};
8 changes: 1 addition & 7 deletions c/auth_libecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,6 @@ static int verify_secp256r1(CkbAuthValidatorType *validator,
return err;
}

// secp256r1 don't need prefilled data.
__attribute__((visibility("default"))) int ckb_auth_load_prefilled_data(
uint8_t algorithm_id, uint8_t *prefilled_data, size_t *len) {
*len = 0;
return 0;
}

// dynamic linking entry
__attribute__((visibility("default"))) int ckb_auth_validate(
uint8_t *prefilled_data, uint8_t algorithm_id, const uint8_t *sig,
Expand All @@ -123,6 +116,7 @@ __attribute__((visibility("default"))) int ckb_auth_validate(
CHECK2(msg != NULL, ERROR_INVALID_ARG);
CHECK2(msg_len > 0, ERROR_INVALID_ARG);
CHECK2(pubkey_hash_len == AUTH160_SIZE, ERROR_INVALID_ARG);

if (algorithm_id == AuthAlgorithmIdSecp256R1) {
err = verify_secp256r1(&validator, validate_signature_secp256r1,
convert_copy);
Expand Down
66 changes: 8 additions & 58 deletions c/ckb_auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@
#define CKB_AUTH_LEN 21
#define AUTH160_SIZE 20
#define BLAKE2B_BLOCK_SIZE 32
// This recommended values is from secp256k1 data but might be changed in the
// future. The buffer with this size must be success to call
// ckb_auth_load_prefilled_data, for any algorithm id. For dependency issue,
// don't include secp256k1_data_info_20210801.h in this file.
#define CKB_AUTH_RECOMMEND_PREFILLED_LEN 1048576

enum AuthErrorCodeType {
ERROR_NOT_IMPLEMENTED = 100,
Expand All @@ -52,8 +47,6 @@ enum AuthErrorCodeType {
ERROR_SPAWN_INVALID_PUBKEY,
// schnorr
ERROR_SCHNORR,
// prefilled error
ERROR_PREFILLED,
};

typedef struct CkbAuthType {
Expand Down Expand Up @@ -103,9 +96,6 @@ typedef int (*ckb_auth_validate_t)(uint8_t *prefilled_data,
size_t sig_len, const uint8_t *msg,
size_t msg_len, uint8_t *pubkey_hash,
size_t pubkey_hash_len);
typedef int (*ckb_auth_load_prefilled_data_t)(uint8_t algorithm_id,
uint8_t *prefilled_data,
size_t *len);

typedef struct CkbAuthValidatorType {
uint8_t *prefilled_data;
Expand All @@ -118,9 +108,6 @@ typedef struct CkbAuthValidatorType {
size_t pubkey_hash_len;
} CkbAuthValidatorType;

int ckb_auth_load_prefilled_data(uint8_t algorithm_id, uint8_t *prefilled_data,
size_t *len);

#ifndef CKB_AUTH_DISABLE_DYNAMIC_LIB

#ifndef CKB_AUTH_DL_BUFF_SIZE
Expand All @@ -143,22 +130,18 @@ typedef struct {

void *handle;
ckb_auth_validate_t func;
ckb_auth_load_prefilled_data_t func2;
} CkbDLCache;

static CkbDLCache g_dl_cache[CKB_AUTH_DL_MAX_COUNT];
static size_t g_dl_cache_count = 0;

int get_dl_func_by_code_hash(const uint8_t *code_hash, uint8_t hash_type,
ckb_auth_validate_t *out_func,
ckb_auth_load_prefilled_data_t *out_func2) {
ckb_auth_validate_t *out_func) {
// Find from cache
for (size_t i = 0; i < g_dl_cache_count; i++) {
CkbDLCache *cache = &g_dl_cache[i];
if (memcmp(cache->code_hash, code_hash, BLAKE2B_BLOCK_SIZE) == 0 &&
hash_type == cache->hash_type) {
*out_func = cache->func;
*out_func2 = cache->func2;
return 0;
}
}
Expand Down Expand Up @@ -190,14 +173,8 @@ int get_dl_func_by_code_hash(const uint8_t *code_hash, uint8_t hash_type,
if (cache->func == 0) {
return CKB_INVALID_DATA;
}
cache->func2 = (ckb_auth_load_prefilled_data_t)ckb_dlsym(
cache->handle, "ckb_auth_load_prefilled_data");
if (cache->func2 == 0) {
return CKB_INVALID_DATA;
}

*out_func = cache->func;
*out_func2 = cache->func2;
memcpy(cache->code_hash, code_hash, BLAKE2B_BLOCK_SIZE);
cache->hash_type = hash_type;

Expand All @@ -207,28 +184,7 @@ int get_dl_func_by_code_hash(const uint8_t *code_hash, uint8_t hash_type,

#endif // CKB_AUTH_DISABLE_DYNAMIC_LIB

int ckb_auth_prepare(CkbEntryType *entry, uint8_t algorithm_id,
uint8_t *prefilled_data, size_t *len) {
if (entry->entry_category == EntryCategoryDynamicLibrary) {
#ifdef CKB_AUTH_DISABLE_DYNAMIC_LIB
// none dynamic library doesn't require prepare
return 0;
#else // CKB_AUTH_DISABLE_DYNAMIC_LIB
ckb_auth_validate_t func = NULL;
ckb_auth_load_prefilled_data_t func2 = NULL;
int err = get_dl_func_by_code_hash(entry->code_hash, entry->hash_type,
&func, &func2);
if (err) {
return err;
}
return func2(algorithm_id, prefilled_data, len);
#endif // CKB_AUTH_DISABLE_DYNAMIC_LIB
} else {
return 0;
}
}

int ckb_auth(CkbEntryType *entry, uint8_t *prefilled_data, CkbAuthType *id,
int ckb_auth(uint8_t *prefilled_data, CkbEntryType *entry, CkbAuthType *id,
const uint8_t *signature, uint32_t signature_size,
const uint8_t *message32) {
int err = 0;
Expand All @@ -238,9 +194,8 @@ int ckb_auth(CkbEntryType *entry, uint8_t *prefilled_data, CkbAuthType *id,
return ERROR_INVALID_ARG;
#else // CKB_AUTH_DISABLE_DYNAMIC_LIB
ckb_auth_validate_t func = NULL;
ckb_auth_load_prefilled_data_t func2 = NULL;
err = get_dl_func_by_code_hash(entry->code_hash, entry->hash_type,
&func, &func2);
err =
get_dl_func_by_code_hash(entry->code_hash, entry->hash_type, &func);
if (err) {
return err;
}
Expand Down Expand Up @@ -355,15 +310,10 @@ static int ckb_auth_validate_with_func(int argc, char *argv[],
pubkey_hash_len == AUTH160_SIZE,
ERROR_SPAWN_INVALID_PUBKEY);

// In exec/spawn, it's safe to allocate big stack memory since the script
// owns whole 4M memory.
uint8_t secp_data[CKB_AUTH_RECOMMEND_PREFILLED_LEN];
size_t len = sizeof(secp_data);
err = ckb_auth_load_prefilled_data(algorithm_id, secp_data, &len);
CHECK(err);
err = validate_func(secp_data, algorithm_id, signature,
(size_t)signature_len, message, (size_t)message_len,
pubkey_hash, (size_t)pubkey_hash_len);
// TODO: load prefilled data when in entry of exec/spawn
err = validate_func(NULL, algorithm_id, signature, (size_t)signature_len,
message, (size_t)message_len, pubkey_hash,
(size_t)pubkey_hash_len);
CHECK(err);

exit:
Expand Down
5 changes: 3 additions & 2 deletions c/ripple.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,16 +215,17 @@ int get_ripple_verify_data(const uint8_t *sign, size_t sign_len,
#undef SIGN_BUFF_OFFSET
}

int verify_ripple(uint8_t *prefilled_data, RippleSignatureData *data) {
int verify_ripple(RippleSignatureData *data) {
int err = 0;

uint8_t msg_hash[256];
const mbedtls_md_info_t *md_info =
mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
CHECK(mbedtls_md(md_info, data->sign_msg, data->sign_msg_len, msg_hash));

uint8_t secp256k1_ctx_buf[CKB_SECP256K1_DATA_SIZE];
secp256k1_context ctx;
ckb_secp256k1_custom_verify_only_initialize(&ctx, prefilled_data);
ckb_secp256k1_custom_verify_only_initialize(&ctx, secp256k1_ctx_buf);

secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
Expand Down
Loading
Loading