Skip to content

Commit

Permalink
Solana (phantom wallet) support
Browse files Browse the repository at this point in the history
  • Loading branch information
XuJiandong committed Apr 11, 2024
1 parent cd764d7 commit 1a09a42
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 42 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
path = deps/secp256k1-20210801
url = https://github.com/nervosnetwork/secp256k1.git
branch = schnorr
[submodule "deps/ed25519"]
path = deps/ed25519
url = https://github.com/nervosnetwork/ed25519.git
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ CLANG_FORMAT_DOCKER := kason223/clang-format@sha256:3cce35b0400a7d420ec8504558a0
all: build/omni_lock build/always_success

all-via-docker: ${PROTOCOL_HEADER}
docker run --rm -v `pwd`:/code ${BUILDER_DOCKER} bash -c "cd /code && make"
docker run -u $(shell id -u):$(shell id -g) --rm -v `pwd`:/code ${BUILDER_DOCKER} bash -c "cd /code && make"


build/always_success: c/always_success.c
Expand All @@ -47,6 +47,15 @@ $(SECP256K1_SRC_20210801):
make src/ecmult_static_pre_context.h src/ecmult_static_context.h


build/ed25519/%.o: deps/ed25519/src/%.c
mkdir -p build/ed25519
$(CC) -c -DCKB_DECLARATION_ONLY -I deps/ed25519/src $(OMNI_LOCK_CFLAGS) -o $@ $^

build/libed25519.a: build/ed25519/sign.o build/ed25519/verify.o build/ed25519/sha512.o build/ed25519/sc.o build/ed25519/keypair.o \
build/ed25519/key_exchange.o build/ed25519/ge.o build/ed25519/fe.o build/ed25519/add_scalar.o
$(AR) cr $@ $^


build/impl.o: deps/ckb-c-std-lib/libc/src/impl.c
$(CC) -c $(filter-out -DCKB_DECLARATION_ONLY, $(CFLAGS_MBEDTLS)) $(LDFLAGS_MBEDTLS) -o $@ $^

Expand Down Expand Up @@ -76,8 +85,8 @@ omni_lock_mol:
${MOLC} --language - --schema-file c/omni_lock.mol --format json > build/omni_lock_mol2.json
moleculec-c2 --input build/omni_lock_mol2.json | clang-format -style=Google > c/omni_lock_mol2.h

build/omni_lock: 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
$(CC) $(OMNI_LOCK_CFLAGS) $(LDFLAGS) -o $@ $<
build/omni_lock: 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/libed25519.a
$(CC) $(OMNI_LOCK_CFLAGS) $(LDFLAGS) -o $@ $< build/libed25519.a
cp $@ $@.debug
$(OBJCOPY) --strip-debug --strip-all $@

Expand All @@ -88,6 +97,7 @@ clean:
rm -rf build/*.debug
rm -f build/omni_lock
cd deps/secp256k1-20210801 && [ -f "Makefile" ] && make clean
rm -rf build/ed25519 build/libed25519.a

install-tools:
if [ ! -x "$$(command -v "${MOLC}")" ] \
Expand Down
50 changes: 44 additions & 6 deletions c/ckb_identity.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
#define SECP256K1_MESSAGE_SIZE 32
#define MAX_PREIMAGE_SIZE 1024
#define MESSAGE_HEX_LEN 64
#define ED25519_SIGNATURE_SIZE 64
#define ED25519_PUBKEY_SIZE 32

const char BTC_PREFIX[] = "CKB (Bitcoin Layer) transaction: 0x";
// BTC_PREFIX_LEN = 35
const size_t BTC_PREFIX_LEN = sizeof(BTC_PREFIX) - 1;
#define BTC_PREFIX_LEN (sizeof(BTC_PREFIX) - 1)

const char COMMON_PREFIX[] = "CKB transaction: 0x";
// COMMON_PREFIX_LEN = 17
const size_t COMMON_PREFIX_LEN = sizeof(COMMON_PREFIX) - 1;
// COMMON_PREFIX_LEN = 19
#define COMMON_PREFIX_LEN (sizeof(COMMON_PREFIX) - 1)

enum CkbIdentityErrorCode {
ERROR_IDENTITY_ARGUMENTS_LEN = -1,
Expand Down Expand Up @@ -61,7 +63,6 @@ typedef struct CkbIdentityType {

enum IdentityFlagsType {
IdentityFlagsCkb = 0,
// values 1~5 are used by pw-lock
IdentityFlagsEthereum = 1,
IdentityFlagsEos = 2,
IdentityFlagsTron = 3,
Expand All @@ -70,6 +71,7 @@ enum IdentityFlagsType {
IdentityCkbMultisig = 6,

IdentityFlagsEthereumDisplaying = 18,
IdentityFlagsSolana = 19,
IdentityFlagsOwnerLock = 0xFC,
IdentityFlagsExec = 0xFD,
IdentityFlagsDl = 0xFE,
Expand Down Expand Up @@ -374,6 +376,37 @@ int validate_signature_eos(void *prefilled_data, const uint8_t *sig,
return err;
}

int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key);
int validate_signature_solana(void *prefilled_data, const uint8_t *sig,
size_t sig_len, const uint8_t *msg, size_t msg_len,
uint8_t *output, size_t *output_len) {
if (*output_len < AUTH160_SIZE || msg_len != SHA256_SIZE) {
return ERROR_INVALID_ARG;
}

// CKB transaction: 0x<signing message hash, hex format>
uint8_t displaying_msg[COMMON_PREFIX_LEN + MESSAGE_HEX_LEN] = {0};
memcpy(displaying_msg, COMMON_PREFIX, COMMON_PREFIX_LEN);
bin_to_hex(msg, displaying_msg + COMMON_PREFIX_LEN, msg_len);

// Unlike secp256k1, Ed25519 cannot recover the public key from the signature alone.
// The public key is located immediately after the signature.
const uint8_t* pubkey = sig + ED25519_SIGNATURE_SIZE;
int success = ed25519_verify(sig, displaying_msg, sizeof(displaying_msg), pubkey);
if (!success) {
return ERROR_MISMATCHED;
}

uint8_t hash[SHA256_SIZE] = {0};
blake2b_state ctx;
blake2b_init(&ctx, BLAKE2B_BLOCK_SIZE);
blake2b_update(&ctx, pubkey, ED25519_PUBKEY_SIZE);
blake2b_final(&ctx, hash, BLAKE2B_BLOCK_SIZE);
memcpy(output, hash, AUTH160_SIZE);
*output_len = AUTH160_SIZE;
return 0;
}

int generate_sighash_all(uint8_t *msg, size_t msg_len) {
int ret;
uint64_t len = 0;
Expand Down Expand Up @@ -953,8 +986,13 @@ int ckb_verify_identity(CkbIdentityType *id, uint8_t *sig, uint32_t sig_size,
if (sig == NULL || sig_size != SECP256K1_SIGNATURE_SIZE) {
return ERROR_IDENTITY_WRONG_ARGS;
}
return verify_sighash_all(id->id, sig, sig_size, validate_signature_btc,
convert_doge_message);
return verify_sighash_all(id->id, sig, sig_size, validate_signature_btc, convert_doge_message);
} else if (id->flags == IdentityFlagsSolana) {
if (sig == NULL || sig_size != (ED25519_SIGNATURE_SIZE + ED25519_PUBKEY_SIZE)) {
return ERROR_IDENTITY_WRONG_ARGS;
}
return verify_sighash_all(id->id, sig, sig_size, validate_signature_solana,
convert_copy);
} else if (id->flags == IdentityCkbMultisig) {
uint8_t msg[BLAKE2B_BLOCK_SIZE];
int ret = generate_sighash_all(msg, sizeof(msg));
Expand Down
1 change: 1 addition & 0 deletions deps/ed25519
Submodule ed25519 added at 34582a
5 changes: 5 additions & 0 deletions tests/omni_lock/omni_lock_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ int hex2bin(uint8_t* buf, const char* src) {
return length;
}

int ed25519_verify(const unsigned char* signature, const unsigned char* message,
size_t message_len, const unsigned char* public_key) {
return 0;
}

UTEST(pubkey_hash, pass) {
init_input(&g_setting);
g_setting.flags = IdentityFlagsCkb;
Expand Down
Loading

0 comments on commit 1a09a42

Please sign in to comment.