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

soc.c (2466B)


      1 #include <string.h>
      2 
      3 #include "keccak-tiny.h"
      4 
      5 #include "keystore.h"
      6 #include "swarm.h"
      7 #include "soc.h"
      8 
      9 // z must be minimum 84 bytes long (32 bytes for out, 20 bytes for topic, 32 bytes for index)
     10 int soc_identifier(unsigned char *z, const unsigned char *topic, const unsigned char *index) {
     11 	int r;
     12 	unsigned char *p;
     13 	unsigned char *src;
     14 	size_t src_sz;
     15 	
     16 	src_sz = SWARM_SOC_TOPIC_SIZE + SWARM_SOC_INDEX_SIZE;
     17 
     18 	p = z + SWARM_WORD_SIZE;
     19 	src = p;
     20 	memcpy(p, topic, SWARM_SOC_TOPIC_SIZE);
     21 
     22 	p += SWARM_SOC_TOPIC_SIZE;
     23 	memcpy(p, index, SWARM_SOC_INDEX_SIZE);
     24 
     25 	r = keccak_hash_btc(z, SWARM_WORD_SIZE, src, src_sz);
     26 	if (r < 0) {
     27 		return 1;
     28 	}
     29 
     30 	return 0;
     31 }
     32 
     33 // z must be minimum 84 bytes long (32 bytes for out, 20 bytes for topic, 32 bytes for index)
     34 int soc_address(unsigned char *z, const unsigned char *identifier, const unsigned char *address) {
     35 	int r;
     36 	unsigned char *p;
     37 	unsigned char *src;
     38 	size_t src_sz;
     39 	
     40 	src_sz = SWARM_SOC_IDENTIFIER_SIZE + SWARM_ADDRESS_SIZE;
     41 
     42 	p = z + SWARM_WORD_SIZE;
     43 	src = p;
     44 	memcpy(p, identifier, SWARM_SOC_IDENTIFIER_SIZE);
     45 
     46 	p += SWARM_SOC_IDENTIFIER_SIZE;
     47 	memcpy(p, address, SWARM_ADDRESS_SIZE);
     48 
     49 	r = keccak_hash_btc(z, SWARM_WORD_SIZE, src, src_sz);
     50 	if (r < 0) {
     51 		return 1;
     52 	}
     53 
     54 	return 0;
     55 }
     56 
     57 unsigned char* soc_serialize(const soc_chunk_t *chunk, unsigned char *z, size_t *sz) {
     58 	int crsr;
     59 
     60 	crsr = 0;
     61 	memcpy(z, chunk, SWARM_SOC_IDENTIFIER_SIZE + SWARM_SIGNATURE_SIZE);
     62 	crsr += SWARM_SOC_IDENTIFIER_SIZE + SWARM_SIGNATURE_SIZE;
     63 
     64 	chunk_serialize(&chunk->data, z + crsr, sz);
     65 
     66 	*sz += crsr;
     67 
     68 	return z;
     69 }
     70 
     71 
     72 // must be minimum 96 bytes long 
     73 int soc_digest(const soc_chunk_t *chunk, unsigned char *z) {
     74 	int r;
     75 	int crsr;
     76 	unsigned char *p;
     77 
     78 	p = z + SWARM_WORD_SIZE;
     79 	crsr = 0;
     80 	memcpy(p + crsr, chunk->identifier, SWARM_SOC_IDENTIFIER_SIZE);
     81 	crsr += SWARM_SOC_IDENTIFIER_SIZE;
     82 	memcpy(p + crsr, chunk->data.hash, SWARM_WORD_SIZE);
     83 	crsr += SWARM_WORD_SIZE;
     84 
     85 	r = keccak_hash_btc(z, SWARM_WORD_SIZE, p, crsr);
     86 	if (r < 0) {
     87 		return 1;
     88 	}
     89 
     90 	return 0;
     91 }
     92 
     93 int soc_verify(const soc_chunk_t *chunk, const keystore_key_t *key_cmp) {
     94 	int r;
     95 	unsigned char b[96];
     96 	keystore_key_t key;
     97 	keystore_key_t *key_r;
     98 
     99 	r = soc_digest(chunk, b);
    100 	if (r != 0) {
    101 		return 1;
    102 	}
    103 
    104 	key_r = key_recover(&key, chunk->signature, b);
    105 	if (key_r == NULL) {
    106 		return 1;
    107 	}
    108 
    109 	r = key_from_public(&key);
    110 	if (r != 0) {
    111 		return 1;
    112 	}
    113 
    114 	r = memcmp(key.label, key_cmp->label, SWARM_ADDRESS_SIZE);
    115 	if (r != 0) {
    116 		return 1;
    117 	}
    118 
    119 	return 0;
    120 }