adding multihash

This commit is contained in:
jmjatlanta 2016-11-07 15:11:58 -05:00
parent f9a921102e
commit 79820e54bf
13 changed files with 877 additions and 2 deletions

199
crypto/encoding/base58.c Normal file
View file

@ -0,0 +1,199 @@
/*
* Copyright 2012-2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#include <string.h>
#include <math.h>
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
/**
* convert a base58 encoded string into a binary array
* @param b58 the base58 encoded string
* @param base58_size the size of the encoded string
* @param bin the results buffer
* @param binszp the size of the results buffer
* @returns true(1) on success
*/
int libp2p_crypto_encoding_base58_decode(const char* b58, size_t base58_size, unsigned char** bin, size_t* binszp)
{
size_t binsz = *binszp;
const unsigned char* b58u = (const void*)b58;
unsigned char* binu = *bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
uint64_t t;
uint32_t c;
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
size_t b58sz;
b58sz = strlen(b58);
memset(outi, 0, outisz * sizeof(*outi));
// Leading zeros, just count
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i) {
++zerocount;
}
for (; i < b58sz; ++i) {
if (b58u[i] & 0x80) {
// High-bit set on invalid digit
return 0;
}
if (b58digits_map[b58u[i]] == -1) {
// Invalid base58 digit
return 0;
}
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--;) {
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
}
if (c) {
// Output number too big (carry to the next int32)
memset(outi, 0, outisz * sizeof(*outi));
return 0;
}
if (outi[0] & zeromask) {
// Output number too big (last int32 filled too far)
memset(outi, 0, outisz * sizeof(*outi));
return 0;
}
}
j = 0;
switch (bytesleft) {
case 3:
*(binu++) = (outi[0] & 0xff0000) >> 16;
case 2:
*(binu++) = (outi[0] & 0xff00) >> 8;
case 1:
*(binu++) = (outi[0] & 0xff);
++j;
default:
break;
}
for (; j < outisz; ++j) {
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
*(binu++) = (outi[j] >> 0) & 0xff;
}
// Count canonical base58 byte count
binu = *bin;
for (i = 0; i < binsz; ++i) {
if (binu[i]) {
break;
}
--*binszp;
}
*binszp += zerocount;
memset(outi, 0, outisz * sizeof(*outi));
return 1;
}
/**
* encode an array of bytes into a base58 string
* @param binary_data the data to be encoded
* @param binary_data_size the size of the data to be encoded
* @param base58 the results buffer
* @param base58_size the size of the results buffer
* @returns true(1) on success
*/
//int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char* base58, size_t* base58_size)
int libp2p_crypto_encoding_base58_encode(const unsigned char* data, size_t binsz, unsigned char** b58, size_t* b58sz)
{
const uint8_t* bin = data;
int carry;
ssize_t i, j, high, zcount = 0;
size_t size;
while (zcount < (ssize_t)binsz && !bin[zcount]) {
++zcount;
}
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memset(buf, 0, size);
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
;
if (*b58sz <= zcount + size - j) {
*b58sz = zcount + size - j + 1;
memset(buf, 0, size);
return 0;
}
if (zcount) {
memset(b58, '1', zcount);
}
for (i = zcount; j < (ssize_t)size; ++i, ++j) {
(*b58)[i] = b58digits_ordered[buf[j]];
}
(*b58)[i] = '\0';
*b58sz = i + 1;
memset(buf, 0, size);
return 1;
}
/***
* calculate the size of the binary results based on an incoming base58 string
* @param base58_string the string
* @returns the size in bytes had the string been decoded
*/
size_t libp2p_crypto_encoding_base58_decode_size(const unsigned char* base58_string) {
size_t string_length = strlen((char*)base58_string);
size_t decoded_length = 0;
size_t radix = strlen(b58digits_ordered);
double bits_per_digit = log2(radix);
decoded_length = floor(string_length * bits_per_digit / 8);
return decoded_length;
}
/**
* calculate the max length in bytes of an encoding of n source bits
* @param base58_string the string
* @returns the maximum size in bytes had the string been decoded
*/
size_t libp2p_crypto_encoding_base58_decode_max_size(const unsigned char* base58_string) {
size_t string_length = strlen((char*)base58_string);
size_t decoded_length = 0;
size_t radix = strlen(b58digits_ordered);
double bits_per_digit = log2(radix);
decoded_length = ceil(string_length * bits_per_digit / 8);
return decoded_length;
}

68
crypto/encoding/x509.c Normal file
View file

@ -0,0 +1,68 @@
//
// x509.c
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#include <stdio.h>
#include <string.h>
#include "mbedtls/rsa.h"
#include "mbedtls/pk.h"
#include "mbedtls/ctr_drbg.h"
#include "libp2p/crypto/encoding/x509.h"
/**
* public methods
*/
/**
* convert a RSA Private Key to an array of bytes in DER format
* @param private_key the private key
* @param bytes where to put the resultant bytes
* @returns true(1) on success
*/
int libp2p_crypto_encoding_x509_private_key_to_der(struct RsaPrivateKey* private_key, unsigned char* bytes[1600]) {
// get everything setup
mbedtls_pk_context ctx;
mbedtls_pk_init( &ctx);
mbedtls_pk_setup( &ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
mbedtls_rsa_context* rsa = mbedtls_pk_rsa( ctx );
// set the values in the context
mbedtls_mpi N;
mbedtls_mpi_init(&N);
mbedtls_mpi_lset(&N, private_key->prime1);
mbedtls_mpi E;
mbedtls_mpi_init(&E);
mbedtls_mpi_lset(&E, private_key->private_exponent);
rsa->N = N;
rsa->E = E;
rsa->len = ( mbedtls_mpi_bitlen(&rsa->N ) + 7) >> 3;
// now write to DER
mbedtls_pk_write_key_der(&ctx, *bytes, 1600);
mbedtls_mpi_free(&N);
mbedtls_mpi_free(&E);
mbedtls_rsa_free(rsa);
mbedtls_pk_free(&ctx);
return 1;
}
int libp2p_crypto_encoding_x509_der_to_private_key(unsigned char* der, size_t der_length, struct RsaPrivateKey* private_key) {
mbedtls_pk_context ctx;
mbedtls_pk_init(&ctx);
mbedtls_pk_parse_key(&ctx, der, der_length, NULL, 0);
return 1;
}

View file

@ -76,3 +76,15 @@ exit:
return retVal;
}
/**
* convert a struct RsaPublicKey into a stream of bytes compatible with x509 PKI
* @param public_key the public key struct
* @param bytes the results
* @param bytes_size the length of the results
*/
int crypto_rsa_public_key_bytes(struct RsaPublicKey* public_key, char** bytes, unsigned long long* bytes_size) {
// marshal to x509
return 0;
}

View file

View file

@ -0,0 +1,47 @@
//
// base58.h
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef base58_h
#define base58_h
/**
* convert a base58 encoded string into a binary array
* @param base58 the base58 encoded string
* @param base58_size the size of the encoded string
* @param binary_data the results buffer
* @param binary_data_size the size of the results buffer
* @returns true(1) on success
*/
int libp2p_crypto_encoding_base58_decode(const unsigned char* base58, size_t base58_size, unsigned char** binary_data, size_t *binary_data_size);
/**
* encode an array of bytes into a base58 string
* @param binary_data the data to be encoded
* @param binary_data_size the size of the data to be encoded
* @param base58 the results buffer
* @param base58_size the size of the results buffer
* @returns true(1) on success
*/
int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char** base58, size_t* base58_size);
/***
* calculate the size of the binary results based on an incoming base58 string with no initial padding
* @param base58_string the string
* @returns the size in bytes had the string been decoded
*/
size_t libp2p_crypto_encoding_base58_decode_size(const unsigned char* base58_string);
/**
* calculate the max length in bytes of an encoding of n source bits
* @param base58_string the string
* @returns the maximum size in bytes had the string been decoded
*/
size_t libp2p_crypto_encoding_base58_decode_max_size(const unsigned char* base58_string);
#endif /* base58_h */

View file

@ -0,0 +1,18 @@
//
// x509.h
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef __LIBP2P_CRYPTO_ENCODING_X509_H__
#define __LIBP2P_CRYPTO_ENCODING_X509_H__
#include "libp2p/crypto/rsa.h"
int libp2p_crypto_encoding_x509_private_key_to_der(struct RsaPrivateKey* private_key, unsigned char* bytes[1600]);
int libp2p_crypto_encoding_x509_der_to_private_key(unsigned char* der, size_t der_length, struct RsaPrivateKey* private_key);
#endif /* x509_h */

View file

@ -43,5 +43,13 @@ struct RsaPrivateKey {
*/
int crypto_rsa_generate_keypair(struct RsaPrivateKey* private_key, unsigned long num_bits_for_keypair);
/**
* convert a struct RsaPublicKey into a stream of bytes compatible with x509 PKI
* @param public_key the public key struct
* @param bytes the results
* @param bytes_size the length of the results
*/
int crypto_rsa_public_key_bytes(struct RsaPublicKey* public_key, char** bytes, unsigned long long* bytes_size);
#endif /* rsa_h */

View file

@ -0,0 +1,61 @@
/**
* An implementation of the multihash protocol in C
*/
#ifndef __LIBP2P_MULTIHASH_H
#define __LIBP2P_MULTIHASH_H
#define MULTIHASH_SHA1 0x11
#define MULTIHASH_SHA2_256 0x12
#define MULTIHASH_SHA2_512 0x13
#define MULTIHASH_SHA3_512 0x14
#define MULTIHASH_SHA3_384 0x15
#define MULTIHASH_SHA3_256 0x16
#define MULTIHASH_SHA3_224 0x17
#define MULTIHASH_SHAKE_128 0x18
#define MULTIHASH_SHAKE_256 0x19
#define MULTIHASH_BLAKE2B 0x20
#define MULTIHASH_BLAKE2S 0x21
struct MultiHash {
char fn_code;
char size;
unsigned char* data;
};
char* libp2p_multihash_get_fn_name(char fn_code);
/**
* encodes the multihash into a hex string
*/
int libp2p_multihash_hex_string(struct MultiHash* hash, char* string, int max_length);
/**
* decodes a hex string into a multihash
*/
int libp2p_multihash_from_hex_string(char* string, int length, struct MultiHash* hash);
/**
* 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);
/**
* 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);
/**
* retrieve the size required for the multihash that is embedded in the base58 encoded string
*/
size_t libp2p_multihash_b58_size(unsigned char* b58_string);
#endif /* multihash_h */

186
multihash/multihash.c Normal file
View file

@ -0,0 +1,186 @@
//
// 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;
}

76
test/crypto/test_base58.h Normal file
View file

@ -0,0 +1,76 @@
//
// test_base58.h
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef test_base58_h
#define test_base58_h
#include "libp2p/crypto/encoding/base58.h"
/***
* tests the base58 encoding and decoding
*/
int test_base58_encode_decode() {
unsigned char original[3] = { 0x41, 0x42 ,0x00 };
size_t buffer_size = 10;
unsigned char buffer[buffer_size];
unsigned char* ptr = buffer;
int retVal = libp2p_crypto_encoding_base58_encode(original, 3, &ptr, &buffer_size);
if (retVal == 0)
return 0;
size_t result_size = 3;
unsigned char result[result_size];
unsigned char* ptr2 = result;
memset(result, 0, result_size);
retVal = libp2p_crypto_encoding_base58_decode(ptr, buffer_size, &ptr2, &result_size);
if (retVal == 0)
return 0;
for (int i = 0; i < 3; i++)
if (original[i] != result[i])
return 0;
return 1;
}
int test_base58_size() {
unsigned char* unencoded = (unsigned char*)"Hello, World!";
size_t string_length = strlen((char*)unencoded) + 1;
size_t encoded_length = 100;
unsigned char encoded[encoded_length];
unsigned char* ptr = encoded;
// now encode it
libp2p_crypto_encoding_base58_encode(unencoded, string_length, &ptr, &encoded_length);
size_t size_enc = libp2p_crypto_encoding_base58_decode_size(ptr);
size_t max_size_enc = libp2p_crypto_encoding_base58_decode_max_size(ptr);
if (size_enc <= string_length && max_size_enc >= string_length)
return 1;
return 0;
}
int test_base58_max_size() {
unsigned char hash[5] = {'S', 'D', 'Y', 'h', 'd' };
size_t results = libp2p_crypto_encoding_base58_decode_max_size(hash);
if (results != 4)
return 0;
return 1;
}
#endif /* test_base58_h */

65
test/crypto/test_rsa.h Normal file
View file

@ -0,0 +1,65 @@
//
// test_rsa.h
// libp2p_xcode
//
// Created by John Jones on 11/3/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef test_rsa_h
#define test_rsa_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libp2p/crypto/rsa.h"
#include "libp2p/crypto/encoding/base64.h"
#include "libp2p/crypto/encoding/x509.h"
/**
* attempt to take a known public key in bytes and convert to bytes compatible with go's version of PKIX
*/
int test_crypto_rsa_public_key_bytes() {
// first we need a public key
struct RsaPrivateKey private_key;
crypto_rsa_generate_keypair(&private_key, 2048);
// save it to a text file (converting the primes to text)
FILE* temp_file = fopen("/tmp/public_key.txt", "w");
fprintf(temp_file, "%llu\n", private_key.public_key.modulus);
fprintf(temp_file, "%llu", private_key.public_key.exponent);
fclose(temp_file);
// TODO: get what go produces
// compare what go produces to ours.
return 0;
}
int test_crypto_x509_private_to_der() {
struct RsaPrivateKey private_key;
private_key.prime1 = 6908992579533823845;
private_key.private_exponent = 65537;
//crypto_rsa_generate_keypair(&private_key, 2048);
unsigned char buffer[1600];
unsigned char* c = buffer;
libp2p_crypto_encoding_x509_private_key_to_der(&private_key, &c);
return 1;
}
int test_crypto_x509_der_to_private() {
char* der = "CAASpwkwggSjAgEAAoIBAQDTDJBWjDzS/HxDNOHazvzH2bu9CPMVHUrrvKRdBUM5ansL6/CC3MVZ6HVm4O6QHRapN6EF2CbrTgI4KBOXIL125Xo8MlROnyfXYk3O5q2tgwL/MbW8kXjtkyCfBak7MUoLOdLU7Svg0gkl3l+uDAiDcCLnwJVcFfq9ch6z4wMOhYJqE5dtx0uXxn6IuKWl1B69FTvBXCc0thw8Rw54b941FDcsBH5ttV9mRNCJym3poZ5qalNgXlxoIIB+PUx5QD+aq7KMJdpAX8HkapBntCOahP/QUceRmma0grlZLeYkH6/oi/hIrM6se3KUZ+F6tBuDFys8UAZy/X2BCUbKjbxtAgMBAAECggEANWfQfpYuLhXGPBt9q6kFPm1SnJtPJ+CpvM2XqhJS2IyhZnrl+bd0GTRBwS7aL42s1lVFYf04nAK5fQxnKK8YQqX/MIxr2RldM5ukpN6qxGWKtJkXrAgD2dqJPrRoBpqKahzPxSHfIJ0Fw5dqDtjsrpYJvyt0oEDPmnDuZAbmFx4sJqnesPNhKxtRMBx1+yxGVuRVJjHcqAgqPqwNiuoMEaYMY+G9yzT6vza8ovCpbX7BBIgM5fAT9PD8TBG//Vu9THvj/ZomiVG2qv6RL0qQyVb+DUzPZz1amBsSvahtXCl72jA3JwAZ943RxSR66P934S0ashkVwLUi46z/EAbJ4QKBgQDojGIO07BEVL2+7VxlGL9XGZQp4Y3qlhh2zDDQGwkCq/KQ+BdNYWitPwqRl9GqFLgpmeQIhyHTOa/IThx+AXGKVQ24ROH+skUs4IbO6R3qY7BKtb5lkZE/Yln09x70BBngUYAzh/rtnsXO3cl1x2XDDqUbCwlGcDAs8Jh/6UnvQwKBgQDoVSQs7Uq9MJCGIUM2bixX89tHzSxq5mn9wMD3/XRVfT5Ua8YkYBuzcmlcT39N7L5BwuyFqX3Vi7lv/Ya/qaQP6XkrZ8W1OAaTlYewfE5ZgknJqSpXcNWhABKeNmqndvqyQ/8HNCv/j8AdraGB2DGO57Xso5J0CQ43W/U9+QIyjwKBgHLL2hw3o+wXaRO3WMUPUmVM2zdRgR0suybp5a7Vqb0H5NZrohUw4NulIzJ8H6Q2VjMzJL6Q9sGu2HepF6ecTtBa7ErqtiVlG4Dr1aCOs5XhYEWBMlwxX+JKSt4Cn+UVoTB7Cy5lEhn7JurX0Xuy0ylXMWoIKKv89cs5eg6quzTBAoGAaq9eEztLjKCWXOE9SetBdYnG8aunb9cqaJlwgu/h0bfXPVDYBbAUSEyLURY4MQI7Q1tM3Pu9iqfEmUZj7/LoIV5mg6X9RX/alT6etk3+dF+9nlqN1OU9U9cCtZ/rTcb2y5EptJcidRH/eCFY/pTV/PcttOJPx/S4kHcroC+N8MUCgYEA6DA5QHxHfNN6Nxv+pEzy2DIxFe9RrBxS+KPBsra1C8jgdeMf4EmfU0Nox92V0q0bRrD5ztqQwSONI0hSRb1iiMWR6MuFnAFajUJfASjjIlZ6nIQjQslI7vjlvYyyHS/p/Codxap+yJlTLWwVEOXp2D9pWwiMq1xEyf0TH1BosvM=";
size_t b64_length = base64_decode_length((unsigned char*)der, strlen(der));
unsigned char buffer[b64_length];
unsigned char* b = buffer;
size_t ultimate_length;
int retVal = base64_decode((unsigned char*)der, strlen(der), b, b64_length, &ultimate_length);
if (retVal == 0)
return 0;
struct RsaPrivateKey private_key;
libp2p_crypto_encoding_x509_der_to_private_key(b, ultimate_length, &private_key);
return 1;
}
#endif /* test_rsa_h */

View file

@ -0,0 +1,122 @@
//
// test_multihash.h
// libp2p_xcode
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef test_multihash_h
#define test_multihash_h
#include "libp2p/multihash/multihash.h"
#include "libp2p/crypto/encoding/base58.h"
int test_multihash_encode() {
struct MultiHash hash;
hash.fn_code = MULTIHASH_SHA1;
hash.size = 2;
unsigned char data[] = "A";
hash.data = data;
// 8 bytes plus terminating null to make it easier to debug
// note: function does not clear the buffer, so we have to
char buffer[9];
char* b = buffer;
memset(b, 0, 9);
int retVal = libp2p_multihash_hex_string(&hash, b, 9);
if (retVal == 0)
return 0;
if (b[0] != '1' && b[1] != '1')
return 0;
if (b[2] != '0' && b[3] != '2')
return 0;
if (b[4] != '4' && b[5] != '1')
return 0;
if (b[6] != '0' && b[7] != '0')
return 0;
return 1;
}
int test_multihash_decode() {
char in[9] = "11024100";
char* string = in;
struct MultiHash hash;
int retVal = libp2p_multihash_from_hex_string(string, 8, &hash);
if (retVal == 0)
return 0;
if (hash.fn_code != 0x11)
return 0;
if (hash.size != 2)
return 0;
if (hash.data[0] != 0x41 || hash.data[1] != 0x00)
return 0;
return 1;
}
int test_multihash_base58_decode() {
unsigned char original[5] = { 'S', 'D', 'Y', 'h', 'd' };
size_t buffer_len = 4;
unsigned char buffer[buffer_len];
unsigned char* ptr = buffer;
int retVal = libp2p_crypto_encoding_base58_decode(original, 5, &ptr, &buffer_len);
if (retVal == 0)
return 0;
if (buffer[0] != 0x11)
return 0;
if (buffer[1] != 0x02)
return 0;
return 1;
}
int test_multihash_size() {
unsigned char hash[6] = {'S', 'D', 'Y', 'h', 'd' ,0 };
unsigned char* ptr = hash;
size_t sz = libp2p_multihash_b58_size(ptr);
return sz == 2;
}
int test_multihash_base58_encode_decode() {
// build the original MultiHash
struct MultiHash original;
original.fn_code = MULTIHASH_SHA1;
original.size = 2;
unsigned char data[] = "A";
original.data = data;
// have a buffer to store the base58 encoding
size_t buffer_size = 65535;
unsigned char buffer[buffer_size];
unsigned char* b = buffer;
// encode it
libp2p_multihash_to_b58(&original, b, buffer_size);
// build a place to store the new MultiHash
struct MultiHash results;
results.size = 2;
unsigned char results_data[2];
results.data = results_data;
// decode it
libp2p_b58_to_multihash(b, strlen((char*)b), &results);
// compare
if (original.fn_code != results.fn_code)
return 0;
if (original.size != results.size)
return 0;
if (original.data[0] != results.data[0])
return 0;
if (original.data[1] != results.data[1])
return 0;
return 1;
}
#endif /* test_multihash_h */

View file

@ -1,6 +1,10 @@
#include <stdio.h>
#include "crypto/test_rsa.h"
#include "multihash/test_multihash.h"
#include "crypto/test_base58.h"
int testit(const char* name, int (*func)(void)) {
printf("Testing %s...\n", name);
int retVal = func();
@ -12,8 +16,17 @@ int testit(const char* name, int (*func)(void)) {
}
int main(int argc, char** argv) {
//testit("test_repo_config_init", test_repo_config_init);
//testit("test_crypto_rsa_public_key_bytes", test_crypto_rsa_public_key_bytes);
//testit("test_crypto_x509_private_to_der", test_crypto_x509_private_to_der);
//testit("test_crypto_x509_der_to_private", test_crypto_x509_der_to_private);
testit("test_multihash_encode", test_multihash_encode);
testit("test_multihash_decode", test_multihash_decode);
testit("test_multihash_base58_encode_decode", test_multihash_base58_encode_decode);
testit("test_multihash_base58_decode", test_multihash_base58_decode);
testit("test_base58_encode_decode", test_base58_encode_decode);
testit("test_base58_size", test_base58_size);
testit("test_base58_max_size", test_base58_max_size);
testit("test_multihash_size", test_multihash_size);
return 1;
}