Skip to content

Commit 9a614e5

Browse files
authored
Merge pull request #3 from joii2020/develop_1
Support SPHINCS+
2 parents af64535 + b259ba9 commit 9a614e5

File tree

169 files changed

+60204
-68266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+60204
-68266
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ jobs:
1212
- name: Update submodules
1313
run: git submodule update --init
1414
- name: Run sphincs+ tests
15-
run: ./tests/sphincsplus/run.sh
16-
- name: Build contract
17-
run: make all-via-docker
15+
run: ./tests/sphincsplus/all_run.sh
1816
- name: Run sphincs+ rust tests
19-
run: cd tests/sphincsplus_rust && cargo test
17+
run: ./tests/sphincsplus_rust/run_rust.sh

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "deps/ckb-c-stdlib"]
22
path = deps/ckb-c-stdlib
33
url = https://github.com/nervosnetwork/ckb-c-stdlib.git
4+
[submodule "deps/sphincsplus"]
5+
path = deps/sphincsplus
6+
url = https://github.com/sphincs/sphincsplus.git

Makefile

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,84 @@
1-
TARGET :=
21
TARGET := riscv64-unknown-linux-gnu-
32
CC := $(TARGET)gcc
43
LD := $(TARGET)gcc
54

5+
PARAMS = sphincs-shake-256f
6+
THASH = robust
7+
68
CFLAGS := -fPIC -O3 -fno-builtin-printf -fno-builtin-memcmp -nostdinc -nostartfiles -fvisibility=hidden -fdata-sections -ffunction-sections -nostdlib -Wno-nonnull-compare -DCKB_VM -DCKB_DECLARATION_ONLY
79
LDFLAGS := -fdata-sections -ffunction-sections
810

9-
CFLAGS := $(CFLAGS) -Wall -Werror -Wno-nonnull -Wno-unused-function
11+
# Using a new version of gcc will have a warning of ckb-c-stdlib
12+
CFLAGS := $(CFLAGS) -w
13+
# CFLAGS := $(CFLAGS) -Wall -Werror -Wno-nonnull -Wno-unused-function
1014
LDFLAGS := $(LDFLAGS) -Wl,-static -Wl,--gc-sections
1115

1216
CFLAGS := $(CFLAGS) -I c -I deps/ckb-c-stdlib/libc -I deps/ckb-c-stdlib -I deps/ckb-c-stdlib/molecule
13-
CFLAGS := $(CFLAGS) -I c/ref
17+
CFLAGS := $(CFLAGS) -I deps/sphincsplus/ref -DPARAMS=$(PARAMS)
1418

15-
SOURCES_DIR = ref
19+
SPHINCS_PLUS_DIR = deps/sphincsplus/ref/
1620

1721
SOURCES = \
18-
c/$(SOURCES_DIR)/params.c \
19-
c/$(SOURCES_DIR)/address.c \
20-
c/$(SOURCES_DIR)/merkle.c \
21-
c/$(SOURCES_DIR)/wots.c \
22-
c/$(SOURCES_DIR)/wotsx1.c \
23-
c/$(SOURCES_DIR)/utils.c \
24-
c/$(SOURCES_DIR)/utilsx1.c \
25-
c/$(SOURCES_DIR)/fors.c \
26-
c/$(SOURCES_DIR)/sign.c \
27-
c/$(SOURCES_DIR)/randombytes.c \
22+
$(SPHINCS_PLUS_DIR)address.c \
23+
$(SPHINCS_PLUS_DIR)merkle.c \
24+
$(SPHINCS_PLUS_DIR)wots.c \
25+
$(SPHINCS_PLUS_DIR)wotsx1.c \
26+
$(SPHINCS_PLUS_DIR)utils.c \
27+
$(SPHINCS_PLUS_DIR)utilsx1.c \
28+
$(SPHINCS_PLUS_DIR)fors.c \
29+
$(SPHINCS_PLUS_DIR)sign.c \
2830
c/ckb-sphincsplus.c
2931

3032
HEADERS = \
31-
c/$(SOURCES_DIR)/params.h \
32-
c/$(SOURCES_DIR)/address.h \
33-
c/$(SOURCES_DIR)/merkle.h \
34-
c/$(SOURCES_DIR)/wots.h \
35-
c/$(SOURCES_DIR)/wotsx1.h \
36-
c/$(SOURCES_DIR)/utils.h \
37-
c/$(SOURCES_DIR)/utilsx1.h \
38-
c/$(SOURCES_DIR)/fors.h \
39-
c/$(SOURCES_DIR)/api.h \
40-
c/$(SOURCES_DIR)/hash.h \
41-
c/$(SOURCES_DIR)/thash.h \
42-
c/$(SOURCES_DIR)/randombytes.h \
33+
$(SPHINCS_PLUS_DIR)params.h \
34+
$(SPHINCS_PLUS_DIR)address.h \
35+
$(SPHINCS_PLUS_DIR)merkle.h \
36+
$(SPHINCS_PLUS_DIR)wots.h \
37+
$(SPHINCS_PLUS_DIR)wotsx1.h \
38+
$(SPHINCS_PLUS_DIR)utils.h \
39+
$(SPHINCS_PLUS_DIR)utilsx1.h \
40+
$(SPHINCS_PLUS_DIR)fors.h \
41+
$(SPHINCS_PLUS_DIR)api.h \
42+
$(SPHINCS_PLUS_DIR)hash.h \
43+
$(SPHINCS_PLUS_DIR)thash.h \
44+
$(SPHINCS_PLUS_DIR)randombytes.h \
4345
c/ckb-sphincsplus.h
4446

45-
# shake
46-
SOURCES += \
47-
c/$(SOURCES_DIR)/fips202.c \
48-
c/$(SOURCES_DIR)/hash_shake.c \
49-
c/$(SOURCES_DIR)/thash_shake_robust.c\
50-
c/$(SOURCES_DIR)/thash_shake_simple.c
51-
HEADERS += \
52-
c/$(SOURCES_DIR)/fips202.h
53-
54-
# sha2
55-
SOURCES += \
56-
c/$(SOURCES_DIR)/sha2.c \
57-
c/$(SOURCES_DIR)/hash_sha2.c \
58-
c/$(SOURCES_DIR)/thash_sha2_robust.c \
59-
c/$(SOURCES_DIR)/thash_sha2_simple.c
60-
HEADERS += \
61-
c/$(SOURCES_DIR)/sha2.h
47+
ifneq (,$(findstring shake,$(PARAMS)))
48+
SOURCES += \
49+
$(SPHINCS_PLUS_DIR)fips202.c \
50+
$(SPHINCS_PLUS_DIR)hash_shake.c \
51+
$(SPHINCS_PLUS_DIR)thash_shake_$(THASH).c
52+
HEADERS += $(SPHINCS_PLUS_DIR)fips202.h
53+
endif
54+
ifneq (,$(findstring haraka,$(PARAMS)))
55+
SOURCES += \
56+
$(SPHINCS_PLUS_DIR)haraka.c \
57+
$(SPHINCS_PLUS_DIR)hash_haraka.c \
58+
$(SPHINCS_PLUS_DIR)thash_haraka_$(THASH).c
59+
HEADERS += $(SPHINCS_PLUS_DIR)haraka.h
60+
endif
61+
ifneq (,$(findstring sha2,$(PARAMS)))
62+
SOURCES += \
63+
$(SPHINCS_PLUS_DIR)sha2.c \
64+
$(SPHINCS_PLUS_DIR)hash_sha2.c \
65+
$(SPHINCS_PLUS_DIR)thash_sha2_$(THASH).c
66+
HEADERS += $(SPHINCS_PLUS_DIR)sha2.h
67+
endif
6268

63-
# haraka
64-
SOURCES += \
65-
c/$(SOURCES_DIR)/haraka.c \
66-
c/$(SOURCES_DIR)/hash_haraka.c \
67-
c/$(SOURCES_DIR)/thash_haraka_robust.c \
68-
c/$(SOURCES_DIR)/thash_haraka_simple.c
69-
HEADERS += \
70-
c/$(SOURCES_DIR)/haraka.h
69+
CFLAGS := $(CFLAGS) -g -DCKB_C_STDLIB_PRINTF
7170

72-
# CFLAGS := $(CFLAGS) -g -DCKB_C_STDLIB_PRINTF
73-
74-
# docker pull nervos/ckb-riscv-gnu-toolchain:gnu-bionic-20191012
75-
BUILDER_DOCKER := nervos/ckb-riscv-gnu-toolchain@sha256:aae8a3f79705f67d505d1f1d5ddc694a4fd537ed1c7e9622420a470d59ba2ec3
71+
# docker pull nervos/ckb-riscv-gnu-toolchain:gnu-jammy-20230214
72+
BUILDER_DOCKER := nervos/ckb-riscv-gnu-toolchain@sha256:7601a814be2595ad471288fefc176356b31101837a514ddb0fc93b11c1cf5135
7673

7774
all: build/sphincsplus_lock
7875

7976
all-via-docker:
8077
docker run --rm -v `pwd`:/code ${BUILDER_DOCKER} bash -c "cd /code && make"
8178

79+
build/convert_asm: c/ref/fips202_asm.S
80+
riscv-naive-assembler -i c/ref/fips202_asm.S > c/ref/fips202_asm_bin.S
81+
8282
build/sphincsplus_lock: c/ckb-sphincsplus-lock.c $(SOURCES) $(HEADERS)
8383
mkdir -p build
8484
$(CC) $(CFLAGS) -o $@ $(SOURCES) $<

c/ckb-sphincsplus-lock.c

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include "api.h"
1313
#include "ckb-sphincsplus.h"
14-
#include "ckb_vm_dbg.h"
1514

1615
#ifndef MOL2_EXIT
1716
#define MOL2_EXIT ckb_exit
@@ -23,8 +22,6 @@
2322
#define BLAKE2B_BLOCK_SIZE 32
2423
#define ONE_BATCH_SIZE 1024 * 64
2524

26-
#define SPHINCSPLUS_PUBKEY_MAX_SIZE 1024
27-
2825
#define SCRIPT_SIZE 1024 * 64 // 32k
2926

3027
#undef ASSERT
@@ -59,9 +56,15 @@ enum SPHINCSPLUS_EXAMPLE_ERROR {
5956
ERROR_SPHINCSPLUS_ARGS,
6057
ERROR_SPHINCSPLUS_WITNESS,
6158
ERROR_SPHINCSPLUS_VERIFY,
62-
ERROR_SPHINCSPLUS_HASH_TYPE,
6359
};
6460

61+
#ifdef CKB_VM
62+
// randombytes in sphincs+ depends on fcntl.h and unistd.h
63+
void randombytes(unsigned char *x, unsigned long long xlen) {
64+
ASSERT(false);
65+
}
66+
#endif // CKB_VM
67+
6568
static int extract_witness_lock(uint8_t *witness, uint64_t len,
6669
mol_seg_t *lock_bytes_seg) {
6770
if (len < 20) {
@@ -196,9 +199,6 @@ int make_witness(WitnessArgsType *witness) {
196199
uint64_t witness_len = 0;
197200
size_t source = CKB_SOURCE_GROUP_INPUT;
198201
err = ckb_load_witness(NULL, &witness_len, 0, 0, source);
199-
// when witness is missing, empty or not accessible, make it zero length.
200-
// don't fail, because owner lock without omni doesn't require witness.
201-
// when it's zero length, any further actions on witness will fail.
202202
if (err != 0) {
203203
witness_len = 0;
204204
}
@@ -226,9 +226,9 @@ int make_witness(WitnessArgsType *witness) {
226226
return 0;
227227
}
228228

229-
int get_sign(uint8_t *sign, crypto_context *cctx) {
229+
int get_sign(uint8_t *sign) {
230230
int err = CKB_SUCCESS;
231-
size_t sign_size = sphincs_plus_get_sign_size(cctx);
231+
size_t sign_size = sphincs_plus_get_sign_size();
232232
WitnessArgsType witness_args;
233233

234234
uint8_t witness_data_source[MAX_WITNESS_SIZE] = {0};
@@ -247,12 +247,7 @@ int get_sign(uint8_t *sign, crypto_context *cctx) {
247247
return err;
248248
}
249249

250-
// Args data:
251-
// |---------------------|--------------|
252-
// | hash type 4 bytes | public key |
253-
//
254-
// note: different hash types have different public key lengths
255-
int get_public_key(uint8_t *pub_key, crypto_context *cctx) {
250+
int get_public_key(uint8_t *pub_key) {
256251
int err = CKB_SUCCESS;
257252

258253
uint8_t script[SCRIPT_SIZE];
@@ -265,17 +260,9 @@ int get_public_key(uint8_t *pub_key, crypto_context *cctx) {
265260

266261
mol_seg_t args_seg = MolReader_Script_get_args(&script_seg);
267262
mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);
268-
269-
CHECK2((args_bytes_seg.size > sizeof(uint32_t)), ERROR_SPHINCSPLUS_ARGS);
270-
uint32_t hash_type = 0;
271-
memcpy(&hash_type, args_bytes_seg.ptr, sizeof(uint32_t));
272-
CHECK2(!sphincs_plus_init_context(hash_type, cctx),
273-
ERROR_SPHINCSPLUS_HASH_TYPE);
274-
275-
size_t pubkey_size = sphincs_plus_get_pk_size(cctx);
276-
CHECK2((args_bytes_seg.size == sizeof(uint32_t)) + pubkey_size,
277-
ERROR_SPHINCSPLUS_ARGS);
278-
memcpy(pub_key, args_bytes_seg.ptr + sizeof(uint32_t), pubkey_size);
263+
size_t pubkey_size = sphincs_plus_get_pk_size();
264+
CHECK2((args_bytes_seg.size == pubkey_size), ERROR_SPHINCSPLUS_ARGS);
265+
memcpy(pub_key, args_bytes_seg.ptr, pubkey_size);
279266

280267
exit:
281268
return err;
@@ -285,21 +272,21 @@ int main() {
285272
int err = CKB_SUCCESS;
286273

287274
// signature data size depends on args data(hash type)
288-
uint8_t pubkey[SPHINCSPLUS_PUBKEY_MAX_SIZE];
289-
crypto_context cctx = {0};
290-
err = get_public_key(pubkey, &cctx);
275+
uint8_t pubkey[sphincs_plus_get_pk_size()];
276+
err = get_public_key(pubkey);
291277
if (err) {
292278
return err;
293279
}
294280

295281
uint8_t message[BLAKE2B_BLOCK_SIZE];
296-
uint8_t sign[sphincs_plus_get_sign_size(&cctx)];
282+
uint8_t sign[sphincs_plus_get_sign_size()];
297283
CHECK(generate_sighash_all(message, BLAKE2B_BLOCK_SIZE));
298284

299-
CHECK(get_sign(sign, &cctx));
300-
err = sphincs_plus_verify(&cctx, sign, sphincs_plus_get_sign_size(&cctx),
301-
message, BLAKE2B_BLOCK_SIZE, pubkey,
302-
sphincs_plus_get_pk_size(&cctx));
285+
CHECK(get_sign(sign));
286+
287+
err = sphincs_plus_verify(sign, sphincs_plus_get_sign_size(), message,
288+
BLAKE2B_BLOCK_SIZE, pubkey,
289+
sphincs_plus_get_pk_size());
303290
CHECK2(err == 0, ERROR_SPHINCSPLUS_VERIFY);
304291

305292
exit:

c/ckb-sphincsplus.c

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,67 +26,45 @@ enum SphincsPlusError {
2626

2727
#include <stdlib.h>
2828

29-
crypto_context *sphincs_plus_new_context(crypto_type type) {
30-
crypto_context *cctx = (crypto_context *)malloc(sizeof(crypto_context));
31-
int err = crypto_init_context(type, cctx);
32-
ASSERT(err == 0);
33-
return cctx;
34-
}
35-
36-
void sphincs_plus_del_context(crypto_context *cctx) { free(cctx); }
37-
3829
#endif // CKB_VM
3930

40-
int sphincs_plus_init_context(crypto_type type, crypto_context *cctx) {
41-
memset(cctx, 0, sizeof(crypto_context));
42-
return crypto_init_context(type, cctx);
43-
}
44-
45-
uint32_t sphincs_plus_get_pk_size(crypto_context *cctx) {
46-
return cctx->spx_pk_bytes;
47-
}
31+
uint32_t sphincs_plus_get_pk_size() { return SPX_PK_BYTES; }
4832

49-
uint32_t sphincs_plus_get_sk_size(crypto_context *cctx) {
50-
return cctx->spx_sk_bytes;
51-
}
33+
uint32_t sphincs_plus_get_sk_size() { return SPX_SK_BYTES; }
5234

53-
uint32_t sphincs_plus_get_sign_size(crypto_context *cctx) {
54-
return cctx->spx_bytes + SPX_MLEN;
55-
}
35+
uint32_t sphincs_plus_get_sign_size() { return SPX_BYTES + SPX_MLEN; }
5636

5737
#ifndef CKB_VM
5838

59-
int sphincs_plus_generate_keypair(crypto_context *cctx, uint8_t *pk,
60-
uint8_t *sk) {
61-
return crypto_sign_keypair(cctx, pk, sk);
39+
int sphincs_plus_generate_keypair(uint8_t *pk, uint8_t *sk) {
40+
return crypto_sign_keypair(pk, sk);
6241
}
6342

64-
int sphincs_plus_sign(crypto_context *cctx, uint8_t *message, uint8_t *sk,
65-
uint8_t *out_sign) {
66-
unsigned long long out_sign_len = sphincs_plus_get_sign_size(cctx);
67-
int ret = crypto_sign(cctx, out_sign, (unsigned long long *)&out_sign_len,
68-
message, SPX_MLEN, sk);
69-
if ((uint32_t)out_sign_len != sphincs_plus_get_sign_size(cctx)) {
43+
int sphincs_plus_sign(uint8_t *message, uint8_t *sk, uint8_t *out_sign) {
44+
unsigned long long out_sign_len = sphincs_plus_get_sign_size();
45+
int ret = crypto_sign(out_sign, (unsigned long long *)&out_sign_len, message,
46+
SPX_MLEN, sk);
47+
if ((uint32_t)out_sign_len != sphincs_plus_get_sign_size()) {
7048
return 1;
7149
}
7250
return ret;
7351
}
7452

7553
#endif // CKB_VM
7654

77-
int sphincs_plus_verify(crypto_context *cctx, uint8_t *sign, uint32_t sign_size,
78-
uint8_t *message, uint32_t message_size,
79-
uint8_t *pubkey, uint32_t pubkey_size) {
80-
size_t sign_len = sphincs_plus_get_sign_size(cctx);
55+
int sphincs_plus_verify(uint8_t *sign, uint32_t sign_size, uint8_t *message,
56+
uint32_t message_size, uint8_t *pubkey,
57+
uint32_t pubkey_size) {
58+
size_t sign_len = sphincs_plus_get_sign_size();
8159

8260
if (sign_size != sign_len || message_size != SPX_MLEN ||
83-
pubkey_size != sphincs_plus_get_pk_size(cctx)) {
61+
pubkey_size != sphincs_plus_get_pk_size()) {
8462
return SphincsPlusError_Params;
8563
}
8664
unsigned char mout[SPX_BYTES + SPX_MLEN];
8765
unsigned long long mlen = 0;
8866

89-
int err = crypto_sign_open(cctx, mout, &mlen, sign, sign_len, pubkey);
67+
int err = crypto_sign_open(mout, &mlen, sign, sign_len, pubkey);
9068
if (err != 0) {
9169
return SphincsPlusError_Verify;
9270
}

0 commit comments

Comments
 (0)