Skip to content

Commit

Permalink
Merge pull request #15 from jjyr/try-sign-with-recoverable
Browse files Browse the repository at this point in the history
feat: use recoverable signature to reduce tx size
  • Loading branch information
xxuejie authored Jun 14, 2019
2 parents 76dc939 + f889685 commit bb76263
Show file tree
Hide file tree
Showing 9 changed files with 1,672 additions and 41 deletions.
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
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) {
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) {
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

0 comments on commit bb76263

Please sign in to comment.