Skip to content
This repository has been archived by the owner on Dec 28, 2018. It is now read-only.

improve on Hash Type #25

Open
sleepdefic1t opened this issue Jun 8, 2018 · 1 comment
Open

improve on Hash Type #25

sleepdefic1t opened this issue Jun 8, 2018 · 1 comment
Labels
enhancement New feature or request

Comments

@sleepdefic1t
Copy link
Contributor

sleepdefic1t commented Jun 8, 2018

Improve on the concept of a Hash type in the Ark-Cpp wrapper

The aim of this issue is to open the discussion of storing hash-types as bytes with optional retrieval as a hex-string.

objectives:

  • improve the storage size of hashable types
  • improve handling of hashable types
  • improve ability to model new hash-types
  • introduce a clean way to check for hash-type conformance

POC Implementation available in

https://github.com/sleepdefic1t/Ark-Cpp/tree/improvements_preview/src/types

Tested implementation uses Hashable as a temple such that hashes, keys, and signatures may be defined via

#define HASH_STORAGE_BYTE_COUNT 32
#define Hash Hashable<HASH_STORAGE_BYTE_COUNT>
#define PUBKEY_STORAGE_BYTE_COUNT 33
#define Publickey Hashable<PUBKEY_STORAGE_BYTE_COUNT>
#define PRIVKEY_STORAGE_BYTE_COUNT 32
#define Privatekey Hashable<PRIVKEY_STORAGE_BYTE_COUNT>
#define SIGNATURE_BYTE_COUNT 71
#define Signature Hashable<SIGNATURE_BYTE_COUNT>

Sample class implementation

template <size_t COUNT>
class Hashable :
	public Printable
{
  public:
	/************************************************** 
	* Constructor 
	* @brief: default empty constructor
	**************************************************/
	Hashable() : bytes_() {};
	/*************************************************/

	/************************************************** 
	* Constructor 
	* @param: const char *const newHash
	* @brief: also checks if Hash is empty before storage
	**************************************************/
	Hashable(const char *const newHash)
	{ 
		strlen(newHash) != 0 ?
			this->set(newHash) :
			void(this->bytes_[0] = '\0');
	};
	/*************************************************/

	/************************************************** 
	* Deconstructor 
	* @brief: fill this->bytes_ with random data before deconstruction
	**************************************************/
	~Hashable() {
		Sanitize(this->bytes_, COUNT);
	};
	/*************************************************/

	/************************************************** 
	* @brief: returns element count of Hashable object
	**************************************************/
	size_t count() const { return COUNT; };
	/*************************************************/

	/************************************************** 
	* @brief: returns size of Hashable object
	**************************************************/
	size_t size() const { return sizeof(this->bytes_); };
	/*************************************************/

	/************************************************** 
	* @brief: returns vector of stored bytes
	**************************************************/
	const inline std::vector<uint8_t> vBytes() const
	{
		return std::vector<uint8_t>(this->bytes_);
	};
	/*************************************************/

	/************************************************** 
	* @brief: returns vector of hex-string representation of stored bytes
	**************************************************/
	const inline std::vector<char> vHex() const
	{
		return (this->bytes_[0] != '\0') ?
				std::vector<char>(this->hex().c_str()) :
				std::vector<char>(1);
	};
	/*************************************************/

	/************************************************** 
	* @brief: returns hex-string representation of stored bytes
	**************************************************/
	std::string hex() const
	{
		if (this->bytes_[0] != '\0')
		{
			char hexBuffer[(COUNT * 2) + 1];
			BytesToHex(this->bytes_, hexBuffer, COUNT);
			return std::string( hexBuffer );
		}
		else
		{
			return std::string("");
		};
	}
	/*************************************************/

	/************************************************** 
	* @brief: returns hex c-string ('\0' or NULL Terminated string) representation of stored bytes
	**************************************************/
	operator const char *() const
	{
		return this->hex().c_str();
	};
	/*************************************************/

	/**************************************************
	* @param: Print& p 
	* @brief: prints Hashable object
	**************************************************/
	virtual size_t printTo(Print& p) const
	{
		size_t size = 0;
		size += p.print( this->hex().c_str() );
		return size;
	};
	/*************************************************/

  protected:
	uint8_t bytes_[COUNT];

	/**************************************************
	* @param: const char *const newHash 
	* @brief: Sets new Hash, copying byte-values to internal storage
	**************************************************/
	void set(const char *const newHash)
	{
		if (isHex(newHash))
		{ 
			HexToBytes(newHash, this->bytes_);
		}
		else
		{ 
			std::memmove(this->bytes_, newHash, COUNT);
		};
	};
	/*************************************************/

};

note: Sanitize method introduced to randomize byte data before deconstruction.
This will necessarily have to use proven T/RNG functions in the crypto libraries,
but is currently implemented as follows:

static uint8_t getRandomDigit()
{	
#ifdef USE_IOT
	randomSeed(random(0, 1024));
	return random(0, 255);
#else
	std::default_random_engine generator;
	std::uniform_int_distribution<uint32_t> distribution(0, 255);
	return distribution(generator);
#endif
}

static void Sanitize(uint8_t* buffer, size_t size)
{
	for (unsigned int i = 0; i < size; i++)
	{
		buffer[i] = getRandomDigit();
	};
};
@sleepdefic1t sleepdefic1t added the enhancement New feature or request label Jun 8, 2018
@sleepdefic1t
Copy link
Contributor Author

Current running implementation @

https://github.com/sleepdefic1t/Ark-Cpp/tree/improvements_preview/src/types

single header src/types/base/byteable.h



#ifndef BYTEABLE_H
#define BYTEABLE_H

#include "utilities/platform.h"
#include "utilities/formatting.h"
#include <vector>
#include <memory>

template <size_t COUNT>
class Byteable
{
    protected:
		uint8_t bytes_[COUNT];
	public:
		/************************************************** 
		* Constructor 
		* @brief: default empty constructor
		**************************************************/
		Byteable() : bytes_() {};
		/*************************************************/

		/************************************************** 
		* Constructor 
		* @brief: default constructor
        * @param: const uint8_t *const newBytes
		**************************************************/
		Byteable(const uint8_t *const newBytes)
		{ 
			(sizeof(newBytes) == COUNT)
				? std::memmove(this->bytes_, newBytes, COUNT)
				: void(this->bytes_[0] = '\0');
		};
		/*************************************************/

		/************************************************** 
		* Deconstructor 
		* @brief: fill this->bytes_ with random data before deconstruction
		**************************************************/
		~Byteable() { Sanitize(this->bytes_, COUNT); };
		/*************************************************/

		/************************************************** 
		* @brief: returns size of Byteable object
		**************************************************/
		size_t size() const
		{
			return (sizeof(this->bytes_) == COUNT)
					? COUNT
					: 0;
		};
		/*************************************************/

		/************************************************** 
		* @brief: returns vector of stored bytes
		**************************************************/
		const inline std::vector<uint8_t> vBytes() const
		{
			return std::vector<uint8_t>(this->bytes_);
		};
		/*************************************************/

};

#endif

single-header src/types/base/hexable.h



#ifndef HEXABLE_H
#define HEXABLE_H

#include "utilities/platform.h"
#include "utilities/formatting.h"
#include "types/base/byteable.h"
#include <vector>
#include <memory>

template <size_t COUNT>
class Hexable :
		public Printable,
		virtual Byteable<COUNT>
{
	public:
		/************************************************** 
		* Constructor 
		* @brief: default empty constructor
		**************************************************/
		Hexable() { this->bytes_[0] = '\0'; };
		/*************************************************/
		
		/************************************************** 
		* Constructor 
		* @param: const char *const newHash
		* @brief: also checks if Hash is empty before storage
		**************************************************/
		Hexable(const char *const newValue)
		{ 
			(isHex(newValue))
				? void(
					std::memmove(
						this->bytes_,
						&ParseHex(newValue).data()[0],
						COUNT
					)
				)
				: void(this->bytes_[0] = '\0');
		};
		/*************************************************/

		/************************************************** 
		* @brief: returns vector of hex-string representation of stored bytes
		**************************************************/
		const inline std::vector<char> vHex() const
		{
			return (this->bytes_[0] != '\0')
				? std::vector<char>(this->hex().c_str())
				: std::vector<char>(1);
		};
		/*************************************************/

		/**************************************************
		* @brief: return hex-cstring of Hexable type
		**************************************************/
		const char* c_str() const
		{
			return (this->bytes_[0] != '\0')
				? BytesToHex(this->bytes_, this->bytes_ + COUNT).c_str()
				: std::string("").c_str();
		};

		/**************************************************
		* @param: Print& p 
		* @brief: prints Hexable object
		**************************************************/
		virtual size_t printTo(Print& p) const
		{
			size_t size = 0;
			size += p.print( this->c_str() );
			return size;
		};
		/*************************************************/

};

#endif

single-header src/types/crypto/eckey.h



#ifndef ECKEY_H
#define ECKEY_H

#include "utilities/platform.h"
#include "types/base/hexable.h"

/********************************************************************************
* Privatekey: 
* Elliptical Curve SECP256K1 Privatekey (essentially a SHA256 in this instance)
* 32 bytes
* 64 Characters
* @brief Represents a 256-bit number
********************************************************************************/

#define PRIVKEY_STORAGE_BYTE_COUNT 32
#define PRIVKEY_STRING_LENGTH 64

#define Privatekey Hexable<PRIVKEY_STORAGE_BYTE_COUNT>


/********************************************************************************
* Publickey: 
* Elliptical Curve SECP256K1 Compressed Publickey
* ex: "0275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a456"
*
* 33 bytes
* 66 Characters
* @brief Represents a 257-bit number
********************************************************************************/

#define PUBKEY_STORAGE_BYTE_COUNT 33
#define PUBKEY_STRING_LENGTH 66

#define Publickey Hexable<PUBKEY_STORAGE_BYTE_COUNT>


#endif

single-header src/types/crypto/ecsignature.h



#ifndef ECSIGNATURE_H
#define ECSIGNATURE_H

#include "utilities/platform.h"
#include "types/base/hexable.h"

/********************************************************************************
* Signature: 
* Elliptical Curve SECP256K1 Signature
* ex: "3045022100e0fc6b066209fd9a70e61372cda2e38431ace5cf79ee0557eb2b1b14315d70f302201978696b71c9a177fa1ce9480ceb1ad04a15471d4c6e8d5b2dcd6d931f350efe"
*
* 71 bytes
* 142 Characters
********************************************************************************/

#define SIGNATURE_BYTE_COUNT 71
#define SIGNATURE_STRING_LENGTH 142

#define Signature Hexable<SIGNATURE_BYTE_COUNT>


#endif

single-header src/types/address.h



#ifndef ADDRESS_H
#define ADDRESS_H

#include "utilities/platform.h"
#include "utilities/formatting.h"
#include "types/base/byteable.h"
#include <cstring>
#include <memory>

/*******************************************************************************
* address: 
* "DHQ4Fjsyiop3qBR4otAjAu6cBHkgRELqGA"
*   
* 34 Characters | Base58-encoded
* Size 272
* 160-bit base58Encoded hash from a RIPEME160 hash
********************************************************************************/
#define ADDRESS_LENGTH 34		/* Actual Length of Address */
/*************************************************
* Address
**************************************************/
class Address :
		public Printable,
		virtual Byteable<ADDRESS_LENGTH>
{
	public:
		/************************************************** 
		* Constructor 
		* @brief: default empty constructor
		**************************************************/
		Address() {};
		/*************************************************/

		/************************************************** 
		* Constructor 
		* @brief: default constructor
		* @param: const char *const newValue
		**************************************************/
		Address(const char *const newValue)
		{ 
			(strlen(newValue) == ADDRESS_LENGTH)
				? void(std::memmove(this->bytes_, newValue, ADDRESS_LENGTH))
				: void(this->bytes_[0] = { '\0' });
		};
		/*************************************************/

		/************************************************** 
		* @brief: returns cstring representation of stored bytes
		**************************************************/
		const char* c_str() const
		{
			return std::string(
				this->bytes_,
				this->bytes_ + ADDRESS_LENGTH
			).c_str();
		};
		/*************************************************/

		/**************************************************
		* @param: Print& p 
		* @brief: prints Address object
		**************************************************/
		virtual size_t printTo(Print& p) const
		{
			size_t size = 0;
			for (int i = 0; i < ADDRESS_LENGTH; i++)
			{
				size += p.print( this->bytes_[i] );
			};
			return size;
		};
		/*************************************************/

};

#endif

single-header src/types/hash.h



#ifndef ADDRESS_H
#define ADDRESS_H

#include "utilities/platform.h"
#include "utilities/formatting.h"
#include "types/base/byteable.h"
#include <cstring>
#include <memory>

/*******************************************************************************
* address: 
* "DHQ4Fjsyiop3qBR4otAjAu6cBHkgRELqGA"
*   
* 34 Characters | Base58-encoded
* Size 272
* 160-bit base58Encoded hash from a RIPEME160 hash
********************************************************************************/
#define ADDRESS_LENGTH 34		/* Actual Length of Address */
/*************************************************
* Address
**************************************************/
class Address :
		public Printable,
		virtual Byteable<ADDRESS_LENGTH>
{
	public:
		/************************************************** 
		* Constructor 
		* @brief: default empty constructor
		**************************************************/
		Address() {};
		/*************************************************/

		/************************************************** 
		* Constructor 
		* @brief: default constructor
		* @param: const char *const newValue
		**************************************************/
		Address(const char *const newValue)
		{ 
			(strlen(newValue) == ADDRESS_LENGTH)
				? void(std::memmove(this->bytes_, newValue, ADDRESS_LENGTH))
				: void(this->bytes_[0] = { '\0' });
		};
		/*************************************************/

		/************************************************** 
		* @brief: returns cstring representation of stored bytes
		**************************************************/
		const char* c_str() const
		{
			return std::string(
				this->bytes_,
				this->bytes_ + ADDRESS_LENGTH
			).c_str();
		};
		/*************************************************/

		/**************************************************
		* @param: Print& p 
		* @brief: prints Address object
		**************************************************/
		virtual size_t printTo(Print& p) const
		{
			size_t size = 0;
			for (int i = 0; i < ADDRESS_LENGTH; i++)
			{
				size += p.print( this->bytes_[i] );
			};
			return size;
		};
		/*************************************************/

};

#endif

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant