From ea8cdfb46ebfeaa90e7ca4aac20684525c13d76d Mon Sep 17 00:00:00 2001 From: xjd Date: Tue, 6 Feb 2024 11:09:56 +0800 Subject: [PATCH] Revert "Support prefilled data in dynamic library (#41)" (#42) This reverts commit 6c84034b5b43fe04ce66691ce2fe3fd95562e07f. --- c/auth.c | 101 ++++-------------- c/auth.syms | 1 - c/auth_libecc.c | 8 +- c/ckb_auth.h | 66 ++---------- c/ripple.h | 5 +- c/secp256k1_helper_20210801.h | 44 +++++++- ckb-auth-rs/src/ckb_auth.rs | 10 +- ckb-auth-rs/src/ckb_auth_dl.rs | 42 +------- ckb-auth-rs/src/lib.rs | 11 +- docs/auth.md | 57 +--------- tests/Makefile | 9 -- tests/auth-c-lock/auth_c_lock.c | 23 ++-- .../contracts/auth-rust-demo/src/entry.rs | 23 +--- 13 files changed, 96 insertions(+), 304 deletions(-) diff --git a/c/auth.c b/c/auth.c index dad18a7..a02849f 100644 --- a/c/auth.c +++ b/c/auth.c @@ -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, @@ -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; } @@ -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) { @@ -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; } @@ -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; @@ -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 @@ -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; @@ -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]; @@ -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; @@ -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; @@ -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. @@ -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, diff --git a/c/auth.syms b/c/auth.syms index 6fc0a5b..6e7d480 100644 --- a/c/auth.syms +++ b/c/auth.syms @@ -1,4 +1,3 @@ { ckb_auth_validate; - ckb_auth_load_prefilled_data; }; diff --git a/c/auth_libecc.c b/c/auth_libecc.c index 7fa8c66..53175b1 100644 --- a/c/auth_libecc.c +++ b/c/auth_libecc.c @@ -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, @@ -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); diff --git a/c/ckb_auth.h b/c/ckb_auth.h index fe17b76..728aa1f 100644 --- a/c/ckb_auth.h +++ b/c/ckb_auth.h @@ -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, @@ -52,8 +47,6 @@ enum AuthErrorCodeType { ERROR_SPAWN_INVALID_PUBKEY, // schnorr ERROR_SCHNORR, - // prefilled error - ERROR_PREFILLED, }; typedef struct CkbAuthType { @@ -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; @@ -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 @@ -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; } } @@ -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; @@ -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; @@ -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; } @@ -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: diff --git a/c/ripple.h b/c/ripple.h index 7c53398..920d81b 100644 --- a/c/ripple.h +++ b/c/ripple.h @@ -215,7 +215,7 @@ 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]; @@ -223,8 +223,9 @@ int verify_ripple(uint8_t *prefilled_data, RippleSignatureData *data) { 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; diff --git a/c/secp256k1_helper_20210801.h b/c/secp256k1_helper_20210801.h index ac04333..107190b 100644 --- a/c/secp256k1_helper_20210801.h +++ b/c/secp256k1_helper_20210801.h @@ -34,7 +34,42 @@ void secp256k1_default_error_callback_fn(const char* str, void* data) { * so as to hold all loaded data. */ int ckb_secp256k1_custom_verify_only_initialize(secp256k1_context* context, - uint8_t* prefilled_data) { + 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; @@ -42,9 +77,10 @@ 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 */ - secp256k1_ge_storage(*pre_g)[] = (secp256k1_ge_storage(*)[])prefilled_data; - secp256k1_ge_storage(*pre_g_128)[] = (secp256k1_ge_storage(*)[])( - &prefilled_data[CKB_SECP256K1_DATA_PRE_SIZE]); + 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; diff --git a/ckb-auth-rs/src/ckb_auth.rs b/ckb-auth-rs/src/ckb_auth.rs index 58ec259..c807f32 100644 --- a/ckb-auth-rs/src/ckb_auth.rs +++ b/ckb-auth-rs/src/ckb_auth.rs @@ -6,16 +6,16 @@ use alloc::format; use ckb_std::high_level::exec_cell; use hex::encode; -#[cfg(feature = "enable-dynamic-library")] -use super::ckb_auth_dl::ckb_auth_dl; #[cfg(feature = "ckb2023")] use alloc::vec::Vec; #[cfg(feature = "ckb2023")] use ckb_std::high_level::spawn_cell; +#[cfg(feature = "enable-dynamic-library")] +use super::ckb_auth_dl::ckb_auth_dl; + pub fn ckb_auth( entry: &CkbEntryType, - prefilled_data: &[u8], id: &CkbAuthType, signature: &[u8], message: &[u8; 32], @@ -23,9 +23,7 @@ pub fn ckb_auth( match entry.entry_category { EntryCategoryType::Exec => ckb_auth_exec(entry, id, signature, message), #[cfg(feature = "enable-dynamic-library")] - EntryCategoryType::DynamicLibrary => { - ckb_auth_dl(entry, prefilled_data, id, signature, message) - } + EntryCategoryType::DynamicLibrary => ckb_auth_dl(entry, id, signature, message), #[cfg(feature = "ckb2023")] EntryCategoryType::Spawn => ckb_auth_spawn(entry, id, signature, message), } diff --git a/ckb-auth-rs/src/ckb_auth_dl.rs b/ckb-auth-rs/src/ckb_auth_dl.rs index bd3a9b9..ce20061 100644 --- a/ckb-auth-rs/src/ckb_auth_dl.rs +++ b/ckb-auth-rs/src/ckb_auth_dl.rs @@ -1,4 +1,4 @@ -use crate::{AuthAlgorithmIdType, CkbAuthError, CkbAuthType, CkbEntryType}; +use crate::{CkbAuthError, CkbAuthType, CkbEntryType}; use alloc::boxed::Box; use alloc::collections::BTreeMap; use ckb_std::{ @@ -21,8 +21,6 @@ type DLContext = CKBDLContext<[u8; 600 * 1024]>; const RISCV_PGSIZE: usize = 4096; -pub const RECOMMEND_PREFILLED_LEN: usize = 1048576; - type CkbAuthValidate = unsafe extern "C" fn( prefilled_data: *const u8, auth_algorithm_id: u8, @@ -34,11 +32,7 @@ type CkbAuthValidate = unsafe extern "C" fn( pubkey_hash_size: usize, ) -> i32; -type CkbLoadPrefilledData = - unsafe extern "C" fn(auth_algorithm_id: u8, data: *mut u8, len: *mut usize) -> i32; - const EXPORTED_FUNC_NAME: &str = "ckb_auth_validate"; -const EXPORTED_PREFILLED_FUNC_NAME: &str = "ckb_auth_load_prefilled_data"; struct CKBDLLoader { pub context: Box, @@ -122,7 +116,6 @@ impl CKBDLLoader { pub fn ckb_auth_dl( entry: &CkbEntryType, - prefilled_data: &[u8], id: &CkbAuthType, signature: &[u8], message: &[u8; 32], @@ -134,9 +127,10 @@ pub fn ckb_auth_dl( )?; let mut pub_key = id.pubkey_hash.clone(); + // TODO: let rc_code = unsafe { func( - prefilled_data.as_ptr() as *const u8, + 0 as *const u8, id.algorithm_id.clone().into(), signature.as_ptr(), signature.len() as usize, @@ -152,33 +146,3 @@ pub fn ckb_auth_dl( _ => Err(CkbAuthError::RunDLError), } } - -pub fn ckb_auth_prepare( - entry: &CkbEntryType, - algorithm_id: AuthAlgorithmIdType, - prefilled_data: &mut [u8], - len: &mut usize, -) -> Result<(), CkbAuthError> { - let func: Symbol = CKBDLLoader::get().get_validate_func( - &entry.code_hash, - entry.hash_type, - EXPORTED_PREFILLED_FUNC_NAME, - )?; - // always fetch the prefilled data length regardless of whether the - // operation succeeds or fails. - let mut prefilled_len = 0; - unsafe { - func( - algorithm_id.clone().into(), - 0 as *mut u8, - &mut prefilled_len, - ); - } - - let code = unsafe { func(algorithm_id.into(), prefilled_data.as_mut_ptr(), len) }; - *len = prefilled_len; - match code { - 0 => Ok(()), - _ => Err(CkbAuthError::RunDLError), - } -} diff --git a/ckb-auth-rs/src/lib.rs b/ckb-auth-rs/src/lib.rs index 52600c4..cba96b7 100644 --- a/ckb-auth-rs/src/lib.rs +++ b/ckb-auth-rs/src/lib.rs @@ -5,18 +5,15 @@ use core::mem::transmute; #[cfg(target_arch = "riscv64")] mod ckb_auth; +#[cfg(target_arch = "riscv64")] +pub use ckb_auth::ckb_auth; + #[cfg(all(feature = "enable-dynamic-library", target_arch = "riscv64"))] mod ckb_auth_dl; #[cfg(target_arch = "riscv64")] mod generate_sighash_all; -#[cfg(target_arch = "riscv64")] -pub use ckb_auth::ckb_auth; - -#[cfg(all(feature = "enable-dynamic-library", target_arch = "riscv64"))] -pub use ckb_auth_dl::{ckb_auth_prepare, RECOMMEND_PREFILLED_LEN}; - #[cfg(target_arch = "riscv64")] pub use crate::generate_sighash_all::generate_sighash_all; @@ -24,7 +21,6 @@ pub use crate::generate_sighash_all::generate_sighash_all; use alloc::ffi::NulError; #[cfg(target_arch = "riscv64")] use ckb_std::{ckb_types::core::ScriptHashType, error::SysError}; - #[cfg(not(target_arch = "riscv64"))] type SysError = u64; #[cfg(not(target_arch = "riscv64"))] @@ -85,7 +81,6 @@ pub enum CkbAuthError { EncodeArgs, GenerateSigHash, UnsupportEntryType, - PrefilledData, } #[cfg(target_arch = "riscv64")] diff --git a/docs/auth.md b/docs/auth.md index 5972143..9deb4a9 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -184,7 +184,7 @@ typedef struct CkbEntryType { We should export the follow function from dynamic library when entry category is `dynamic library`: ```C -int ckb_auth_load_prefilled_data(uint8_t auth_algorithm_id, uint8_t *prefilled_data, size_t *len); +int ckb_auth_load_prefilled_data(uint8_t auth_algorithm_id, void *prefilled_data, size_t *len); ``` The first argument denotes the `algorithm_id` in `CkbAuthType`. The `prefilled` and `len` will be described below. @@ -250,11 +250,10 @@ The invocation method is the same as that of `Spawn`. ### High Level APIs The following API can combine the low level APIs together: ```C -int ckb_auth_prepare(uint8_t auth_algorithm_id, uint8_t *prefilled_data, size_t *len); -int ckb_auth(EntryType* entry, uint8_t* prefilled_data, CkbAuthType *id, uint8_t *signature, uint32_t signature_size, const uint8_t *message32) +int ckb_auth_load_prefilled_data(uint8_t auth_algorithm_id, void *prefilled_data, size_t *len); +int ckb_auth(EntryType* entry, CkbAuthType *id, uint8_t *signature, uint32_t signature_size, const uint8_t *message32) ``` Most of developers only need to use these functions without knowing the low level APIs. -The behavior of `ckb_auth_prepare` is identical to `ckb_auth_load_prefilled_data`. ### Rust High Level APIs @@ -264,10 +263,9 @@ Dependencies name: `ckb-auth-rs` #### API Description ``` rust -pub fn ckb_auth_prepare(entry: &CkbEntryType, algorithm_id: AuthAlgorithmIdType, prefilled_data: &mut [u8],len: &mut usize); +pub fn ckb_auth_load_prefilled_data(auth_algorithm_id: u8, prefilled_data: &mut[u8]); pub fn ckb_auth( entry: &CkbEntryType, - prefilled_data: &[u8], id: &CkbAuthType, signature: &[u8], message: &[u8; 32], @@ -282,53 +280,6 @@ pub fn ckb_auth( `message` : Participate in the message data of the signature. -Note that `ckb_auth_prepare` is nearly identical to the C version's -`ckb_auth_prepare`. However, since it is not possible to pass a variable like -`NULL` as `&mut [u8]` in Rust, the len function will always return the length of -the required prefilled data, regardless of whether the operation succeeds or -fails. - -### Examples of High Level API - - -Recommended way to use high level APIs in C: -```C -// while using ckb-auth with dynamic library, the stack memory space is limited. -// Put it in global variables(bss section) or allocator memory to avoid stack overflow. -uint8_t g_secp_data[CKB_AUTH_RECOMMEND_PREFILLED_LEN]; -size_t g_secp_data_len = sizeof(g_secp_data); -int main() { - // other code ... - int ret = ckb_auth_prepare(&entry, algorithm_id, g_secp_data, &g_secp_data_len); - if (ret) { - return ret; - } - ret = ckb_auth(&entry, g_secp_data, &auth, sig, sig_len, msg); - // other code ... -} -``` - -Recommended way to use high level APIs in Rust: -```Rust -static mut SECP_DATA: [u8; RECOMMEND_PREFILLED_LEN] = [0u8; RECOMMEND_PREFILLED_LEN]; -pub fn main() { - // other code ... - let secp_data = { - let mut len: usize = RECOMMEND_PREFILLED_LEN; - ckb_auth_prepare( - &entry, - algorithm_id, - unsafe { &mut SECP_DATA }, - &mut len, - )?; - unsafe { &SECP_DATA } - }; - ckb_auth(&entry, secp_data, &id, &signature, &message)?; - // other code ... -} -``` - - #### Other Issues for High Level C APIs A dynamic library will create a cache in static memory for loading ckb-auth. This cache is initially set to 200k, and if adjustments are necessary, you can diff --git a/tests/Makefile b/tests/Makefile index 78e6c76..d48b7e5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -13,15 +13,6 @@ all: \ rust-demo-tests-only-ckb2023 \ rust-demo-tests-only-dl -dev: \ - build-auth-lock \ - c-tests \ - rust-demo-tests \ - spawn-tests \ - rust-demo-tests-no-def-features \ - rust-demo-tests-only-ckb2023 \ - rust-demo-tests-only-dl - all-with-clang: \ build-auth-lock-with-clang \ c-tests \ diff --git a/tests/auth-c-lock/auth_c_lock.c b/tests/auth-c-lock/auth_c_lock.c index f4fd8dc..3b9e2f9 100644 --- a/tests/auth-c-lock/auth_c_lock.c +++ b/tests/auth-c-lock/auth_c_lock.c @@ -3,7 +3,7 @@ // entry category> see `CkbEntryType` // // witness lock: signature -#define CKB_C_STDLIB_PRINTF + #include "blake2b.h" #include "blockchain.h" #include "ckb_auth.h" @@ -152,12 +152,6 @@ int generate_sighash_all(uint8_t *msg, size_t msg_len) { return 0; } -// while using ckb-auth with dynamic library, the stack memory space is limited. -// Put it in global variables(bss section) or allocator memory to avoid stack -// overflow. -uint8_t g_secp_data[CKB_AUTH_RECOMMEND_PREFILLED_LEN]; -size_t g_secp_data_len = sizeof(g_secp_data); - int main() { int ret; uint64_t len = 0; @@ -220,7 +214,6 @@ int main() { case AuthAlgorithmIdRipple: if (lock_bytes_seg.ptr[lock_bytes_seg.size - 1] >= lock_bytes_seg.size) { - printf("AuthAlgorithmIdRipple"); return 102; // ERROR_INVALID_ARG } lock_bytes_seg.size -= lock_bytes_seg.ptr[lock_bytes_seg.size - 1]; @@ -228,20 +221,16 @@ int main() { default: break; } - ret = ckb_auth_prepare(&entry, auth.algorithm_id, g_secp_data, - &g_secp_data_len); - if (ret) { - return ret; - } + // ckb_auth can be invoked multiple times for different signatures. // Here we use the same one to demo the usages. - ret = ckb_auth(&entry, g_secp_data, &auth, lock_bytes_seg.ptr, - lock_bytes_seg.size, msg32); + ret = ckb_auth(0, &entry, &auth, lock_bytes_seg.ptr, lock_bytes_seg.size, + msg32); if (ret) { return ret; } - ret = ckb_auth(&entry, g_secp_data, &auth, lock_bytes_seg.ptr, - lock_bytes_seg.size, msg32); + ret = ckb_auth(0, &entry, &auth, lock_bytes_seg.ptr, lock_bytes_seg.size, + msg32); if (ret) { return ret; } diff --git a/tests/auth-rust-lock/contracts/auth-rust-demo/src/entry.rs b/tests/auth-rust-lock/contracts/auth-rust-demo/src/entry.rs index 8aca25a..fbe9535 100644 --- a/tests/auth-rust-lock/contracts/auth-rust-demo/src/entry.rs +++ b/tests/auth-rust-lock/contracts/auth-rust-demo/src/entry.rs @@ -1,5 +1,6 @@ // Import from `core` instead of from `std` since we are in no-std mode use core::result::Result; + // Import heap related library from `alloc` // https://doc.rust-lang.org/alloc/index.html // use alloc::{vec, vec::Vec}; @@ -13,16 +14,13 @@ use ckb_auth_rs::{ ckb_auth, generate_sighash_all, AuthAlgorithmIdType, CkbAuthError, CkbAuthType, CkbEntryType, EntryCategoryType, }; -#[cfg(feature = "enable-dynamic-library")] -use ckb_auth_rs::{ckb_auth_prepare, RECOMMEND_PREFILLED_LEN}; use ckb_std::{ ckb_constants::Source, ckb_types::{bytes::Bytes, core::ScriptHashType, prelude::*}, high_level::{load_script, load_witness_args}, }; -#[cfg(feature = "enable-dynamic-library")] -static mut SECP_DATA: [u8; RECOMMEND_PREFILLED_LEN] = [0u8; RECOMMEND_PREFILLED_LEN]; +// use ckb_std::debug; pub fn main() -> Result<(), Error> { let mut pubkey_hash = [0u8; 20]; @@ -86,24 +84,11 @@ pub fn main() -> Result<(), Error> { .map_err(|f| CkbAuthError::from(f)) .unwrap(), }; - #[cfg(feature = "enable-dynamic-library")] - let secp_data = { - let mut len: usize = RECOMMEND_PREFILLED_LEN; - ckb_auth_prepare( - &entry, - id.algorithm_id.clone(), - unsafe { &mut SECP_DATA }, - &mut len, - )?; - unsafe { &SECP_DATA } - }; - #[cfg(not(feature = "enable-dynamic-library"))] - let secp_data = &mut [0u8; 1]; - ckb_auth(&entry, secp_data, &id, &signature, &message)?; + ckb_auth(&entry, &id, &signature, &message)?; // ckb_auth can be invoked multiple times for different signatures. Here we // use the same one to demo the usage. - ckb_auth(&entry, secp_data, &id, &signature, &message)?; + ckb_auth(&entry, &id, &signature, &message)?; Ok(()) }