libswarm-ng

C implementation of BMT hasher, Swarmhash and Single Owner Chunk for swarm
git clone git://git.defalsify.org/libswarm-ng.git
Log | Files | Refs | Submodules | README

commit acc805eed62cf84b45dd592f6a73a6845e292895
parent 9f5b275010fc04d453baa62c5a7ec214eef03593
Author: nolash <dev@holbrook.no>
Date:   Thu, 16 Sep 2021 12:27:08 +0200

Add signature and recovery

Diffstat:
MMakefile.dev | 5++---
MROADMAP | 2++
Msrc/keystore.c | 24++++++++++++++++++++++--
Msrc/keystore.h | 4+++-
Mtest/check_bmt.c | 3+--
Mtest/check_keystore.c | 42+++++++++++++++++++++++++++++++++++++++---
Mtest/common.c | 33+++++++++++++++++++++++++++++++++
Mtest/common.h | 8+++++++-
8 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/Makefile.dev b/Makefile.dev @@ -32,7 +32,7 @@ build_base: prep build_keccak build_secp256k1: prep build_keystore: prep build_keccak build_secp256k1 - $(CC) -c -o build/keystore.o $(CFLAGS) src/keystore.c + $(CC) -c -o build/keystore.o -I aux/secp256k1/include -L aux/secp256k1/.libs $(CFLAGS) src/keystore.c build_soc: prep build_keccak build_keystore @@ -51,13 +51,12 @@ build_check: build_base build_check_common build_check_keystore: build_base build_keystore build_check_common - $(CC) -I./src -o build/test/check_keystore build/swarm.o build/keystore.o test/check_keystore.c $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1 + $(CC) -I./src -o build/test/check_keystore build/swarm.o build/keystore.o test/check_keystore.c $(CFLAGS_CHECK) ./aux/secp256k1/.libs/libsecp256k1.a -lcheck -lkeccak-tiny -ltestcommon build_check_soc: build build_check_common build_check_keystore $(CC) -I./src -o build/test/check_soc build/swarm.o build/soc.o test/check_soc.c $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon - build_lib: build $(CC) -fPIC -rdynamic --shared -o build/lib/libswarm.so build/swarm.o build/swarmfile.o build/bmt.o build/endian.o $(AR) -rvs build/lib/libswarm.a build/swarmfile.o build/swarm.o build/bmt.o build/endian.o build/libkeccak-tiny-small.o diff --git a/ROADMAP b/ROADMAP @@ -4,3 +4,5 @@ * Single-owner chunks - 0.0.3 * Postage stamps +- 0.1.0 + * Proper autotools environment diff --git a/src/keystore.c b/src/keystore.c @@ -1,14 +1,34 @@ #include <string.h> #include "secp256k1.h" +#include "secp256k1_recovery.h" #include "keystore.h" -unsigned char* keystore_sign_digest(const keystore_t *keystore, unsigned char *z, const unsigned char *label, const unsigned char *digest, const size_t digest_sz) { +unsigned char* keystore_sign(const keystore_t *keystore, unsigned char *z, const int key_idx, const unsigned char *digest) { + int r; + int recover; + char recover_byte; + secp256k1_context *ecctx; + secp256k1_ecdsa_recoverable_signature signature; keystore_key_t key; - return 0; + ecctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + keystore_get(keystore, &key, key_idx); + r = secp256k1_ecdsa_sign_recoverable(ecctx, &signature, digest, key.pk, NULL, NULL); + if (r == 0) { + return NULL; + } + + r = secp256k1_ecdsa_recoverable_signature_serialize_compact(ecctx, z, &recover, &signature); + if (r == 0) { + return NULL; + } + *(z+64) = (unsigned char)recover; + + return z; } diff --git a/src/keystore.h b/src/keystore.h @@ -3,6 +3,8 @@ #define SWARM_PRIVATE_KEY_SIZE 32 #define SWARM_KEY_LABEL_SIZE 20 +#define SWARM_PUBLIC_KEY_SIZE 65 +#define SWARM_SIGNATURE_SIZE 65 typedef struct keystore_key { unsigned char pk[SWARM_PRIVATE_KEY_SIZE]; @@ -20,6 +22,6 @@ typedef struct keystore { keystore_key_t* keystore_put(keystore_t *keystore, const keystore_key_t *z, const char *passphrase, size_t passphrase_sz); keystore_key_t* keystore_get(const keystore_t *keystore, keystore_key_t *z, const int idx); -unsigned char* keystore_sign_digest(const keystore_t *keystore, unsigned char *z, const unsigned char *label, const unsigned char *digest, const size_t digest_sz); +unsigned char* keystore_sign(const keystore_t *keystore, unsigned char *z, const int key_idx, const unsigned char *digest); #endif // _LIBSWARM_SIGN_H diff --git a/test/check_bmt.c b/test/check_bmt.c @@ -23,7 +23,6 @@ END_TEST START_TEST(check_bmt_sum_foo) { bmt_t bmt_context; char *input = "foo"; - char *hash_of_foo = "2387e8e7d8a48c2a9339c97c1dc3461a9a7aa07e994c5cb8b38fd7c1b3e6ea48"; char v_chk[_SWARM_WORD_SIZE]; char input_length = 3; int r; @@ -32,7 +31,7 @@ START_TEST(check_bmt_sum_foo) { r = bmt_sum(&bmt_context); ck_assert_int_eq(r, 0); - hex2bin(hash_of_foo, v_chk); + hex2bin(HASH_OF_FOO, v_chk); ck_assert_mem_eq(bmt_context.buf, v_chk, _SWARM_WORD_SIZE); } END_TEST diff --git a/test/check_keystore.c b/test/check_keystore.c @@ -4,6 +4,7 @@ #include "keystore.h" #include "hex.h" #include "common.h" +#include "swarm.h" START_TEST(check_keystore_init) { @@ -17,7 +18,8 @@ START_TEST(check_keystore_getput) { keystore_t keystore; keystore_key_t key_one; keystore_key_t key_two; - keystore_key_t key_returned; + keystore_key_t key_out; + keystore_key_t *key_returned; struct block_generator bg; bg.v = 0; @@ -32,12 +34,45 @@ START_TEST(check_keystore_getput) { ck_assert_int_eq(keystore.keys_count, 2); - keystore_get(&keystore, &key_returned, 1); + key_returned = keystore_get(&keystore, &key_out, 1); + + ck_assert_mem_eq(&key_two, &key_out, sizeof(keystore_key_t)); + ck_assert_mem_eq(&key_two, key_returned, sizeof(keystore_key_t)); keystore_free(&keystore); - ck_assert_mem_eq(&key_two, &key_returned, sizeof(keystore_key_t)); +} +END_TEST + +START_TEST(check_keystore_sign) { + int r; + keystore_t keystore; + keystore_key_t key; + struct block_generator bg; + unsigned char signature[SWARM_SIGNATURE_SIZE]; + unsigned char *signature_returned; + unsigned char digest[SWARM_WORD_SIZE]; + unsigned char public_key[SWARM_PUBLIC_KEY_SIZE]; + unsigned char public_key_check[SWARM_PUBLIC_KEY_SIZE]; + + keystore_init(&keystore); + hex2bin(TEST_PRIVATE_KEY, key.pk); + keystore_put(&keystore, &key, NULL, 0); + + hex2bin(HASH_OF_FOO, digest); + + signature_returned = keystore_sign(&keystore, signature, 0, digest); + + ck_assert_mem_eq(signature, signature_returned, sizeof(keystore_key_t)); + + r = signature_recover_compact(signature, public_key, digest); + ck_assert_int_eq(r, 0); + + hex2bin(TEST_PUBLIC_KEY, public_key_check); + ck_assert_mem_eq(public_key, public_key_check, SWARM_PUBLIC_KEY_SIZE); + + keystore_free(&keystore); } END_TEST @@ -49,6 +84,7 @@ Suite * common_suite(void) { tc = tcase_create("core"); tcase_add_test(tc, check_keystore_init); tcase_add_test(tc, check_keystore_getput); + tcase_add_test(tc, check_keystore_sign); suite_add_tcase(s, tc); return s; diff --git a/test/common.c b/test/common.c @@ -1,6 +1,9 @@ #include <stdlib.h> #include <stddef.h> +#include "secp256k1.h" +#include "secp256k1_recovery.h" + #include "swarm.h" #include "keystore.h" #include "common.h" @@ -32,3 +35,33 @@ keystore_t* keystore_init(keystore_t *keystore) { void keystore_free(keystore_t *keystore) { free(keystore->keys); } + +int signature_recover_compact(const unsigned char *signature, unsigned char *public_key, unsigned char *digest) { + int r; + size_t public_key_sz; + + secp256k1_context *ecctx; + secp256k1_ecdsa_recoverable_signature signature_o; + secp256k1_pubkey public_key_o; + + + r = secp256k1_ecdsa_recoverable_signature_parse_compact(ecctx, &signature_o, signature, (int)*(signature+64)); + if (r == 0) { + return 1; + } + + r = secp256k1_ecdsa_recover(ecctx, &public_key_o, &signature_o, digest); + if (r == 0) { + return 1; + } + + public_key_sz = SWARM_PUBLIC_KEY_SIZE; + r = secp256k1_ec_pubkey_serialize(ecctx, public_key, &public_key_sz, &public_key_o, SECP256K1_EC_UNCOMPRESSED); + if (r == 0) { + return 1; + } + if (public_key_sz != SWARM_PUBLIC_KEY_SIZE) { + return 1; + } + return 0; +} diff --git a/test/common.h b/test/common.h @@ -1,5 +1,11 @@ #include <stddef.h> +#include "keystore.h" + +#define HASH_OF_FOO "2387e8e7d8a48c2a9339c97c1dc3461a9a7aa07e994c5cb8b38fd7c1b3e6ea48" +#define TEST_PRIVATE_KEY "5087503f0a9cc35b38665955eb830c63f778453dd11b8fa5bd04bc41fd2cc6d6" +#define TEST_PUBLIC_KEY "049f6bb6a7e3f5b7ee71756a891233d1415658f8712bac740282e083dc9240f5368bdb3b256a5bf40a8f7f9753414cb447ee3f796c5f30f7eb40a7f5018fc7f02e" +#define TEST_ADDRESS "eb3907ecad74a0013c259d5874ae7f22dcbcc95c" // mockdata struct block_generator { @@ -11,4 +17,4 @@ int block_generate(struct block_generator *bg, char *buf, size_t l); keystore_t* keystore_init(keystore_t *keystore); void keystore_free(keystore_t *keystore); - +int signature_recover_compact(const unsigned char *signature, unsigned char *public_key, unsigned char *digest);