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

Solana (phantom wallet) support #6

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
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 $@ [email protected]
$(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