Archive

Author Archive

The State Of Bitcoin

May 23, 2017 2 comments

Well, that’s all fine and dandy for us bitcoiners. What most people that have recently “seen the light” don’t know is that the brutal scaling war going on behind the scenes can tear the price in half (at least) in the near future.

Categories: bitcoin

Encrypting/Decrypting For Confidentiality

May 20, 2017 1 comment

Depending on how they’re designed, there are up to 5 services that a cryptographic system can provide to its users:

In my last post, Hashing For Integrity, we used the Poco.Crypto library to demonstrate how one-way hash functions can provide for message integrity over unsecured communication channels. In this post, we’ll use the library to “Encrypt/Decrypt For Confidentiality“.

The figure below shows how a matched symmetric key/cipher pair provides the service of “confidentiality” to system users. Since they are “symmetric“, the encryption key is the same as the decryption key. Anyone with the key and matching cipher can decrypt a message (or file) that was encrypted with the same key/cipher pair.

The gnarly issue with symmetric key cryptographic sytems is how to securely distribute copies of the key to those, and only those, users who should get the key. Even out-of-band key transfers (via e-mail, snail mail, telephone call, etc) are vulnerable to being intercepted by “bad guys“. The solution to the “secure key distribution” problem is to use asymmetric key cryptography in conjunction with symmetric key cryptography, but that is for a future blog post.

To experiment with symmetric key encryption/decryption using the Poco.Crypto library, we have added a MyCrypto class to the bulldozer00/PocoCryptoExample GitHub repository.

The design of the Poco.Crypto library requires users to create a CipherKey object directly, and then load the key into a Cipher acquired through a CipherFactory singleton.

The MyCipher class data members and associated constructor code are shown below:

After the MyCipher constructor has finished executing, the following CipherKey characteristics appear in the console:

Note that for human readability, the 256 bit key value is printed out as a series of 64, 4 bit hex nibbles.

So, where did we get the “aes-256-cbc” key name from, and are there different key generation algorithms that we could’ve used instead? We got the key name from the openssl library by entering “openssh -h” at the command line:

Using “des-ede” as the key name, we get the following console output after the constructor has finished executing:

The number of bits in a CipherKey is important. The larger the number of bits, the harder it is for the bad guys to crack the system.

So, now that we have a matched CipherKey and Cipher object pair, let’s put them to use to encrypt/decrypt a ClearText message. As you can see below, the Poco.Crypto library makes the implementation of the MyCipher::encryptClearTextMsg() and MyCipher::decryptCipherTextMsg()  member functions trivially simple.

The unit test code that ensures that the ClearText message can be encrypted/decrypted is present in the  MyCipherTest.cpp file:

The console output after running the test is as anticipated:

So, there you have it. In this post we employed the Poco.Crypto library to learn how to use and test the facilities provided by the library to simulate a crypto system that provides its users with confidentiality using encryption/decryption. I hope this post was useful to those C++ programmers who are interested in cryptographic systems and want to get started coding with the Poco.Crypto library.

Categories: C++ Tags:

Hashing For Integrity

May 3, 2017 5 comments

Introduction

Before I discovered the wild and wacky world of Bitcoin, I didn’t pay much attention to cryptography or system security. Those intertwined subject areas, though important, seemed boring to me. Plus, the field is loaded with all kinds of rich, complex, terminology and deep, bit-wise, computationally-intensive, mathematical computations:

Symmetric/Asymmetric key generation algorithms, secure key distribution, private/public key pairs, block and bitstream cipher algorithms: DES, 3DES, AES, Blowfish, encryption by substitution/translation, hashing algorithms for integrity: MD5, RSA, SHA1, SHA2, RIPEMD-160, digital signatures, message digests, confidentiality, authentication, non-repudiation.

But now that I’m a “Bitcoiner“, all these topics suddenly seem interesting to me. Thus, I decided to look for a C++ Crypto library and write some buggy, exploratory, code to learn what the hell is going on.

Out of the gate, I didn’t want to get bogged down or overwhelmed by interfacing directly with the bedrock openssl C library API which underpins most higher level Crypto libraries. I wanted an easier-to-use, abstraction-oriented wrapper library on top of it that would shield me from all of the low level details in openssl

I didn’t have to look far for a nice C++ Crypto library. Poco has a Crypto library. Poco is a well-known, highly polished, set of general purpose, open source libraries/frameworks that is widely deployed across the globe.

The next thing I needed to do was to narrow down the scope of the project. Instead of hacking together some big complicated application, I decided to learn how “hashing achieves message integrity“.

Hashing For Integrity

A hash is a one-way function. When a message, large or small, is sent through a hashing algorithm, the resulting output is NOT an encrypted message that can be decrypted further downstream. It’s a simple, fixed size (in terms of number of bits) value also known as a message “fingerprint“, or “digest“.

Let’s say “I owe you $100” and you want an acknowledgment from me of that fact. I could write it down on paper, sign the note, and give it to you. My signature conveys the fact that I authorized the IOU and it gives the message a degree of integrity.

If you received the note without my signature, I could deny the IOU and I could deny ever sending the note to you. I can even say that you made it up out of thin air to scam $100 from me.

By providing you with an electronic version of the “I owe you $100” note AND a fingerprint in the form of a hash value derived from the content of the note, you could at least verify that the note content is legit and hasn’t been tampered with.

You would do this verification by locally running the note content through the exact same hash function I did, and then comparing your hash value with the fingerprint/digest supplied directly with the note. If they match, then the note is legit. Otherwise, it means that the note was “altered” sometime after I generated the first hash value. Any little change, even a one bit mutation to the message, invalidates the fingerprint derived from the unaltered message. That’s the nature of hashing.

Using Poco::Crypto::SHA1Engine For Hashing

The class diagram in the figure below shows what I needed from the Poco.Crypto library in order to code up and simulate the behavior of a hashing system.

The Poco::Crypto:SHA1Engine class implements the SHA-1 message digest algorithm. (FIPS 180-1, see (http://www.itl.nist.gov/fipspubs/fip180-1.htm) ). Here’s a simple code usage example in which: an engine is created, a message is sent to it, and a hash value is returned:

The following console output from the code shows that the SH1Engine, in its default configuration, generates 160 bit hash values. The SH1Engine::digestToHex() converts the bit pattern into 40, 4bit, nibbles and returns a human-readable hexidecimal string:

The PocoCryptoExample Project

Using the Eclipse CDT, I coded up the design in the class diagram from the previous section. The PocoCryptoExample source tree is available on GitHub here: https://github.com/bulldozer00/PocoCryptoExample. All you have to do is download the source tree, import it into Eclipse as “an existing Eclipse project“, and build the executable using the internal CDT builder (see README.md).

The test driver code that exercises the design (in MessageIntegrityTest.cpp) is as follows:

  1. Initializes the Poco Crypto library (which in turn initializes the openssl library).
  2. Creates the Sender, Recipient, and the I owe you $100” message.
  3. Invokes the Sender to compute the message fingerprint, set the message and fingerprint within a ChannelMessage, and transmit the result to the Recipient.
  4. Upon receipt of the transaction status (success/failure) back from the Recipient, the test driver prints the result to the console.

The test driver then:

  1. Commands the Sender to simulate a man-in-the-middle attack by maliciously changing the message content to You owe me $10,000” and sending a  new ChannelMessage to the Recipient without changing the fingerprint from the prior ChannelMessage.
  2. Upon receipt of the transaction status (success/failure), the test driver prints the result to the console.
  3. Uninitializes the Poco Crypto library (which in turn uninitializes the openssl library) and exits.

Here is the console output produced by the program:

What’s Next?

A next step in the learning process can be to integrate a Poco::Crypto::Cipher class into the design so that message encryption/decryption capability can be added. As you can see from the example code on the Poco Cipher API page, it’s not as easy as adding the SHA1Engine. It is more difficult to create/use a Cipher object because the class depends on the CipherFactory and CipherKey classes.

With those additions, we can simulate sending an encrypted and fingerprinted (integrity AND confidentiality) message to “matchedRecipients who have the same Poco.Crypto objects in their code. A Recipient would then use the SH1Engine to first check that the fingerprint belongs to the message. If the message passes that test, the recipient would then use the Cipher to decrypt the message content.

You know what would be great? If the ISO C++ standards committee added a <crypto> library to the C++ standard library to complement the impressive random number generation and probability distribution functionality available in <random>.

Categories: C++ Tags: ,

Bitcoin Echo Chambers

Categories: bitcoin

Mind-To-Code-To-Mind And Mind-To-Model-To-Code

April 27, 2017 Leave a comment

Since my previous post, I’ve been thinking in more detail about how we manage to move an integrated set of static structures and dynamic behaviors out of our heads and into a tree of associated source code files. A friend of mine, Bill Livingston, coined this creative process as “bridging the gap” across the “Gulf Of Human Intellect” (GOHI).

The figure below shows two methods of transcending the GOHI: direct mind-to-code (M2C), and indirect mind-to-model-to-source (M2M2C). The difference is that M2M2C is scale-able where as M2C is not. Note that both methods are iterative adventures.

Past a certain system size (7 +/- 2 interconnected chunks?), no one can naturally fit a big system model entirely within their head without experiencing mental duress. By employing a concrete model as a “cache” between the mind and the code, M2M2C can give large performance and confidence boosts to the mind. But, one has to want to actively learn how to model ideas in order to achieve these benefits.

From Mind-To-Code (M2C)

How do we grow from a freshly minted programmer into a well-rounded, experienced, software engineer? Do we start learning from the top-down about abstract systems, architecture, design, and/or software development processes? Or do we start learning from the bottom up about concrete languages, compilers, linkers, build systems, version control systems?

It’s natural to start from the bottom-up; learning how to program “hands on“. Thus, after learning our first language-specific constructs, we write our first “Hello World” program. We use M2C to dump our mind’s abstract content directly into a concrete main.cpp  file via an automatic, effortless, Vulcan mind-meld process.

Next, we learn, apply, and remember over time a growing set of language and library features, idioms, semantics, and syntax. With the addition of these language technical details into to our mind space, we gain confidence and we can tackle bigger programming problems. We can now hold a fairly detailed vision of bigger programs in our minds – all at once.

From Mind-To-Model-To-Code (M2M2C)

However, as we continue to grow, we start to yearn of building even bigger, more useful, valuable systems that we know we can’t hold together in our minds – all at once. We turn “upward“, stretching our intellectual capabilities toward the abstract stuff in the clouds. We learn how to apply heuristics and patterns to create and capture design and architecture artifacts.

Thus, unless we want to go down the language lawyer/teacher route, we learn how to think outside of the low level “language space“. We start thinking in terms of “design space“, creating cohesive functional units of structure/behavior and the mechanisms of loosely connecting them together for inter-program and intra-program communication.

We learn how to capture these designs via a modeling tool(s) so we can use the concrete design artifacts as a memory aid and personal navigational map to code up, integrate, and test the program(s). The design artifacts also serve double duty as communication aid for others. Since our fragile minds are unreliable, and they don’t scale linearly, the larger the system (in terms of number of units, types of units, size of units, and number of unit-to-unit interfaces), the more imperative it is to capture these artifacts and keep them somewhat in synch with the fleeting images we are continuously munching on in our mind.

We don’t want to record too much detail in our model because the overhead burden would be too great if we had to update the concrete model artifacts every time we changed a previous decision. On the other hand, we don’t want to be too miserly. If we don’t record “just enough” detail, we won’t be able mentally trace back from the artifacts to the “why?” design decisions we made in our head. That’s the “I don’t know why that’s in the code base or how we got here” syndrome.

A Useful Design Tool

For a modeling tool, we can use plain ole paper sketches that use undecipherable “my own personal notation“, or we can use something more rigorous like basic UML diagrams.

For example, take the static structural model of a simple 3 class design in this UML class diagram:

I reverse-engineered this model out of a small section of the code base in an open source software project. If you know UML, you know that the diagram reads as:

  • A CBlockis aCBlockHeader.
  • A CBlockhas” one or more CTransactionRef objects that it creates, owns, and manages during runtime
  • A CBlockHeaderhas” several data members that it creates, owns, and manages during runtime.

Using this graphic artifact, we can get to a well structured skeleton code base better than trying to hold the entire design in our head at once and then doing that Vulcan mind meld thingy directly to code again.

Using the UML class diagram, I coded up the skeletal structure of the program as three pairs of .h + .cpp files. Some UML tools can auto-generate the code skeletons at the push of a button after the model(s) have been manually entered into the tool’s database. But that would be a huge overkill here.

As a sanity-test, I wrote a main.cpp file that simply creates and destroys an object of each type:

From Mind-To-Model-To-Code: Repeat And Rise

For really big systems, the ephemeral, qualitative, “ilities” and “itys” tend to ominously pop up out of the shadows during the tail end of a lengthy development effort (during the dreaded system integration & testing phases). They suddenly, but understandably, become as important to success as the visible, “functional feature set“.  After all, if your system is dirt slow (low respons-ivity), and/or crashes often (low reliab-ility ), and/or only accommodates half the number of users as desired (low scala-bility), no one may buy it.

So, in summary, we start out as a junior programmer with limited skills:

Then, assuming we don’t stop learning because “we either know it all already or we’ll figure it out on the fly” we start transforming into a more skilled software engineer.

Categories: technical, uml Tags:

The Satoshi Personal Development Process

April 15, 2017 1 comment

A System Of Layers

The ability of the human mind to grasp and understand large, software-intensive, systems is severely constrained by the level of complexity that can be held within its boundaries at once.

One way of reasoning about a large system is to conceptually view it as a layered stack of increasingly abstract, reasonably distinct, entities.

“Each system level provides the context for the level(s) below.” – Unknown

At the top of the stack, we have the System layer: The set of interrelated capabilities and functions that capture the abstract ideas, wants, needs, and expectations for what we want the system to do for us.

The next layer down is the Architecture:  the patterns of structures and behaviors of the set of interconnected elements that comprise the system. Every system has an architecture, whether it is widely known or not.

The third layer down is the Design: the patterns of structures and behaviors of the set of interconnected modules within each architectural element.  Like at the system level, every architecture has a design, whether it is widely known or not.

Finally, at the bottom, where all is scrutably visible, we have the Implementation: the concrete, messy, raw materials (the source code and the hardware) which we create and mold over time to develop, build, integrate, and test, the system. In C++ implementations of a system, the source code is comprised of nested namespaces, classes, functions, and imperative statements stored on files that are compiled and linked together into a set of libraries and executable images deployed on the hardware that ultimately runs the software.

“It’s better to have a partial view of the whole than a complete view of the parts.” – Dave Snowden

When the system switch is flipped on, all the inter and intra connected layers begin an intricate shake-bake dance from which dynamic behaviors emerge to provide perceived value to (at least) some subset of its stakeholders (users, owners, builders, etc).

A System Of Systems

No system exists in a vacuum. Many four layer SADI systems are often inter-connected to provide more value to existing and newly added users. Take the Bitcoin eco-system, for example:

Many L2 systems like the Lightening and Liquid products are under development as we speak. L3 systems – who knows?

A large system can development can start unintentionally from the bottom up, intentionally from the top down, or semi-intentionally from both ends at once via an unknown, creative, iterative, schizophrenic, thinking process.

The Fused Satoshi Layers

If you read Satoshi Nakamoto’s writings, you can get some insight into the thought process he used to birth one of the potentially greatest man-made systems of all time, Bitcoin.

As Satoshi’s quote implies, instead of a neatly stacked, modular, four layer SADI system with crisply defined boundaries and interfaces, he thought about the top 3 “fused” layers for 2 years before hatching the first C++ implementation that ignited a movement intended to crush the existent, corrupt, world-wide banking system.

Other than his groundbreaking white paper, Bitcoin: A Peer-to-Peer Electronic Cash System, it is unknown if he captured/recorded any of his architectural and/or design ideas in writings and drawings like Leonardo daVinci.

Perhaps there seems to be no a-priori diagrams/notes avalailable for the world to marvel at because he kept obsessively massaging, molding, and simulating the top three SAD system layers deep inside his brilliant mind before writing/releasing the first version of the Bitcoin C++ implementation as an open source project for all to see:

Somewhat paradoxically, Satoshi also said that he wrote all the code before hatching the white paper:

So, Satoshi’s personal development process for Bitcoin seems to have been:

  1. Intense, iterative, simulative, thinking at the SAD layers of abstraction for over 2 years (like all brilliantly obsessed innovators do?)
  2. Intensive, iterative, detailed C++ coding at the Implementation level for an unknown period of time.
  3. Writing the white paper after the code was “done“.

Like life, system development is damn messy. Whether you start developing a system to implement a grand vision of yours rigorously from the top down, or haphazardly from the bottom up, you’re likely to get something working. However, you never know what you’re gonna git: 1) an elegant, highly maintainable code base, 2) a kludgy house of cards, or, most likely, 3) a semi-maintainable psuedo-mess in between those two extremes.

So, what’s the point of this post? Hell I don’t know. I just felt like writing it. Since I had no “grand vision” for what I wanted from this post, I started haphazardly from the bottom up and then bounced back and forth between bottom-up writing and top-down thinking until I decided it was “done“. In my day job, where I write C++ software, I always start from the top-down first (unless I’m trying trying to understand/localize/fix a bug in my or a peer’s sprawling code – which is, sadly, most of the time).

How about you? Do you start a new project with “Hello World” coding and pray for guidance from the good lord above to lead you to the promised land, or do you start rustling up and leading those billions of brain cells in your head that are just chomping at the bit to guide you to the holy grail of self-realization?

“The entire system also must have conceptual integrity, and that requires a system architect to design it all, from the top down.” – Fred Brooks

Sloppy Coding II

April 11, 2017 4 comments

Introduction

In the prequel to this post, “Sloppy Coding“, I showed some rather trivial, small-scoped, examples of  antiquated C++ coding style currently present in a hugely successful, widely deployed, open source code base. In this follow up post, I’ll do the same, but at the higher, class level scope.

Hey, I troll often, and this is what trollers do. 🙂

The Class Definition Under Assault

If you’re a young, advancing, C++ programmer, you may want to think about avoiding the bad design decisions that I rag about in the following class definition:

Where Are The Private Members?

After scanning through the class definition for the first time, the most blatantly obvious faux pax I noticed right off the bat was the “everything is public!” violation of the golden rule of encapsulation. If the intent was for CBlockHeader to be a user-defined type with no need to establish and preserve any invariant conditions, then it should have been declared as a less verbose struct .

I know, I know, that’s another nitpick. But there’s more to it than meets the eye. Notice the last three CBlockHeader class member functions are declared const. Since users can directly reach into a skinless CBlockHeader object to mutate its internal state at will, nice users can be unsafely stomped on by cheaters (Jihan Wu? 🙂 ) in between calls.

The cheater gets the 50, and the nice guy gets the goose egg.

Where Are The Initializers?

Notice that the CBlockHeader class constructor does not contain an initialization list – all initialization is performed in the constructor body via a call to SetNull().

An initialization explicitly states that initialization, rather than assignment, is done and can be more elegant and efficient (CppCoreGuidelines). It also prevents “use before set” errors. For a slight performance bump upon each CBlockHeader object instantiation and good C++ style, the struct implementation of the CBlockHeader constructor should look like this, no?

Nasty Pre-processor Hackros, Turtles All The Way Down

Ugh, I don’t even know what to say about the dangerous 1980’s C pre-processor macro bombs planted in the class definition: ADD_SERIAL_METHODS, NCONST_PTR (nested within ADD_SERIAL_METHODS) , and READWRITE. Compared  to the design flaws pointed out previously, these abominations make the class uncomfortably uninhabitable for a large population of otherwise competent C++ programmers.

Bjarne Stroustrup is the creator of C++ and a long time hero of mine. He’s been passionately evolving the language (C With Classes, C++, C++98, C++11, C++14, C++17) and a leading force in the community since the 80s.  Mr. Stroustrup has this to say about Hacros:

A safer, more maintainable, alternative to the current Hack-Horiffic design would be to wrap the required inline functionality in class templates and have CBlockHeader publicly extend those classes. The details are left to the aspiring student.

Fini

Ok, ok. EVERYONE on social media knows that trolls beget trolls. So, troll away at this post. Rip me to shreds. I deserve payback.

%d bloggers like this: