Skip to content

Commit a07b472

Browse files
committed
Use the hash of pubkey in arg
1 parent 608fd3b commit a07b472

File tree

8 files changed

+103
-43
lines changed

8 files changed

+103
-43
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ TARGET := riscv64-unknown-linux-gnu-
22
CC := $(TARGET)gcc
33
LD := $(TARGET)gcc
44

5-
PARAMS = sphincs-shake-256f
6-
THASH = robust
5+
PARAMS = sphincs-shake-128f
6+
THASH = simple
77

88
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
99
LDFLAGS := -fdata-sections -ffunction-sections

c/ckb-sphincsplus-lock.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,14 @@ enum SPHINCSPLUS_EXAMPLE_ERROR {
5454
ERROR_SPHINCSPLUS_SYSCALL,
5555
ERROR_SPHINCSPLUS_ENCODING,
5656
ERROR_SPHINCSPLUS_ARGS,
57+
ERROR_SPHINCSPLUS_PUBKEY,
5758
ERROR_SPHINCSPLUS_WITNESS,
5859
ERROR_SPHINCSPLUS_VERIFY,
5960
};
6061

6162
#ifdef CKB_VM
6263
// randombytes in sphincs+ depends on fcntl.h and unistd.h
63-
void randombytes(unsigned char *x, unsigned long long xlen) {
64-
ASSERT(false);
65-
}
64+
void randombytes(unsigned char *x, unsigned long long xlen) { ASSERT(false); }
6665
#endif // CKB_VM
6766

6867
static int extract_witness_lock(uint8_t *witness, uint64_t len,
@@ -226,28 +225,43 @@ int make_witness(WitnessArgsType *witness) {
226225
return 0;
227226
}
228227

229-
int get_sign(uint8_t *sign) {
228+
// Witness data structure
229+
// |-----Signature data-----|-----Public Key-----|
230+
int get_sign_info(uint8_t *sign, uint8_t *pubkey) {
230231
int err = CKB_SUCCESS;
231232
size_t sign_size = sphincs_plus_get_sign_size();
233+
size_t pubkey_size = sphincs_plus_get_pk_size();
234+
232235
WitnessArgsType witness_args;
233236

234237
uint8_t witness_data_source[MAX_WITNESS_SIZE] = {0};
238+
BytesOptType mol_lock;
239+
mol2_cursor_t mol_lock_bytes;
240+
size_t out_len;
241+
uint8_t buffer[sign_size + pubkey_size];
242+
235243
g_witness_data_source = witness_data_source;
236244
CHECK(make_witness(&witness_args));
237245

238-
BytesOptType mol_lock = witness_args.t->lock(&witness_args);
246+
mol_lock = witness_args.t->lock(&witness_args);
239247
CHECK2(!mol_lock.t->is_none(&mol_lock), ERROR_SPHINCSPLUS_WITNESS);
240248

241-
mol2_cursor_t mol_lock_bytes = mol_lock.t->unwrap(&mol_lock);
242-
size_t out_len = mol2_read_at(&mol_lock_bytes, sign, sign_size);
249+
mol_lock_bytes = mol_lock.t->unwrap(&mol_lock);
250+
CHECK2(mol_lock_bytes.size == sign_size + pubkey_size,
251+
ERROR_SPHINCSPLUS_WITNESS);
252+
253+
out_len = mol2_read_at(&mol_lock_bytes, buffer, sign_size + pubkey_size);
254+
CHECK2(out_len == sign_size + pubkey_size, ERROR_SPHINCSPLUS_WITNESS);
255+
256+
memcpy(sign, buffer, sign_size);
257+
memcpy(pubkey, buffer + sign_size, pubkey_size);
243258

244-
CHECK2(out_len == sign_size, ERROR_SPHINCSPLUS_WITNESS);
245259
exit:
246260
g_witness_data_source = NULL;
247261
return err;
248262
}
249263

250-
int get_public_key(uint8_t *pub_key) {
264+
int get_public_key_hash(uint8_t *pub_key) {
251265
int err = CKB_SUCCESS;
252266

253267
uint8_t script[SCRIPT_SIZE];
@@ -260,30 +274,39 @@ int get_public_key(uint8_t *pub_key) {
260274

261275
mol_seg_t args_seg = MolReader_Script_get_args(&script_seg);
262276
mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);
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);
277+
CHECK2((args_bytes_seg.size == BLAKE2B_BLOCK_SIZE), ERROR_SPHINCSPLUS_ARGS);
278+
memcpy(pub_key, args_bytes_seg.ptr, BLAKE2B_BLOCK_SIZE);
266279

267280
exit:
268281
return err;
269282
}
270283

271-
int main() {
272-
int err = CKB_SUCCESS;
284+
int check_pubkey(uint8_t *pubkey, uint8_t *pubkey_hash) {
285+
blake2b_state blake2b_ctx;
286+
blake2b_init(&blake2b_ctx, BLAKE2B_BLOCK_SIZE);
287+
blake2b_update(&blake2b_ctx, pubkey, sphincs_plus_get_pk_size());
288+
uint8_t msg[BLAKE2B_BLOCK_SIZE];
289+
blake2b_final(&blake2b_ctx, msg, sizeof(msg));
273290

274-
// signature data size depends on args data(hash type)
275-
uint8_t pubkey[sphincs_plus_get_pk_size()];
276-
err = get_public_key(pubkey);
277-
if (err) {
278-
return err;
291+
if (memcmp(pubkey_hash, msg, BLAKE2B_BLOCK_SIZE)) {
292+
return ERROR_SPHINCSPLUS_PUBKEY;
293+
} else {
294+
return 0;
279295
}
296+
}
280297

298+
int main() {
299+
int err = CKB_SUCCESS;
300+
301+
uint8_t pubkey_hash[BLAKE2B_BLOCK_SIZE];
281302
uint8_t message[BLAKE2B_BLOCK_SIZE];
282303
uint8_t sign[sphincs_plus_get_sign_size()];
283-
CHECK(generate_sighash_all(message, BLAKE2B_BLOCK_SIZE));
284-
285-
CHECK(get_sign(sign));
304+
uint8_t pubkey[sphincs_plus_get_pk_size()];
286305

306+
CHECK(get_public_key_hash(pubkey_hash));
307+
CHECK(generate_sighash_all(message, BLAKE2B_BLOCK_SIZE));
308+
CHECK(get_sign_info(sign, pubkey));
309+
CHECK(check_pubkey(pubkey, pubkey_hash));
287310
err = sphincs_plus_verify(sign, sphincs_plus_get_sign_size(), message,
288311
BLAKE2B_BLOCK_SIZE, pubkey,
289312
sphincs_plus_get_pk_size());

tests/sphincsplus/optimization/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ TARGET := riscv64-unknown-linux-gnu-
22
CC := $(TARGET)gcc
33
LD := $(TARGET)gcc
44

5-
PARAMS = sphincs-shake-256f
6-
THASH = robust
5+
PARAMS = sphincs-shake-128f
6+
THASH = simple
77

88
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 -g -DCKB_C_STDLIB_PRINTF
99
LDFLAGS := -fdata-sections -ffunction-sections

tests/sphincsplus/optimization/run-all-optimization.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ workdir=$(
66
cd $workdir
77

88
HASH_NAMES="shake sha2 haraka"
9-
HASH_SIZES="128 256"
10-
HASH_OPTIONS="s"
9+
HASH_SIZES="128 192 256"
10+
HASH_OPTIONS="s f"
1111
THASHS="simple robust"
1212
for HASH_NAME in ${HASH_NAMES[@]}; do
1313
for HASH_SIZE in ${HASH_SIZES[@]}; do

tests/sphincsplus_rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ version = "0.1.0"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[features]
9-
default = ["shake", "hash_256", "hash_options_f", "thashes_robust"]
9+
default = ["shake", "hash_128", "hash_options_f", "thashes_simple"]
1010
haraka = []
1111
sha2 = []
1212
shake = []

tests/sphincsplus_rust/run_example.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
if [ ! -n "$1" ] ;then
22
HASH_NAME="shake"
33
HASH_SIZE="128"
4-
THASH="robust"
5-
HASH_OPTION="s"
4+
THASH="simple"
5+
HASH_OPTION="f"
66
else
77
HASH_NAME=$1
88
HASH_SIZE=$2

tests/sphincsplus_rust/src/utils.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::dummy_data_loader::DummyDataLoader;
22
use super::sphincsplus::*;
3+
use ckb_hash::blake2b_256;
34
use ckb_types::core::{
45
cell::{CellMetaBuilder, ResolvedTransaction},
56
TransactionView,
@@ -25,6 +26,7 @@ lazy_static! {
2526
pub struct TestConfig {
2627
key: SphincsPlus,
2728
pub sign_error: bool,
29+
pub pubkey_hash_error: bool,
2830
pub pubkey_error: bool,
2931
pub message_error: bool,
3032
rng: ThreadRng,
@@ -36,6 +38,7 @@ impl TestConfig {
3638
Self {
3739
key: SphincsPlus::new(),
3840
sign_error: false,
41+
pubkey_hash_error: false,
3942
pubkey_error: false,
4043
message_error: false,
4144
rng: thread_rng(),
@@ -54,10 +57,10 @@ impl TestConfig {
5457
}
5558

5659
pub fn gen_tx(dummy: &mut DummyDataLoader, config: &mut TestConfig) -> TransactionView {
57-
let lock_args = Bytes::from(if config.pubkey_error {
58-
config.gen_rand_buf(config.key.pk.len())
60+
let lock_args = Bytes::from(if config.pubkey_hash_error {
61+
config.gen_rand_buf(32)
5962
} else {
60-
config.key.pk.to_vec()
63+
blake2b_256(&config.key.pk).to_vec()
6164
});
6265
gen_tx_with_grouped_args(dummy, vec![(lock_args, 1)], config)
6366
}
@@ -116,7 +119,7 @@ pub fn gen_tx_with_grouped_args(
116119
previous_out_point.clone(),
117120
(previous_output_cell.build(), Bytes::new()),
118121
);
119-
let witness_len = config.key.get_sign_len();
122+
let witness_len = config.key.get_sign_len() + config.key.get_pk_len();
120123
let random_extra_witness = config.gen_rand_buf(witness_len);
121124

122125
let witness_args = WitnessArgsBuilder::default()
@@ -149,7 +152,7 @@ pub fn sign_tx_by_input_group(
149152
config: &mut TestConfig,
150153
) -> TransactionView {
151154
let tx_hash = tx.hash();
152-
let witness_len = config.key.get_sign_len();
155+
let sign_info_len = config.key.get_sign_len() + config.key.get_pk_len();
153156

154157
let mut signed_witnesses: Vec<packed::Bytes> = tx
155158
.inputs()
@@ -165,7 +168,7 @@ pub fn sign_tx_by_input_group(
165168

166169
let zero_lock: Bytes = {
167170
let mut buf = Vec::new();
168-
buf.resize(witness_len, 0);
171+
buf.resize(sign_info_len, 0);
169172
buf.into()
170173
};
171174

@@ -190,11 +193,25 @@ pub fn sign_tx_by_input_group(
190193
config.rng.fill(&mut message);
191194
}
192195
let start = std::time::Instant::now();
193-
let sign = Bytes::from(if config.sign_error {
194-
config.gen_rand_buf(config.key.get_sign_len())
195-
} else {
196-
config.key.sign(&message)
197-
});
196+
let mut witness_buf = Vec::new();
197+
witness_buf.resize(sign_info_len, 0);
198+
199+
witness_buf[..config.key.get_sign_len()].copy_from_slice(
200+
&if config.sign_error {
201+
config.gen_rand_buf(config.key.get_sign_len())
202+
} else {
203+
config.key.sign(&message)
204+
},
205+
);
206+
207+
witness_buf[config.key.get_sign_len()..].copy_from_slice(
208+
&if config.pubkey_error {
209+
config.gen_rand_buf(config.key.get_pk_len())
210+
} else {
211+
config.key.pk.clone()
212+
},
213+
);
214+
198215
if config.print_time {
199216
println!(
200217
"sign time(native): {} us ({:.2?}s)",
@@ -203,7 +220,7 @@ pub fn sign_tx_by_input_group(
203220
);
204221
}
205222

206-
sign
223+
Bytes::from(witness_buf)
207224
};
208225

209226
witness

tests/sphincsplus_rust/tests/test_sphincsplus.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ fn test_err_sign() {
4646
}
4747
}
4848

49+
#[test]
50+
fn test_err_pubkey_hash() {
51+
let mut config = TestConfig::new();
52+
config.pubkey_hash_error = true;
53+
54+
let mut dummy = DummyDataLoader::new();
55+
56+
let tx = gen_tx(&mut dummy, &mut config);
57+
let tx = sign_tx(&mut dummy, tx, &mut config);
58+
59+
let resolved_tx = build_resolved_tx(&dummy, &tx);
60+
let mut verifier = TransactionScriptsVerifier::new(&resolved_tx, &dummy);
61+
62+
verifier.set_debug_printer(debug_printer);
63+
let verify_result = verifier.verify(MAX_CYCLES);
64+
if verify_result.is_ok() {
65+
panic!("pass verification");
66+
}
67+
}
68+
4969
#[test]
5070
fn test_err_pubkey() {
5171
let mut config = TestConfig::new();

0 commit comments

Comments
 (0)