<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>sunnyg.io</title>
      <link>https://sunnyg.io</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://sunnyg.io/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 13 Dec 2014 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Quantum Computer-Proof Digital Signatures, Part 2 - Merkle Signatures</title>
          <pubDate>Sat, 13 Dec 2014 00:00:00 +0000</pubDate>
          <author>Sunny Gonnabathula</author>
          <link>https://sunnyg.io/blog/merkle-signatures/</link>
          <guid>https://sunnyg.io/blog/merkle-signatures/</guid>
          <description xml:base="https://sunnyg.io/blog/merkle-signatures/">&lt;p&gt;In my previous &lt;a href=&quot;https:&#x2F;&#x2F;sunnyg.io&#x2F;blog&#x2F;lamport-signatures&#x2F;&quot;&gt;post&lt;&#x2F;a&gt;, I went over my &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunny-g&#x2F;lamport-merkle.js&quot;&gt;implementation&lt;&#x2F;a&gt; of a quantum-computer-proof digital signature algorithm known as the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lamport_signature&quot;&gt;Lamport signature scheme&lt;&#x2F;a&gt;. We also learned of its greatest weakness: the keypairs can only be used once. While we can&#x27;t change this property of the algorithm, we can mitigate the weakness by chaining multiple Lamport keys together into a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Merkle_tree&quot;&gt;Merkle tree&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keypair-structure&quot;&gt;Keypair Structure&lt;&#x2F;h2&gt;
&lt;p&gt;A Merkle tree is just a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tree_%28data_structure%29&quot;&gt;tree&lt;&#x2F;a&gt; where each node&#x27;s value is the hash of its children&#x27;s values. The top (or root) node has the interesting property of implicitly containing the information of the entire tree since every node&#x27;s value implicitly contains the values of if it&#x27;s children.&lt;&#x2F;p&gt;
&lt;p&gt;So with this in mind, we will start by generating a Lamport keypair for every message we may want to sign with this key tree (the variable &lt;code&gt;keyNum&lt;&#x2F;code&gt;). We then generate the hash of each keypair&#x27;s public key and store these hashes in our tree (along with the keypairs and other useful information like the &lt;code&gt;size&lt;&#x2F;code&gt;, &lt;code&gt;numOfLevels&lt;&#x2F;code&gt; in the tree, and the &lt;code&gt;topHash&lt;&#x2F;code&gt;, which is effectively our key tree&#x27;s public key).&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;var MerkleKeyTree = function(keyNum) {
  this.size = keyNum || KEYNUM;
  this._leaves = [];
  this.usedKeyCount = 0;
  var firstRow = [];
  for (var leafNum = 0; leafNum &amp;lt; this.size; leafNum++) {
    var keypair = new LamportKeypair();
    this._leaves.push(keypair);
    firstRow.push(hash(keypair.pubKey));
  }
  this.levels = [firstRow];

  var levels = Math.ceil(Math.log2(this.size));
  for (var i = 1; i &amp;lt;= levels; i++) {
    &#x2F;&#x2F; for each level in the tree starting w&#x2F; 1 above the bottom
    var curRow = [];
    var prevRow = this.levels[i - 1];
    for (var k = 0; k &amp;lt; prevRow.length; k += 2) {
      &#x2F;&#x2F; for each hash in the previous row
      &#x2F;&#x2F; hash it and the next hash&amp;#39;s values
      var h = hash(prevRow[k] + prevRow[k + 1]);
      curRow.push(h);
    }
    this.levels[i] = curRow;
  }

  this.numOfLevels = this.levels.length;
  this.numOfKeys = this._leaves.length;
  this.topHash = this.levels[this.levels.length - 1][0];
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So here&#x27;s what the Merkle tree in our key tree looks like, with each array containing the hashes of its two child hashes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;..&#x2F;attachments&#x2F;2014-12-13-merkle-tree.png&quot; alt=&quot;A sample Merkle key tree&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;message-signing&quot;&gt;Message Signing&lt;&#x2F;h2&gt;
&lt;p&gt;To use this tree to sign a message, we have to:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Select a keypair (&lt;code&gt;leaf&lt;&#x2F;code&gt;) and use it to generate a signature.&lt;&#x2F;li&gt;
&lt;li&gt;Publish the signature, along with the path of hashes at each level necessary to recreate the &lt;code&gt;topHash&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We must publish the path so that once the user verifies that the Lamport keypair we used was legitimate, they can hash the public key + sibling public key, and continue hashing these hashes + their siblings until they reach the &lt;code&gt;topHash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;MerkleKeyTree.prototype.sign = function(msg) {
  var finalSig = {};
  if (this.usedKeyCount === this.size - 1) {
    throw new Error(&amp;#39;This is your last keypair on this tree);
  }
  &#x2F;&#x2F; select the first unused keypair
  for (var i = 0; i &amp;lt; this.numOfKeys; i++) {
    if (!this._leaves[i].used) {
      var randomKeypair = this._leaves[i];
      var randomKeypairIndex = i;
      break;
    }
  }
  finalSig.keyPairId = randomKeypairIndex;
  finalSig.pubKey = randomKeypair.pubKey;
  finalSig.message = msg;
  finalSig.signature = randomKeypair.sign(msg);
  &#x2F;&#x2F; create the path of the hashes needed to get from the
    &#x2F;&#x2F; published keypair to the topHash
  finalSig.path = [];
  var curLevel = 0;
  var idx = randomKeypairIndex;
  while (curLevel &amp;lt; this.numOfLevels) {
    if (idx % 2) {
      finalSig.path.push(this.levels[curLevel][idx - 1])
    } else {
      finalSig.path.push(this.levels[curLevel][idx + 1])
    }
    curLevel++;
    idx = parentIdx(idx);
  }
&#x2F;&#x2F; publish the signature, set key properties
  finalSig.path[finalSig.path.length - 1] = this.topHash;
  randomKeypair.used = true;
  this.usedKeyCount++;
  return finalSig;
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s an example signature of a message signed by the key tree above:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;..&#x2F;attachments&#x2F;2014-12-13-merkle-sig.png&quot; alt=&quot;A sample signature&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;message-verification&quot;&gt;Message Verification&lt;&#x2F;h2&gt;
&lt;p&gt;To verify a signature, we must first verify &lt;code&gt;signature&lt;&#x2F;code&gt; against &lt;code&gt;pubKey&lt;&#x2F;code&gt;, just as we would with a traditional Lamport key. Then, we&#x27;ll have to hash the &lt;code&gt;pubKey&lt;&#x2F;code&gt; and hash the result (in the right order) with its sibling key&#x27;s hash, and keep taking the output and hashing it with its sibling in the next level of the key tree until we end up with one, lone hash.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;MerkleKeyTree.prototype.verify = function (sigObj) {
  var idx = sigObj.keyPairId;
  var lamport = this._leaves[idx];
  &#x2F;&#x2F; if this is a valid Lamport signature...
  if (lamport.verify(sigObj.message, sigObj.signature)) {
    &#x2F;&#x2F; ... calculate the sibling hashes until you reach the topHash
    var h = hash(sigObj.pubKey);
    for (var i = 0; i &amp;lt; sigObj.path.length - 1; i++) {
      var auth = sigObj.path[i];
      if (idx % 2) {
        h = hash(auth + h);
      } else {
        h = hash(h + auth);
      }
      idx = parentIdx(idx); &#x2F;&#x2F; gets the parent level hash index
    }
    if (h === sigObj.path[sigObj.path.length - 1]) {
      return true;
    }
  }
  return false;
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If at the end of this process we end up with the string at the end of our &lt;code&gt;path&lt;&#x2F;code&gt; array (which is also our &lt;code&gt;topHash&lt;&#x2F;code&gt;), we&#x27;ll know that the key used to sign the message belongs to this key tree and this &lt;code&gt;topHash&lt;&#x2F;code&gt; (which should match up with the &lt;code&gt;topHash&lt;&#x2F;code&gt; of the expected owner and message signer).&lt;&#x2F;p&gt;
&lt;p&gt;In conclusion, with this signature scheme, we&#x27;ve allowed a user to generate one large key tree that can be used to sign arbitrarily many messages (including newer keytrees) while only marginally increasing the signature size. While this can&#x27;t be used for secretly encrypting messages, in many applications (e.g. authenticating cryptocurrency transactions), a signature scheme is just enough.&lt;&#x2F;p&gt;
&lt;p&gt;I hope both of these posts have shed some light on how wild yet understandable some cryptographic concepts can be. You can always check out my repo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunny-g&#x2F;lamport-merkle.js&quot;&gt;here&lt;&#x2F;a&gt; and as always, thanks for reading!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Quantum Computer-Proof Digital Signatures, Part 1 - Lamport Signatures</title>
          <pubDate>Sun, 07 Dec 2014 00:00:00 +0000</pubDate>
          <author>Sunny Gonnabathula</author>
          <link>https://sunnyg.io/blog/lamport-signatures/</link>
          <guid>https://sunnyg.io/blog/lamport-signatures/</guid>
          <description xml:base="https://sunnyg.io/blog/lamport-signatures/">&lt;p&gt;For my MVP (minimal viable product) project at &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;hackreactor.com&quot;&gt;Hack Reactor&lt;&#x2F;a&gt;, I developed a browser &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunny-g&#x2F;lamport-merkle.js&quot;&gt;library&lt;&#x2F;a&gt; that implements two quantum-computer-proof digital signature algorithms known as the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lamport_signature&quot;&gt;Lamport&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Merkle_signature_scheme&quot;&gt;Merkle signature schemes&lt;&#x2F;a&gt;. In this post, I&#x27;ll be going over the Lamport scheme and how it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keypair-structure&quot;&gt;Keypair Structure&lt;&#x2F;h2&gt;
&lt;p&gt;Unlike keypairs of traditional encryption algorithms, Lamport keys are not mathematically tied to one another nor are they derived from hard-to-solve problems like prime factorization (this is in fact the reason this algorithm is quantum computer-proof: so long as our secure hashing function can&#x27;t have solving its inverse optimized by quantum computing, we should be safe). Our private key then is simply composed of 256 pairs of 32 byte numbers while the public key is made up of the hashes of each number:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;var LamportKeypair = function() {
  this._privKey = [];
  this.pubKey = [];
  this.used = false;

  for (var i = 0; i &amp;lt; 256; i++) {
    var num1 = random32ByteString();
    var num2 = random32ByteString();
    var hash1 = hash(num1);
    var hash2 = hash(num2);

    this._privKey.push([num1, num2]);
    this.pubKey.push([hash1, hash2]);
  }
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;message-signing&quot;&gt;Message Signing&lt;&#x2F;h2&gt;
&lt;p&gt;To sign a message with this key, we only have to do two things:&lt;&#x2F;p&gt;
&lt;p&gt;Generate a 32 byte (256 bit) hash of the message.
For each bit in the message, publish either the 1st or 2nd random number of that bit&#x27;s corresponding pair of numbers within our private key.
These steps end up looking like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;LamportKeypair.prototype.sign = function(msg) {
  var msgHash = hash(msg);
  var signature = [];

  var that = this;
  &#x2F;&#x2F; this iterates over every bit in a hash string
  &#x2F;&#x2F; callback takes the bit and its index in the string
  eachBit(msgHash, function(bit, bitIdx) {
    signature.push( that._privKey[bitIdx][bit] );
  });
  return signature;
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But wait, if we publish the numbers in our private key, doesn&#x27;t that defeat the purpose of making it private?&lt;&#x2F;p&gt;
&lt;p&gt;Well yes, and this highlights the usability weakness of this signature scheme: we can only use each keypair once. The workaround for this is to incorporate multiple keys into a Merkle tree, but that&#x27;s a topic for a later post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;message-verification&quot;&gt;Message Verification&lt;&#x2F;h2&gt;
&lt;p&gt;To verify the message, all we need to do now is check to see that every number in our signature hashes to one of the values in its corresponding pair in our public key:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;LamportKeypair.prototype.verify = function(msg, signature) {
  var msgHash = hash(msg);
  var authentic = true;

  var that = this;
  eachBit(msgHash, function(bit, bitIdx) {
    if (hash(signature[bitIdx]) !== that.pubKey[bitIdx][bit]) {
      authentic = false;
    }
  });
  return authentic;
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;why-this-works&quot;&gt;Why This Works&lt;&#x2F;h1&gt;
&lt;p&gt;To be a valid digital signature algorithm, we have to satisfy one main condition (and maybe a few others that I&#x27;m forgetting): &lt;em&gt;the public key cannot leak any information about the private key&lt;&#x2F;em&gt;. Since our public key only contains the hashes of these random numbers (and since hash functions can&#x27;t be run in reverse, that is, from a hash tell us the input), we satisfy that condition and can now know with certainty one thing: &lt;strong&gt;the only person who could have published the numbers in the signature and the hashes in the public key is the same person who possessed all of the random numbers of the private key in the first place.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I hope this post has piqued your interest in non-traditional encryption schemes; I have a &lt;a href=&quot;https:&#x2F;&#x2F;sunnyg.io&#x2F;blog&#x2F;merkle-signatures&#x2F;&quot;&gt;companion post&lt;&#x2F;a&gt; about how Merkle trees can mitigate the one-time-expiry property of Lamport signatures. If you want to check out my repo, you can find it (and star it hopefully?) &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunny-g&#x2F;lamport-merkle.js&quot;&gt;here&lt;&#x2F;a&gt;. Thanks for reading!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>IP Addressing (and a segue into CJDNS)</title>
          <pubDate>Tue, 18 Nov 2014 00:00:00 +0000</pubDate>
          <author>Sunny Gonnabathula</author>
          <link>https://sunnyg.io/blog/ip-addressing/</link>
          <guid>https://sunnyg.io/blog/ip-addressing/</guid>
          <description xml:base="https://sunnyg.io/blog/ip-addressing/">&lt;p&gt;In this post, I&#x27;ll be lightly elaborating on a 5-minute talk I&#x27;ve yet to give to my classmates at &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.hackreactor.com&#x2F;&quot;&gt;Hack Reactor&lt;&#x2F;a&gt;. We&#x27;ll start with IPv4 addresses, their format and what&#x27;s known as address exhaustion before going over the advantages to the new IPv6 address format and finishing with an overview into &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cjdelisle&#x2F;cjdns&quot;&gt;CJDNS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ipv4&quot;&gt;IPv4&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;thumb&#x2F;7&#x2F;74&#x2F;Ipv4_address.svg&#x2F;500px-Ipv4_address.svg.png&quot; alt=&quot;ipv4 byte scheme&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;IPv4 addresses are composed of 4 sections of 8-bit numbers, giving us an address space of (2^8)^4 addresses, or for those who don&#x27;t speak in exponentials, a maximum of 4,294,967,296 unique addresses. However, the amount actually addressable to individual devices is far less since many of these are (by convention) inaccessible or reserved for other uses.&lt;&#x2F;p&gt;
&lt;p&gt;For example, some addresses were allocated to some big companies of the 90&#x27;s, such as Xerox, Apple and Halliburton. Other addresses and address spaces, were allocated for future private use. Two such addresses are http:&#x2F;&#x2F;127.0.0.0 and http:&#x2F;&#x2F;127.0.0.1 and are known as the loopback addresses, only accessible locally on your computer or server (hence the more common URL, http:&#x2F;&#x2F;localhost).&lt;&#x2F;p&gt;
&lt;p&gt;There are some ranges reserved for &quot;private networks,&quot; some of which you might recognize as your router&#x27;s IP address (192.168.0.1, 10.0.0.1 or 172.16.0.0). By giving routers a unique global address (and giving their connected devices a derivative address from one of the three private network address spaces listed above), we&#x27;ve been able to mitigate this address space exhaustion issue and avoid its implications. But considering there may be as many 16 billion internet-connected devices by the end of 2014, even this scheme will have to come to an end.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ipv6&quot;&gt;IPv6&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;http:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;thumb&#x2F;1&#x2F;15&#x2F;Ipv6_address.svg&#x2F;500px-Ipv6_address.svg.png&quot; alt=&quot;ipv6 byte scheme&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The next iteration of IP addressing is known as IPv6 and makes quite a large change to their format. They are composed of 8 groups of 4 hexadecimal characters, giving us an address space of (16^4)^8 == 2^128, or 3.402 e38 addresses. Interestingly enough, this scheme was named in 1995, meaning that this problem was not only forseen almost 20 years ago, but it hasn&#x27;t reached significant adoption. But this brings me to my next point and what I really want to talk about...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cjdns&quot;&gt;CJDNS&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cjdelisle&#x2F;cjdns&quot;&gt;CJDNS&lt;&#x2F;a&gt; is an open-source, p2p encrypted meshnetting software and protocol whose developers aim make it the backbone of a new, NSA-proof internet (a goal that, while very, very lofty, might actually be accomplished at some point in the future).&lt;&#x2F;p&gt;
&lt;p&gt;Although it&#x27;s use constitutes a separate, otherwise inaccessible-to-the-rest-of-the-world internet, I included it here in this post because it does something very interesting: it assigns unique IPv6 addresses to all of it&#x27;s nodes from the get-go.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;3.bp.blogspot.com&#x2F;-5swPB9xcxfg&#x2F;VIiAnVbe4NI&#x2F;AAAAAAAANRs&#x2F;lpGBkKiNeRE&#x2F;s1600&#x2F;1-tutorial-osi-7-layer-model.gif&quot; alt=&quot;OSI Model&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On what we know as the World Wide Web, traffic can be encrypted between a browser and server on the presentation layer of the OSI Model using the SSL protocol, which is now used almost everywhere. However, there are some weaknesses with SSL (excluding &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;heartbleed.com&#x2F;&quot;&gt;bugs&lt;&#x2F;a&gt; in some of its various implementations), namely the required existence of trusted third-parties.&lt;&#x2F;p&gt;
&lt;p&gt;Rather than resort to this layer for encrypting traffic, CJDNS operates and encrypts on the IP layer, just above the two layers responsible for actually carrying and delivering internet traffic. In effect, CJDNS completely hijacks and rewrites the book on how IP-layer traffic and routing work and the responsibilities they should inherit.&lt;&#x2F;p&gt;
&lt;p&gt;What&#x27;s even more interesting is the fact that the addresses themselves are the hash of the public keys used to encrypt the packets sent between any two nodes. This means that you can always be certain that the address you are communicating with is responsible for the encryption of the traffic you receive from them and that the traffic has not been man-in-the-middled; who that user is and whether or not you can trust them is unfortunately a completely different question.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m going to end this post here, but will continue this line of thought in another post in the near future, and will hopefully be connected to its most popular intranet known as Hyperboria; if so, I&#x27;ll be sure to leave a tutorial for getting started with this super-cool software.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
