adding multihash
This commit is contained in:
parent
f9a921102e
commit
79820e54bf
13 changed files with 877 additions and 2 deletions
199
crypto/encoding/base58.c
Normal file
199
crypto/encoding/base58.c
Normal 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
68
crypto/encoding/x509.c
Normal 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;
|
||||
}
|
12
crypto/rsa.c
12
crypto/rsa.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
47
include/libp2p/crypto/encoding/base58.h
Normal file
47
include/libp2p/crypto/encoding/base58.h
Normal 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 */
|
18
include/libp2p/crypto/encoding/x509.h
Normal file
18
include/libp2p/crypto/encoding/x509.h
Normal 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 */
|
|
@ -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 */
|
||||
|
|
61
include/libp2p/multihash/multihash.h
Normal file
61
include/libp2p/multihash/multihash.h
Normal 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
186
multihash/multihash.c
Normal 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
76
test/crypto/test_base58.h
Normal 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
65
test/crypto/test_rsa.h
Normal 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 */
|
122
test/multihash/test_multihash.h
Normal file
122
test/multihash/test_multihash.h
Normal 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 */
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue