commit 98fd2307066fa973bf2aad98ff60f7e8dce6714a
parent 8540fff2831fcabede856bf7f8b45c2cbcd807fe
Author: nolash <dev@holbrook.no>
Date: Thu, 16 Sep 2021 23:11:22 +0200
Add generate address and publickey on key struct
Diffstat:
13 files changed, 290 insertions(+), 38 deletions(-)
diff --git a/Makefile.dev b/Makefile.dev
@@ -50,6 +50,7 @@ build_check_common:
build_check: build_base build_check_common
$(CC) -I./src -o build/test/check_bmt build/swarm.o build/bmt.o build/endian.o build/swarmfile.o test/check_bmt.c $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1
$(CC) -I./src -o build/test/check_file build/swarm.o build/bmt.o build/endian.o build/swarmfile.o test/check_file.c $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1
+ $(CC) -I./src -o build/test/check_chunk build/chunk.o build/swarm.o build/bmt.o build/endian.o build/swarmfile.o test/check_chunk.c $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1
build_check_keystore: build_base build_keystore build_check_common
@@ -57,7 +58,7 @@ build_check_keystore: build_base build_keystore build_check_common
build_check_soc: build build_check_common build_soc
- $(CC) -I./src -o build/test/check_soc build/chunk.o build/swarm.o build/soc.o test/check_soc.c -L./aux/secp256k1/.libs $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1
+ $(CC) -I./src -o build/test/check_soc build/keystore.o build/endian.o build/bmt.o build/chunk.o build/swarm.o build/soc.o test/check_soc.c -L./aux/secp256k1/.libs $(CFLAGS_CHECK) -lcheck -lkeccak-tiny -ltestcommon -lsecp256k1
build_lib: build
$(CC) -fPIC -rdynamic --shared -o build/lib/libswarm.so build/swarm.o build/swarmfile.o build/bmt.o build/endian.o
@@ -66,8 +67,9 @@ build_lib: build
.PHONY: test clean
check_base: build build_check
- LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_bmt
- LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_file
+ #LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_bmt
+ LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_chunk
+ #LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_file
check_keystore: build build_check_keystore
LD_LIBRARY_PATH=./build/:./build/test CK_FORK=no build/test/check_keystore
diff --git a/src/chunk.c b/src/chunk.c
@@ -1,7 +1,8 @@
-#include <string.h>
#include <stddef.h>
+#include "string.h"
#include "chunk.h"
+#include "bmt.h"
unsigned char* chunk_serialize(const swarm_chunk_t *chunk, unsigned char *z, size_t *sz) {
int crsr;
@@ -16,3 +17,21 @@ unsigned char* chunk_serialize(const swarm_chunk_t *chunk, unsigned char *z, siz
return z;
}
+
+int chunk_verify(const swarm_chunk_t *chunk) {
+ int r;
+ bmt_t bctx;
+
+ bmt_init(&bctx, chunk->payload, chunk->payload_sz, (bmt_spansize_t)*chunk->span);
+ r = bmt_sum(&bctx);
+ if (r != 0) {
+ return 1;
+ }
+
+ r = memcmp(chunk->hash, bctx.buf, SWARM_WORD_SIZE);
+ if (r != 0) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/chunk.h b/src/chunk.h
@@ -12,5 +12,6 @@ typedef struct swarm_chunk {
} swarm_chunk_t;
unsigned char* chunk_serialize(const swarm_chunk_t *chunk, unsigned char *z, size_t *sz);
+int chunk_verify(const swarm_chunk_t *chunk);
#endif // _LIBSWARM_CHUNK_H
diff --git a/src/def.h b/src/def.h
@@ -6,6 +6,7 @@
#define SWARM_PRIVATE_KEY_SIZE 32
#define SWARM_KEY_LABEL_SIZE 20
#define SWARM_PUBLIC_KEY_SIZE 65
+#define SWARM_PUBLIC_KEY_COMPRESSED_SIZE 33
#define SWARM_SIGNATURE_SIZE 65
#define SWARM_KECCAK_RATE 200-64
diff --git a/src/keystore.c b/src/keystore.c
@@ -50,3 +50,93 @@ keystore_key_t* keystore_get(const keystore_t *keystore, keystore_key_t *z, cons
memcpy(z, keystore->keys+idx, sizeof(keystore_key_t));
return z;
}
+
+
+int key_from_public(keystore_key_t *key) {
+ int r;
+ secp256k1_context *ecctx;
+ unsigned char digest[SWARM_WORD_SIZE];
+
+ r = keccak_hash_btc(digest, SWARM_WORD_SIZE, key->pubk + 1, SWARM_PUBLIC_KEY_SIZE - 1);
+ if (r < 0) {
+ return 1;
+ }
+
+ memcpy(key->label, digest + SWARM_WORD_SIZE - SWARM_ADDRESS_SIZE, SWARM_ADDRESS_SIZE);
+
+ return 0;
+}
+
+
+int key_from_private(keystore_key_t *key) {
+ int r;
+ secp256k1_context *ecctx;
+ secp256k1_pubkey public_key_o;
+ size_t public_key_sz;
+ unsigned char *p;
+
+ ecctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
+
+ r = secp256k1_ec_pubkey_create(ecctx, &public_key_o, key->pk);
+ if (r == 0) {
+ return 1;
+ }
+
+ public_key_sz = SWARM_PUBLIC_KEY_SIZE;
+ r = secp256k1_ec_pubkey_serialize(ecctx, key->pubk, &public_key_sz, &public_key_o, SECP256K1_EC_UNCOMPRESSED);
+ if (r == 0) {
+ return 1;
+ }
+
+ r = key_from_public(key);
+ if (r != 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int key_recover_compact(const unsigned char *signature, unsigned char *public_key, const unsigned char *digest) {
+ int r;
+ size_t public_key_sz;
+
+ secp256k1_context *ecctx;
+ secp256k1_ecdsa_recoverable_signature signature_o;
+ secp256k1_pubkey public_key_o;
+
+ ecctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
+
+ 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;
+}
+
+
+keystore_key_t* key_recover(keystore_key_t *z, const unsigned char *signature, const unsigned char *digest) {
+ int r;
+
+ r = key_recover_compact(signature, z->pubk, digest);
+ if (r != 0) {
+ return NULL;
+ }
+
+ return z;
+}
diff --git a/src/keystore.h b/src/keystore.h
@@ -5,9 +5,11 @@
typedef struct keystore_key {
unsigned char pk[SWARM_PRIVATE_KEY_SIZE];
+ unsigned char pubk[SWARM_PUBLIC_KEY_SIZE];
unsigned char label[SWARM_KEY_LABEL_SIZE];
} keystore_key_t;
+
typedef struct keystore {
size_t pk_sz;
size_t label_sz;
@@ -17,8 +19,12 @@ typedef struct keystore {
keystore_key_t* (*label)(keystore_key_t *key);
} keystore_t;
+
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(const keystore_t *keystore, unsigned char *z, const int key_idx, const unsigned char *digest);
+keystore_key_t* key_recover(keystore_key_t *key, const unsigned char *signature, const unsigned char *digest);
+int key_from_public(keystore_key_t *key);
+int key_from_private(keystore_key_t *key);
#endif // _LIBSWARM_SIGN_H
diff --git a/src/soc.c b/src/soc.c
@@ -2,6 +2,7 @@
#include "keccak-tiny.h"
+#include "keystore.h"
#include "swarm.h"
#include "soc.h"
@@ -66,3 +67,44 @@ unsigned char* soc_serialize(const soc_chunk_t *chunk, unsigned char *z, size_t
return z;
}
+
+
+// must be minimum 96 bytes long
+int soc_digest(const soc_chunk_t *chunk, unsigned char *z) {
+ int r;
+ int crsr;
+ unsigned char *p;
+
+ p = z + SWARM_WORD_SIZE;
+ crsr = 0;
+ memcpy(p + crsr, chunk->identifier, SWARM_SOC_IDENTIFIER_SIZE);
+ crsr += SWARM_SOC_IDENTIFIER_SIZE;
+ memcpy(p + crsr, chunk->data.hash, SWARM_WORD_SIZE);
+ crsr += SWARM_WORD_SIZE;
+
+ r = keccak_hash_btc(z, SWARM_WORD_SIZE, p, crsr);
+ if (r < 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int soc_verify(soc_chunk_t *chunk) {
+ int r;
+ unsigned char b[96];
+ keystore_key_t key;
+ keystore_key_t *key_r;
+
+ r = soc_digest(chunk, b);
+ if (r != 0) {
+ return 1;
+ }
+
+ key_r = key_recover(&key, chunk->signature, b);
+ if (key_r == NULL) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/soc.h b/src/soc.h
@@ -1,7 +1,7 @@
#ifndef _LIBSWARM_SOC_H
#define _LIBSWARM_SOC_H
-#include "swarm.h"
+#include "def.h"
#include "chunk.h"
#define SWARM_SOC_TOPIC_SIZE 20
@@ -16,6 +16,8 @@ typedef struct soc_chunk {
int soc_identifier(char *z, const char *topic, const char *index);
int soc_address(char *z, const char *identifier, const char *address);
+int soc_digest(const soc_chunk_t* chunk, unsigned char *z);
unsigned char* soc_serialize(const soc_chunk_t *chunk, unsigned char *z, size_t *sz);
+int soc_verify(soc_chunk_t *chunk);
#endif // _LIBSWARM_SOC_H
diff --git a/test/check_chunk.c b/test/check_chunk.c
@@ -0,0 +1,56 @@
+#include <check.h>
+#include <stdlib.h>
+
+#include "common.h"
+#include "hex.h"
+#include "def.h"
+#include "chunk.h"
+
+
+START_TEST(check_chunk_verify) {
+ int r;
+ swarm_chunk_t chunk;
+
+ hex2bin(HASH_OF_FOO, chunk.hash);
+ memset(chunk.span, 0, SWARM_DATA_LENGTH_TYPESIZE);
+ chunk.span[0] = 3;
+ chunk.payload = "foo";
+ chunk.payload_sz = 3;
+
+ r = chunk_verify(&chunk);
+ ck_assert_int_eq(r, 0);
+
+ chunk.span[0] = 4;
+ r = chunk_verify(&chunk);
+ ck_assert_int_eq(r, 1);
+}
+END_TEST
+
+
+Suite * common_suite(void) {
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("chunk");
+ tc = tcase_create("core");
+ tcase_add_test(tc, check_chunk_verify);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
+
+int main(void) {
+ int n_fail;
+
+ Suite *s;
+ SRunner *sr;
+
+ s = common_suite();
+ sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_VERBOSE);
+ n_fail = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (n_fail == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test/check_keystore.c b/test/check_keystore.c
@@ -44,10 +44,31 @@ START_TEST(check_keystore_getput) {
}
END_TEST
+START_TEST(check_keystore_key_generate) {
+ int r;
+ keystore_key_t key;
+
+ unsigned char public_key_check[SWARM_PUBLIC_KEY_SIZE];
+ unsigned char label_check[SWARM_ADDRESS_SIZE];
+
+ hex2bin(TEST_PRIVATE_KEY, key.pk);
+ r = key_from_private(&key);
+ ck_assert_int_eq(r, 0);
+
+ hex2bin(TEST_PUBLIC_KEY, public_key_check);
+ ck_assert_mem_eq(key.pubk, public_key_check, SWARM_PUBLIC_KEY_SIZE);
+
+ hex2bin(TEST_ADDRESS, label_check);
+ ck_assert_mem_eq(key.label, label_check, SWARM_ADDRESS_SIZE);
+}
+END_TEST
+
START_TEST(check_keystore_sign) {
int r;
keystore_t keystore;
keystore_key_t key;
+ keystore_key_t key_recovered;
+ keystore_key_t *key_recovered_returned;
struct block_generator bg;
unsigned char signature[SWARM_SIGNATURE_SIZE];
unsigned char *signature_returned;
@@ -66,11 +87,12 @@ START_TEST(check_keystore_sign) {
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);
+ key_recovered_returned = key_recover(&key_recovered, signature, digest);
+ ck_assert_ptr_nonnull(key_recovered_returned);
hex2bin(TEST_PUBLIC_KEY, public_key_check);
- ck_assert_mem_eq(public_key, public_key_check, SWARM_PUBLIC_KEY_SIZE);
+ ck_assert_mem_eq(key_recovered.pubk, public_key_check, SWARM_PUBLIC_KEY_SIZE);
+ ck_assert_mem_eq(key_recovered.pubk, key_recovered_returned->pubk, SWARM_PUBLIC_KEY_SIZE);
keystore_free(&keystore);
}
@@ -84,6 +106,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_key_generate);
tcase_add_test(tc, check_keystore_sign);
suite_add_tcase(s, tc);
diff --git a/test/check_soc.c b/test/check_soc.c
@@ -5,6 +5,7 @@
#include "hex.h"
#include "common.h"
#include "def.h"
+#include "keystore.h"
START_TEST(check_soc_identifier) {
@@ -22,6 +23,7 @@ START_TEST(check_soc_identifier) {
}
END_TEST
+
START_TEST(check_soc_address) {
int i;
int r;
@@ -37,6 +39,42 @@ START_TEST(check_soc_address) {
}
END_TEST
+
+START_TEST(check_soc_digest) {
+ soc_chunk_t chunk;
+ int i;
+ int r;
+ char out[96];
+
+ r = soc_digest(&chunk, out);
+ ck_assert_int_eq(r, 0);
+}
+END_TEST
+
+
+START_TEST(check_soc_verify) {
+ int r;
+ soc_chunk_t chunk;
+ keystore_key_t key;
+ keystore_key_t *key_returned;
+ struct block_generator bg;
+
+ bg.v = 0;
+ bg.m = 256;
+
+ hex2bin("TEST_PRIVATE_KEY", key.pk);
+ r = key_from_private(&key);
+ ck_assert_int_eq(r, 0);
+
+ *(chunk.signature+64) = 0x01;
+ r = soc_verify(&chunk);
+ ck_assert_int_eq(r, 0);
+
+ //key_returned = key_recover(&key, chunk.signature, digest);
+}
+END_TEST
+
+
START_TEST(check_soc_serialize) {
soc_chunk_t soc_chunk;
long long span;
@@ -83,6 +121,8 @@ Suite * common_suite(void) {
tc = tcase_create("core");
tcase_add_test(tc, check_soc_identifier);
tcase_add_test(tc, check_soc_address);
+ tcase_add_test(tc, check_soc_digest);
+ tcase_add_test(tc, check_soc_verify);
tcase_add_test(tc, check_soc_serialize);
suite_add_tcase(s, tc);
diff --git a/test/common.c b/test/common.c
@@ -36,32 +36,3 @@ 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
@@ -17,4 +17,3 @@ 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);