This video is free to watch - hope you enjoy it! If you like what you see, there's a ton more where that came from...

# Hashing and Asymmetric Encryption

In this video we dive into hashing algorithms, how they're used and what they're good (and not so good) for. We'll also dig into RSA, one of the most important pieces of software ever created.

This is premium content - you can own it in just 30 seconds!

I’ve used hashes for a long time and had a general understanding of what they do… but that’s about it. I knew I needed to hash passwords (and other secure data) if I was going to store them in my database… but that’s about all.

I was never sure which algorithms to use nor why… so I dug in and found out. That’s the first part of this video.

The second is asymmetric encryption: encoding with a public key and decoding with a second, private key. Absolutely ground-breaking idea! The math is amazingly straightforward too… although I will admit to struggling to explain some of it.

## The Code

To produce a simple hash using Node:

``````const crypto = require("crypto");

const hash = crypto.createHash("sha256")
.update("hi")
.digest("hex");

console.log(hash);
``````

Hashing a password with PBKDF2 using a million rounds to slow things down:

``````const crypto = require("crypto");

return new Promise(function(resolve, reject){
crypto.pbkdf2(pw,"super-secret-salt",1000000,32,"sha512", function(err, buffer){
if(err) reject(err);
else resolve(buffer.toString("hex"))
});
})
}

``````

Hashing using scrypt, assigning a cost:

``````const hashPassword = function(pw){
return new Promise(function(resolve, reject){
crypto.scrypt(pw,"super-secret-salt",32, {cost: 2**14}, function(err, buffer){
if(err) reject(err);
else resolve(buffer.toString("hex"))
});
})
}
``````

Creating a checksum using MD5:

``````const crypto = require("crypto");
const fs = require("fs");

const checksum = function(data){
return crypto.createHash("md5").update(data, "utf8").digest("hex")
}

console.log(checksum(data));
``````

A super-simple mining operation (meant for demonstration only) for blockchain stuff:

``````const crypto = require("crypto");

const createHash = (block) => {
//need to pass a string to our
const hashValue = JSON.stringify(block)
return crypto.createHash("sha256")
.update(hashValue)
.digest("base64");
}

const mine = (block, difficulty = 2) => {
let found = false, start = new Date().getTime();
//we're looking for a string of 0s so let's create the pattern
//I could use Regex but I'm not that good
console.log("Looking for a hash starting with", lookingFor);
const duration = new Date().getTime() - start;

while(!found){
const possibleHash = createHash(block);
found = possibleHash.substring(0, difficulty) === lookingFor;
if(found){
block.hashKey = possibleHash;
return block;
}
block.nonce += 1;
//10 second kill switch
if(duration > 10000) return "Didn't find it under 10s"
}
}

const block = {
transactions: [
{from: "me", to: "you", amount: 10.00},
{from: "you", to: "me", amount: 5.00}
],
timestamp: 1609702546153, //if this changes the hash changes
nonce: 0,
previousKey: "00RSDThMVcQAvoocD3klO/6pjJ4a8pRbZ3ykk3XXhXE="
}
//let's see how long this takes
const start = new Date().getTime();
//let's do it!
const result = mine(block, 4);
const duration = new Date().getTime() - start;
console.log(`That took duration \${duration}ms`);
console.log(result);
``````

And finally, our trip through the basics of RSA using super small primes:

``````//resources
//https://www.cs.drexel.edu/~jpopyack/IntroCS/HW/RSAWorksheet.html
//https://www.cryptool.org/en/cto/highlights/rsa-step-by-step
//let's find two relatively prime numbers, e and d, such that
//e % d mod r === 1
//this is the cornerstone of RSA
var findEandD = function(r) {
//These are common candidates for e, which can be autoset
//and typically 65537 is used, but we'll
//start small for speed
const possibleEs = [3n,5n,17n,257n,65537n]
//now, loop over the possible e's so we can find our d
for(let e of possibleEs){
//we want to find a coprime for e, so let's factor it
//up to r and see if e % r is 1
//if it is, we found our coprime
for (let d = 1n; d < r; d++) {
const candidate = e * d;
if (candidate % r == 1n) return {e: e, d: d};
}
}
assert.fail("We shouldn't reach this point")
}

const p = 499n;
const q = 491n;
assert.notStrictEqual(p,q, "p and q must be different primes");

//our public key, N
const N = p * q;

//Euler's totient for deriving r
//r = phi(n) = (p-1) * (q-1)
const r = (p-1n) * (q-1n);

//now we can calculate e and d for our private key
const {e,d} = findEandD(r);

//our message
const M = 25n;

console.log("e",e);
console.log("d",d);
console.log("N",N);
console.log("r",r);

console.log("M", M);

//the RSA algorithm
const encrypted = M**e % N;
const decrypted = encrypted**d % N;

console.log("Encrypted",encrypted);
console.log("Decrypted",decrypted);
``````

I cite a number of articles in this video - hard not to. But here they are if you want to read more:

## The Code

Code for this video (and for the entire series) can be found in the production GitHub repo.

• ### The Basics of Logic

Let’s jump right in at the only place we can: the very begining, diving into the perfectly obvious and terribly argumentative 'rules of logic'.

• ### Boolean Algebra

You're George Boole, a self-taught mathematician and somewhat of a genius. You want to know what God's thinking so you decide to take Aristotle's ideas of logic and go 'above and beyond' to include mathematical proofs.

• ### Binary Mathematics

This is a famous interview question: 'write a routine that adds two positive integers and do it without using mathematic operators'. Turns out you can do this using binary!

• ### Bitwise Operators

Up until now we've been representing binary values as strings so we could see what's going on. It's time now to change that and get into some real binary operations.

• ### Logical Negation

We've covered how to add binary numbers together, but how do you subtract them? For that, you need a system for recognizing a number as negative and a few extra rules. Those rules are one's and two's complement.

• ### Entropy and Quantifying Information

Now that we know how to use binary to create switches and digitally represent information we need to ask the obvious question: 'is this worthwhile'? Are we improving things and if so, how much?

• ### Encoding and Lossless Compression

Claude Shannon showed us how to change the way we encode things in order to increase efficiency and speed up information trasmission. We see how in this video.

• ### Correcting Errors in a Digital Transmission, Part 1

There are *always* errors during the transmission of information, digital or otherwise. Whether it's written (typos, illegible writing), spoken (mumbling, environment noise) or digital (flipped bits), we have to account for and fix these problems.

• ### Correcting Errors in a Digital Transmission, Part 2

In the previous video we saw how we could correct errors using parity bits. In this video we'll orchestrate those bits using some math along with a divide and conquer algorithm to correct single-bit errors in transmissions of any size.

• ### Encryption Basics

In this video we play around with cryptography and learn how to encrypt things in a very simple, basic way. We then ramp up our efforts quickliy, creating our own one-time pad and Diffie-Hellman secure key transmitter.

• ### Hashing and Asymmetric Encryption

In this video we dive into hashing algorithms, how they're used and what they're good (and not so good) for. We'll also dig into RSA, one of the most important pieces of software ever created.

• ### Functional Programming

Functional programming builds on the concepts developed by Church when he created Lambda Calculus. We'll be using Elixir for this one, which is a wonderful language to use when discovering functional programming for the first time

• ### Lambda Calculus

Before their were computers or programming languages, Alonzo Church came up with a set of rules for working with functions, what he termed lambdas. These rules allow you to compute anything that can be computed.

• ### Database Normalization

How does a spreadsheet become a highly-tuned set of tables in a relational system? There are rules for this - the rules of normalization - which is an essential skill for any developer working with data

• ### Big O Notation

No video with this one - just a post with lots of code for quick review. Understanding Big O has many real world benefits, aside from passing a technical interview. In this post I'll provide a cheat sheet and some real world examples.

• ### Arrays and Linked Lists

The building block data structures from which so many others are built. Arrays are incredibly simple - but how much do you know about them? Can you build a linked list from scratch?

• ### Stacks, Queues and Hash Tables

You can build all kinds of things using the flexibility of a linked list. In this video we'll get to know a few of the more common data structures that you use every day.

• ### Trees, Binary Trees and Graphs

The bread and butter of technical interview questions. If you're going for a job at Google, Microsoft, Amazon or Facebook - you can be almost guaranteed to be asked a question that used a binary tree of some kind.

• ### Basic Sorting Algorithms

You will likely *never* need to implement a sorting algorithm - but understanding how they work could come in handy at some point. Interviews and workarounds for framework problems come to mind.

• ### DFS, BFS and Binary Tree Search

You now know all about trees and graphs - but how do you use them? With search and traversal algorithms of course! This is the next part you'll need to know when you're asked a traversal question in an interview. And you will be.

• ### Dynamic Programming and Fibonnaci

Dynamic programming gives us a way to elegantly create algorithms for various problems and can greatly improve the way you solve problems in your daily work. It can also help you ace an interview.

• ### Calculating Prime Numbers

The use of prime numbers is everywhere in computer science... in fact you're using them right now to connect to this website, read your email and send text messages.

• ### Graph Traversal: Bellman Ford

How can you traverse a graph ensuring you take the route with the lowest cost? The Bellman-Ford algorithm will answer this question.

• ### Graph Traversal: Djikstra

Bellman-Ford works well but it takes too long and your graph can't have cycles. Djikstra solved this problem with an elegant solution.

• ### Design Patterns: Creational

Tried and true design patterns for creating objects in an object-oriented language.

• ### Design Patterns: Structural

As your application grows in size you need to have a plan to handle the increase in complexity. The Gang of Four have some ideas that could work for you.

• ### Design Patterns: Behavioral

Mediators, Decorators and Facades - this is the deep end of object-oriented programming and something you'll come face to face with as your application grows.

• ### Principles of Software Design

You've heard the terms before: YAGNI, SOLID, Tell Don't ASK, DRY... what are they and what do they mean?

• ### Testing Your Code: TDD and BDD

Testing code has moved beyond the realm of QA and into the realm of design, asking you to think about what you do before you do it. Let's have a look at some strategies.

• ### Shell Script Basics

It's a Unix world. You should have a functional knowledge of how to get around a Unix machine using the command line, as well as how to complete basic tasks using shell scripts and Make files.

• ### Hands On: Creating a Useful Shell Script

I use the static site generator Jekyll to write my blog. I store the site at Github, who then translates and hosts it all for me for free. Jekyll is simple to use and I like it a lot. There's only one problem: it's a bit manual.

• ### Deciphering a Complex Bash Script

I use the static site generator Jekyll to write my blog. I store the site at Github, who then translates and hosts it all for me for free. Jekyll is simple to use and I like it a lot. There's only one problem: it's a bit manual.

• ### Making Your Life Easier with Make

Make is a build utility that works with a file called a Makefile and basic shell scripts. It can be used to orchestrate the output of any project that requires a build phase. It's part of Linux and it's easy to use.

• ### Using Make to Improve Your Test Suite

No video with this one - just a post with lots of code. Make has been around forever and is often overlooked in favor of tools that recreate precisely what it does, but in crappier ways. Let's see how you can use Make to help your testing process.

[[prev.summary]]

[[next.summary]]