commit acc805eed62cf84b45dd592f6a73a6845e292895
parent 9f5b275010fc04d453baa62c5a7ec214eef03593
Author: nolash <dev@holbrook.no>
Date: Thu, 16 Sep 2021 12:27:08 +0200
Add signature and recovery
Diffstat:
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);