From 670265336da4844265e490f8a5c5f598958460f4 Mon Sep 17 00:00:00 2001 From: joii2020 Date: Wed, 10 Jan 2024 17:19:48 +0800 Subject: [PATCH] Display message while signing * add new ethereum algorithm id(18) for displaying message * update bitcoin algorithm id * keep eos/tron/dogecoin as same to PW --- build.rs | 2 +- c/ckb_identity.h | 120 ++++++++++++++++------------- tests/omni_lock_rust/tests/misc.rs | 21 +++-- 3 files changed, 84 insertions(+), 59 deletions(-) diff --git a/build.rs b/build.rs index 2413c56..37e63bf 100644 --- a/build.rs +++ b/build.rs @@ -39,7 +39,7 @@ const BINARIES: &[(&str, &str)] = &[ ), ( "omni_lock", - "dea31e1f104cf6a26ee3cbace40f6fa70e2deb556cd12fdc23eae15889d0d37b", + "f1cce5bed98ae1e40003d1388852e8ef2cb1be921adef6d2be9022e60238d331", ), ]; diff --git a/c/ckb_identity.h b/c/ckb_identity.h index c91746d..5dfe900 100644 --- a/c/ckb_identity.h +++ b/c/ckb_identity.h @@ -1,6 +1,5 @@ #ifndef CKB_C_STDLIB_CKB_IDENTITY_H_ #define CKB_C_STDLIB_CKB_IDENTITY_H_ - #include #include @@ -26,8 +25,8 @@ #define MAX_PREIMAGE_SIZE 1024 #define MESSAGE_HEX_LEN 64 -const char BTC_PREFIX[] = "Bitcoin layer (CKB) transaction: "; -// BTC_PREFIX_LEN = 33 +const char BTC_PREFIX[] = "CKB (Bitcoin Layer-2) transaction: "; +// BTC_PREFIX_LEN = 35 const size_t BTC_PREFIX_LEN = sizeof(BTC_PREFIX) - 1; const char COMMON_PREFIX[] = "CKB transaction: "; @@ -84,6 +83,15 @@ typedef int (*validate_signature_t)(void *prefilled_data, const uint8_t *sig, typedef int (*convert_msg_t)(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, size_t new_msg_len); +static void bin_to_hex(const uint8_t *source, uint8_t *dest, size_t len) { + const static uint8_t HEX_TABLE[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + for (int i = 0; i < len; i++) { + dest[i * 2] = HEX_TABLE[source[i] >> 4]; + dest[i * 2 + 1] = HEX_TABLE[source[i] & 0x0F]; + } +} + static int extract_witness_lock(uint8_t *witness, uint64_t len, mol_seg_t *lock_bytes_seg) { if (len < 20) { @@ -490,12 +498,17 @@ static int convert_eth_message_displaying(const uint8_t *msg, size_t msg_len, if (msg_len != new_msg_len || msg_len != BLAKE2B_BLOCK_SIZE) return ERROR_IDENTITY_ARGUMENTS_LEN; + uint8_t hex_msg[MESSAGE_HEX_LEN] = {0}; + bin_to_hex(msg, hex_msg, 32); + SHA3_CTX sha3_ctx; keccak_init(&sha3_ctx); - /* personal hash, ethereum prefix \u0019Ethereum Signed Message:\n32 */ + /* personal_sign ethereum prefix \u0019Ethereum Signed Message:\n */ unsigned char eth_prefix[28]; eth_prefix[0] = 0x19; - memcpy(eth_prefix + 1, "Ethereum Signed Message:\n32", 27); + memcpy(eth_prefix + 1, "Ethereum Signed Message:\n", 0x19); + // COMMON_PREFIX_LEN + MESSAGE_HEX_LEN -> 17 + 64 = 81 + memcpy(eth_prefix + 1 + 0x19, "81", 2); keccak_update(&sha3_ctx, eth_prefix, 28); // @@ -503,7 +516,7 @@ static int convert_eth_message_displaying(const uint8_t *msg, size_t msg_len, // CKB transaction: {txhash} // keccak_update(&sha3_ctx, (unsigned char *)COMMON_PREFIX, COMMON_PREFIX_LEN); - keccak_update(&sha3_ctx, (unsigned char *)msg, 32); + keccak_update(&sha3_ctx, (unsigned char *)hex_msg, MESSAGE_HEX_LEN); keccak_final(&sha3_ctx, new_msg); return 0; } @@ -534,44 +547,35 @@ int verify_sighash_all(uint8_t *pubkey_hash, uint8_t *sig, uint32_t sig_len, return 0; } -static void bin_to_hex(const uint8_t *source, uint8_t *dest, size_t len) { - const static uint8_t HEX_TABLE[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - for (int i = 0; i < len; i++) { - dest[i * 2] = HEX_TABLE[source[i] >> 4]; - dest[i * 2 + 1] = HEX_TABLE[source[i] & 0x0F]; - } -} - -int convert_btc_message_variant(const uint8_t *msg, size_t msg_len, - uint8_t *new_msg, size_t new_msg_len, - const char *magic, const uint8_t magic_len, - const char *prefix, size_t prefix_len) { +int convert_btc_message(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, + size_t new_msg_len) { if (msg_len != new_msg_len || msg_len != SHA256_SIZE) return ERROR_INVALID_ARG; + const char magic[25] = "Bitcoin Signed Message:\n"; + const int8_t magic_len = 24; + const char *prefix = BTC_PREFIX; + size_t prefix_len = BTC_PREFIX_LEN; // // Displaying message on wallet like below: // Bitcoin layer (CKB) transaction: {txhash} // - uint8_t temp[MESSAGE_HEX_LEN + prefix_len]; - memcpy(temp, prefix, prefix_len); - bin_to_hex(msg, temp + prefix_len, 32); + uint8_t hex_msg[MESSAGE_HEX_LEN]; + bin_to_hex(msg, hex_msg, 32); - // len of magic + magic string + len of message, size is 26 Byte - uint8_t new_magic[magic_len + 2]; - new_magic[0] = magic_len; // MESSAGE_MAGIC length - memcpy(&new_magic[1], magic, magic_len); - new_magic[magic_len + 1] = MESSAGE_HEX_LEN; // message length + // Signature message: + // magic_len magic prefix_len+MESSAGE_HEX_LEN prefix message_hex + // 1 magic_len 1 prefix_len 64 + uint8_t data[magic_len + 2 + MESSAGE_HEX_LEN + prefix_len]; + data[0] = magic_len; + memcpy(data + 1, magic, magic_len); - /* Calculate signature message */ - uint8_t temp2[magic_len + 2 + MESSAGE_HEX_LEN]; - uint32_t temp2_size = magic_len + 2 + MESSAGE_HEX_LEN; - memcpy(temp2, new_magic, magic_len + 2); - memcpy(temp2 + magic_len + 2, temp, MESSAGE_HEX_LEN); + data[magic_len + 1] = MESSAGE_HEX_LEN + prefix_len; + memcpy(data + magic_len + 2, prefix, prefix_len); + memcpy(data + magic_len + 2 + prefix_len, hex_msg, MESSAGE_HEX_LEN); SHA256_CTX sha256_ctx; sha256_init(&sha256_ctx); - sha256_update(&sha256_ctx, temp2, temp2_size); + sha256_update(&sha256_ctx, data, sizeof(data)); sha256_final(&sha256_ctx, new_msg); SHA256_CTX sha256_ctx2; @@ -589,23 +593,38 @@ int convert_copy(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, return 0; } -const char BTC_MESSAGE_MAGIC[25] = "Bitcoin Signed Message:\n"; -const int8_t BTC_MAGIC_LEN = 24; -int convert_btc_message(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, - size_t new_msg_len) { - return convert_btc_message_variant(msg, msg_len, new_msg, new_msg_len, - BTC_MESSAGE_MAGIC, BTC_MAGIC_LEN, - BTC_PREFIX, BTC_PREFIX_LEN); -} - -const char DOGE_MESSAGE_MAGIC[26] = "Dogecoin Signed Message:\n"; -const int8_t DOGE_MAGIC_LEN = 25; - int convert_doge_message(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, size_t new_msg_len) { - return convert_btc_message_variant(msg, msg_len, new_msg, new_msg_len, - DOGE_MESSAGE_MAGIC, DOGE_MAGIC_LEN, - COMMON_PREFIX, COMMON_PREFIX_LEN); + if (msg_len != new_msg_len || msg_len != SHA256_SIZE) + return ERROR_INVALID_ARG; + const char magic[26] = "Dogecoin Signed Message:\n"; + const int8_t magic_len = 25; + + uint8_t temp[MESSAGE_HEX_LEN]; + bin_to_hex(msg, temp, 32); + + // len of magic + magic string + len of message, size is 26 Byte + uint8_t new_magic[magic_len + 2]; + new_magic[0] = magic_len; // MESSAGE_MAGIC length + memcpy(&new_magic[1], magic, magic_len); + new_magic[magic_len + 1] = MESSAGE_HEX_LEN; // message length + + /* Calculate signature message */ + uint8_t temp2[magic_len + 2 + MESSAGE_HEX_LEN]; + uint32_t temp2_size = magic_len + 2 + MESSAGE_HEX_LEN; + memcpy(temp2, new_magic, magic_len + 2); + memcpy(temp2 + magic_len + 2, temp, MESSAGE_HEX_LEN); + + SHA256_CTX sha256_ctx; + sha256_init(&sha256_ctx); + sha256_update(&sha256_ctx, temp2, temp2_size); + sha256_final(&sha256_ctx, new_msg); + + SHA256_CTX sha256_ctx2; + sha256_init(&sha256_ctx2); + sha256_update(&sha256_ctx2, new_msg, SHA256_SIZE); + sha256_final(&sha256_ctx2, new_msg); + return 0; } int convert_tron_message(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, @@ -622,11 +641,6 @@ int convert_tron_message(const uint8_t *msg, size_t msg_len, uint8_t *new_msg, memcpy(tron_prefix + 1, "TRON Signed Message:\n32", 23); keccak_update(&sha3_ctx, tron_prefix, 24); - // - // Displaying message on wallet like below: - // CKB transaction: {txhash} - // - keccak_update(&sha3_ctx, (unsigned char *)COMMON_PREFIX, COMMON_PREFIX_LEN); keccak_update(&sha3_ctx, (unsigned char *)msg, 32); keccak_final(&sha3_ctx, new_msg); return 0; diff --git a/tests/omni_lock_rust/tests/misc.rs b/tests/omni_lock_rust/tests/misc.rs index 5ad7b60..bb9ccfc 100644 --- a/tests/omni_lock_rust/tests/misc.rs +++ b/tests/omni_lock_rust/tests/misc.rs @@ -92,13 +92,16 @@ pub const SECP256K1_TAG_PUBKEY_HYBRID_ODD: u8 = 0x07; // Refer to https://en.bitcoin.it/wiki/BIP_0137 // These values are used to denote the signature types of Bitcoin. -// Each type corresponds to a distinct public key hash and a unique signature +// Each type corresponds to a distinct public key hash and a unique signature // data header. pub const BITCOIN_V_TYPE_P2PKHUNCOMPRESSED: u8 = 27; pub const BITCOIN_V_TYPE_P2PKHCOMPRESSED: u8 = 31; pub const BITCOIN_V_TYPE_SEGWITP2SH: u8 = 35; pub const BITCOIN_V_TYPE_SEGWITBECH32: u8 = 39; +pub const BTC_PREFIX: &str = "CKB (Bitcoin Layer-2) transaction: "; +pub const COMMON_PREFIX: &str = "CKB transaction: "; + lazy_static! { pub static ref OMNI_LOCK: Bytes = Bytes::from(&include_bytes!("../../../build/omni_lock")[..]); pub static ref SIMPLE_UDT: Bytes = @@ -1211,13 +1214,22 @@ impl BitcoinConfig { } pub fn convert_message(&self, message: &[u8; 32]) -> CkbH256 { - let message_magic = b"\x18Bitcoin Signed Message:\n\x40"; + let message_magic = b"Bitcoin Signed Message:\n"; let msg_hex = hex::encode(message); assert_eq!(msg_hex.len(), 64); - let mut temp2: BytesMut = BytesMut::with_capacity(message_magic.len() + msg_hex.len()); + let mut temp2: BytesMut = + BytesMut::with_capacity(1 + message_magic.len() + 1 + BTC_PREFIX.len() + msg_hex.len()); + temp2.put_u8(message_magic.len() as u8); temp2.put(Bytes::from(message_magic.to_vec())); - temp2.put(Bytes::from(hex::encode(message))); + + temp2.put_u8(0x40 + BTC_PREFIX.len() as u8); + + temp2.put(Bytes::from(format!( + "{}{}", + BTC_PREFIX, + hex::encode(message) + ))); let msg = calculate_sha256(&temp2.to_vec()); let msg = calculate_sha256(&msg); @@ -1260,7 +1272,6 @@ impl DogecoinConfig { let msg = calculate_sha256(&temp2.to_vec()); let msg = calculate_sha256(&msg); - CkbH256::from(msg) }