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

feat: use recoverable signature to reduce tx size #15

Merged
merged 3 commits into from
Jun 14, 2019
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ dkms.conf
build/
c/flatbuffers_common_reader.h
c/protocol_reader.h

tests/target
tests/tmp
26 changes: 26 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
language: rust
rust: 1.34.2
dist: xenial
sudo: true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need sudo here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, I just copy the .travis.yml template from CKB

cache:
cargo: true
timeout: 1024

git:
depth: 2

env:
global:
- RUST_BACKTRACE=full

before_install:
- cargo sweep --version || cargo install --git https://github.com/holmgr/cargo-sweep --rev 4770deda37a2203c783e301b8c0c895964e8971e
- cargo sweep -s

script: make ci

before_cache:
- rm -rf ./target/release
- rm -rf ./target/debug/incremental/
- cargo sweep -f

8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ build/secp256k1_blake160_sighash_all: c/secp256k1_blake160_sighash_all.c c/proto
$(SECP256K1_LIB):
cd deps/secp256k1 && \
./autogen.sh && \
CC=$(CC) LD=$(LD) ./configure --with-bignum=no --enable-ecmult-static-precomputation --enable-endomorphism --host=$(TARGET) && \
CC=$(CC) LD=$(LD) ./configure --with-bignum=no --enable-ecmult-static-precomputation --enable-endomorphism --enable-module-recovery --host=$(TARGET) && \
make libsecp256k1.la

c/protocol_reader.h: c/protocol.fbs $(FLATCC)
Expand All @@ -24,6 +24,12 @@ c/protocol_reader.h: c/protocol.fbs $(FLATCC)
$(FLATCC):
cd deps/flatcc && scripts/initbuild.sh make && scripts/build.sh

ci:
docker run --rm -v `pwd`:/code xxuejie/riscv-gnu-toolchain-rv64imac:xenial-20190606 bash -c "cd /code && make"
mkdir -p tests/tmp
cp build/secp256k1_blake160_sighash_all tests/tmp/
cd tests && cargo test

clean:
rm -rf build/secp256k1_blake160_sighash_all
cd deps/flatcc && scripts/cleanall.sh
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# ckb-contracts
[![Build Status](https://travis-ci.com/nervosnetwork/ckb-system-scripts.svg?branch=master)](https://travis-ci.com/nervosnetwork/ckb-system-scripts)

CKB's official smart contracts. Those contracts will be included in system cells in genesis blocks
74 changes: 34 additions & 40 deletions c/secp256k1_blake160_sighash_all.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
#define ERROR_SYSCALL -4
#define ERROR_SECP_ABORT -5
#define ERROR_SECP_INITIALIZE -6
#define ERROR_SECP_PARSE_PUBKEY -7
#define ERROR_SECP_RECOVER_PUBKEY -7
#define ERROR_SECP_PARSE_SIGNATURE -8
#define ERROR_SECP_VERIFICATION -9
#define ERROR_SECP_SERIALIZE_PUBKEY -9
#define ERROR_BUFFER_NOT_ENOUGH -10
#define ERROR_ENCODING -11

#define BLAKE2B_BLOCK_SIZE 32
#define BLAKE160_SIZE 20
#define PUBKEY_SIZE 33
#define TEMP_SIZE 1024
#define RECID_INDEX 64
/* 32 KB */
#define WITNESS_SIZE 32768

Expand Down Expand Up @@ -71,13 +72,13 @@ static int extract_bytes(ns(Bytes_table_t) bytes, unsigned char *buffer, volatil
* pubkey in lock script.
*
* Witness:
* 2. pubkey, real pubkey used to identify token owner
* 3. signature, signature used to present ownership
* 4. signature size, in little endian 64 bit unsigned integer
* 1. signature, signature used to present ownership
* 2. signature size, in little endian 64 bit unsigned integer
*/
int main(int argc, char* argv[])
{
int ret;
int recid;
size_t index = 0;
uint64_t signature_size = 0;
volatile uint64_t len = 0;
Expand Down Expand Up @@ -131,52 +132,28 @@ int main(int argc, char* argv[])
return ERROR_ENCODING;
}
args = ns(Witness_data(witness_table));
if (ns(Bytes_vec_len(args)) < 2) {
if (ns(Bytes_vec_len(args)) < 1) {
return ERROR_WRONG_NUMBER_OF_ARGUMENTS;
}

/* Check pubkey hash */
len = TEMP_SIZE;
ret = extract_bytes(ns(Bytes_vec_at(args, 0)), temp, &len);
if (ret != CKB_SUCCESS) {
return ERROR_ENCODING;
}
blake2b_state blake2b_ctx;
blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE);
blake2b_update(&blake2b_ctx, temp, len);
blake2b_final(&blake2b_ctx, temp, BLAKE2B_BLOCK_SIZE);

if (memcmp(argv[1], temp, BLAKE160_SIZE) != 0) {
return ERROR_PUBKEY_BLAKE160_HASH;
}

/* load pubkey */
len = TEMP_SIZE;
ret = extract_bytes(ns(Bytes_vec_at(args, 0)), temp, &len);
if (ret != CKB_SUCCESS) {
return ERROR_ENCODING;
}

secp256k1_pubkey pubkey;
if (secp256k1_ec_pubkey_parse(&context, &pubkey, temp, len) == 0) {
return ERROR_SECP_PARSE_PUBKEY;
}

/* Load signature */
len = TEMP_SIZE;
ret = extract_bytes(ns(Bytes_vec_at(args, 1)), temp, &len);
ret = extract_bytes(ns(Bytes_vec_at(args, 0)), temp, &len);
if (ret != CKB_SUCCESS) {
return ERROR_ENCODING;
}

secp256k1_ecdsa_signature signature;
if (secp256k1_ecdsa_signature_parse_der(&context, &signature, temp, len) == 0) {
/* The 65th byte is recid according to contract spec.*/
recid = temp[RECID_INDEX];
/* Recover pubkey */
secp256k1_ecdsa_recoverable_signature signature;
if (secp256k1_ecdsa_recoverable_signature_parse_compact(&context, &signature, temp, recid) == 0) {
doitian marked this conversation as resolved.
Show resolved Hide resolved
return ERROR_SECP_PARSE_SIGNATURE;
}

blake2b_state blake2b_ctx;
blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE);
blake2b_update(&blake2b_ctx, tx_hash, BLAKE2B_BLOCK_SIZE);
for (size_t i = 2; i < ns(Bytes_vec_len(args)); i++) {
for (size_t i = 1; i < ns(Bytes_vec_len(args)); i++) {
len = TEMP_SIZE;
ret = extract_bytes(ns(Bytes_vec_at(args, i)), temp, &len);
if (ret != CKB_SUCCESS) {
Expand All @@ -186,8 +163,25 @@ int main(int argc, char* argv[])
}
blake2b_final(&blake2b_ctx, temp, BLAKE2B_BLOCK_SIZE);

if (secp256k1_ecdsa_verify(&context, &signature, temp, &pubkey) != 1) {
return ERROR_SECP_VERIFICATION;
secp256k1_pubkey pubkey;

if (secp256k1_ecdsa_recover(&context, &pubkey, &signature, temp) != 1) {
xxuejie marked this conversation as resolved.
Show resolved Hide resolved
return ERROR_SECP_RECOVER_PUBKEY;
}

/* Check pubkey hash */
size_t pubkey_size = PUBKEY_SIZE;
if (secp256k1_ec_pubkey_serialize(&context, temp, &pubkey_size, &pubkey, SECP256K1_EC_COMPRESSED) != 1 ) {
return ERROR_SECP_SERIALIZE_PUBKEY;
}

len = PUBKEY_SIZE;
blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE);
blake2b_update(&blake2b_ctx, temp, len);
blake2b_final(&blake2b_ctx, temp, BLAKE2B_BLOCK_SIZE);

if (memcmp(argv[1], temp, BLAKE160_SIZE) != 0) {
return ERROR_PUBKEY_BLAKE160_HASH;
}

index += 1;
Expand Down
Loading