c-libp2p/multihash_old/multihash.c

187 lines
4.7 KiB
C
Raw Normal View History

2016-11-07 20:11:58 +00:00
//
// multihash.c
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libp2p/multihash/multihash.h"
#include "libp2p/crypto/encoding/base58.h"
char* libp2p_multihash_get_fn_name(char fn_code) {
switch(fn_code) {
case (0x11):
return "sha1";
case(0x12):
return "sha2-256";
case(0x13):
return "sha2-512";
case(0x14):
return "sha3-512";
case(0x15):
return "sha3-384";
case(0x16):
return "sha3-256";
case(0x17):
return "sha3-224";
case(0x18):
return "shake-128";
case(0x19):
return "shake-256";
case(0x20):
return "blake2b";
case(0x21):
return "blake2s";
}
return 0x00;
}
/**
* helper function to convert a char string to a byte
* @param s the string (only grabs the first character)
* @returns the value of the char
*/
unsigned char from_hex_to_char(const char* s) {
// make sure there is a null in position 3
char buff[3];
buff[0] = s[0];
buff[1] = s[1];
buff[2] = 0;
char* ptr = &buff[2];
return strtoul(buff, &ptr, 16);
}
/***
* convert a MultiHash into a byte array
* @param hash the MultiHash to convert
* @param results the resultant byte array
* @param max_length the maximum length of the byte array
* @returns true(1) on success
*/
int from_multihash_to_byte_array(struct MultiHash* hash, unsigned char* results, size_t max_length) {
// what size is needed?
int required_size = hash->size + 2;
if (required_size < max_length)
return 0;
results[0] = hash->fn_code;
results[1] = hash->size;
// now copy in the data
for(int i = 0; i < hash->size; i++)
results[i+2] = hash->data[i];
return 1;
}
/***
* public methods
**/
/***
* retrieve the size element of the multihash object that is embedded in the base58 string
* @param b58_string the base58 encoded string
* @returns the size element of the MultiHash object
*/
size_t libp2p_multihash_b58_size(unsigned char* b58_string) {
size_t byte_length = libp2p_crypto_encoding_base58_decode_max_size(b58_string);
unsigned char bytes[byte_length];
unsigned char* ptr = bytes;
int retVal = libp2p_crypto_encoding_base58_decode(b58_string, strlen((char*)b58_string), &ptr, &byte_length);
if (retVal == 0)
return 0;
return ptr[1];
}
/**
* turns a multihash into a string of hex
*/
int libp2p_multihash_hex_string(struct MultiHash* hash, char* string, int max_length) {
// calculate the size of the struct
size_t struct_size = sizeof(char) * (hash->size + 2);
// make sure we have enough space (2 bytes for each byte, plus terminating null
if (max_length < (struct_size * 2))
return 0;
// put in the hex values
char temp[3];
sprintf(temp, "%02x", hash->fn_code);
string[0] = temp[0];
string[1] = temp[1];
sprintf(temp, "%02x", hash->size);
string[2] = temp[0];
string[3] = temp[1];
for(int i = 0; i < struct_size - 2; i++) {
sprintf(temp, "%02x", hash->data[i]);
string[(i*2) + 4] = temp[0];
string[(i*2) + 5] = temp[1];
}
return 1;
}
/**
* decodes a hex string into a multihash
*/
int libp2p_multihash_from_hex_string(char* string, int length, struct MultiHash* hash) {
hash->fn_code = from_hex_to_char(&string[0]);
hash->size = from_hex_to_char(&string[2]);
for(int i = 0; i < hash->size; i++) {
int pos = (i * 2) + 4;
if (pos > length - 1)
return 0;
hash->data[i] = from_hex_to_char(&string[(i*2) + 4]);
}
return 1;
}
/**
* turns a multihash into a b58 string
* @param hash the Multihash to encode
* @param binary_buffer the buffer to fill
* @param max_length the size of the buffer
* @returns true(1) on success
*/
int libp2p_multihash_to_b58(struct MultiHash* hash, unsigned char* binary_buffer, size_t max_length) {
int bytes_length = hash->size + 2;
unsigned char bytes[bytes_length];
unsigned char* ptr = bytes;
int retVal = from_multihash_to_byte_array(hash, bytes, bytes_length);
if (retVal == 0)
return 0;
// finally encode the array into base64
return libp2p_crypto_encoding_base58_encode(ptr, bytes_length, &binary_buffer, &max_length);
}
/**
* turns a base58 encoded string into a MultiHash
* @param b58_string the base58 encoded string
* @param b58_string_length the length of the encoded string
* @param hash the MultiHash to fill
* @returns true(1) on success
*/
int libp2p_b58_to_multihash(unsigned char* b58_string, size_t b58_string_length, struct MultiHash* hash) {
size_t buffer_size = libp2p_crypto_encoding_base58_decode_max_size(b58_string);
unsigned char buffer[buffer_size];
unsigned char* b = buffer;
libp2p_crypto_encoding_base58_decode(b58_string, b58_string_length, &b, &buffer_size);
// now build the hash
hash->fn_code = b[0];
hash->size = b[1];
memcpy(hash->data, &b[2], hash->size);
return 0;
}