<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: librehash</title>
    <description>The latest articles on Forem by librehash (@librehash).</description>
    <link>https://forem.com/librehash</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F233472%2Fdeb3bac1-b210-4da2-9b34-66b99b3b13a4.png</url>
      <title>Forem: librehash</title>
      <link>https://forem.com/librehash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/librehash"/>
    <language>en</language>
    <item>
      <title>Deploying Firecracker VMs</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Wed, 05 Oct 2022 23:47:41 +0000</pubDate>
      <link>https://forem.com/librehash/deploying-firecracker-vms-1d99</link>
      <guid>https://forem.com/librehash/deploying-firecracker-vms-1d99</guid>
      <description>&lt;p&gt;GitHub URL for the project - &lt;a href="https://github.com/firecracker-microvm/firecracker" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt; - "&lt;em&gt;Secure and fast microVMs for serverless computing&lt;/em&gt;." &lt;/p&gt;

&lt;p&gt;Also - "&lt;em&gt;Firecracker is an open source virtualization technology that is purpose-built for creating and managing secure, multi-tenant container and function-based services that provide serverless operational models. Firecracker runs workloads in lightweight virtual machines, called microVMs, which combine the security and isolation properties provided by hardware virtualization technology with the speed and flexibility of containers&lt;/em&gt;." &lt;/p&gt;

&lt;h3&gt;
  
  
  More on the Project
&lt;/h3&gt;

&lt;p&gt;Written in Rust (that's a delectable plus). Looks like this was actually created by Amazon, I believe (still open source ; relax Pedro). &lt;/p&gt;

&lt;p&gt;Yup, confirmed within the Git repo - "Firecracker was developed at Amazon Web Services to accelerate the speed and efficiency of services like AWS Lambda and AWS Fargate. Firecracker is open sourced under Apache version 2.0."&lt;/p&gt;

&lt;p&gt;The VM operates with a VMM (virtual machine monitor), which leverages the KVM (Linux) to create &amp;amp; run 'microVMs'. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The virtualized environments are designed to be secure by default (according to the project specs); this is done by "[excluding] unnecessary devices and guest-facing functionality to reduce the memory footprint and attack surface area of each microVM". &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firecracker can be integrated with other container runtimes like 'Kata Containers' (this is another project that we're going to get to in a second)  + 'Weaveworks Ignite' (fuck them) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;More information on the project can be found here - &lt;a href="https://firecracker-microvm.github.io/" rel="noopener noreferrer"&gt;https://firecracker-microvm.github.io/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More Helpful Info About the Project&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Supports all modern processor types pretty much ; Intel / AMD / ARM (last one is a present surprise as well) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is built w security in mind in its design (via the minimalism of the VM creation); also, its meant to isolate VM instances entirely from the actual OS / root system in a manner that plugs up leaks pretty comprehensively. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  More on the Inner Workings of 'FireCracker'
&lt;/h3&gt;

&lt;p&gt;Below is a picture from the main site that the project claims illustrates an "example host running Firecracker microVMs". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndc7lmz9juj4w2e06em8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndc7lmz9juj4w2e06em8.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Claim that the VMs use so little resources that one could plausibly "run thousands of microVMs onto the same machine" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"This means that every function, container, or container group can be encapsulated with a virtual machine barrier, enabling workloads from different customers to run on the same machine, without any tradeoffs to security or efficiency" (okay! this is a pretty big claim, but I like it ; would like to see the 3rd-party evaluations of how much this project adheres to that promise in practice) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Each Firecracker microVM is further isoalted with common Linux user-space security barriers by a companion p rogram called 'jailer'"; 'the jailer provides a second line of defense in case the virtualization barrier is ever compromised' (so they're really gun-ho on the idea that the VMs constructed with this tool are of a caliber capable of preventing any and all 'escapes' / 'leaks' from the VMs [people will always try to find a way though] &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"The Firecracker VMM is built to be processor agnostic. Intel processors are supported for production workloads" (that last statement implies that this project is only built for Intel in any practical sense) ; especially with the follow-up that, "Support for AMd and ARM processors is in 'developer preview'" (what's that?) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The virtualization software that they most closely compare this tool to is 'QEMU' (which is fucking amazing, I will accept &lt;strong&gt;zero slander on QEMU ever or on the developer - Fabian - that created QEMU virtualization because he's a fucking genius when you look at what he's managed to do&lt;/strong&gt;) &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a 'gaggle' of projects that are also able to run 'Firecracker'. Those are (from the website): &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;'Appfleet' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'firecracker-containerd' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'fly.io' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'koyeb' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'kata containers' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'OpenNebula' (used this a couple of times; wasn't a huge fan of it although it was easy to setup at the time) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'Qovery' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'UniK' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;'Weave FireKube' + 'Ignite' &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Actually Deploy Firecracker
&lt;/h3&gt;

&lt;p&gt;Wasn't even going to get this fire down the rabbit hole, but these folks tempted me - so here goes nothing. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;**"You can build Firecracker on any Unix/Linux system that has Docker running and 'bash' installed" (using the following code):&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/firecracker-microvm/firecracker
&lt;span class="nb"&gt;cd &lt;/span&gt;firecracker
tools/devtool build
&lt;span class="nv"&gt;toolchain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-unknown-linux-musl"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, "&lt;em&gt;The Firecracker binary will be placed at build/cargo_target/${toolchain}/debug/firecracker. For more information on building, testing, and running Firecracker, go to the quickstart guide.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Start Guide&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Start Guide &amp;amp; Instructions Once the Initial Build + Installation Code Has Been Run
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Firecracker uses KVM and needs read/write access that can be granted as shown below&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;setfacl &lt;span class="nt"&gt;-m&lt;/span&gt; u:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:rw /dev/kvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also need to ensure that the user running the VMs has "read write access to '/dev/kvm'" &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Directions on How to Set Up Read/Write Access to /dev/kvm&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md#appendix-a-setting-up-kvm-access" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md#appendix-a-setting-up-kvm-access&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Firecracker is linked statically against musl, having no library dependencies. You can just download the latest binary from our release page, and run it on your x86_64 or aarch64 Linux machine.&lt;/em&gt;" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Once the firecracker binary has been downloaded [instructions above], we just need to ensure that we've moved the binary into &lt;code&gt;/usr/bin&lt;/code&gt; so that we can use it liberally in CLI) &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Additionally, here's a 'building from the source section&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md#building-from-source" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md#building-from-source&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Running Firecracker
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"&lt;em&gt;In production, Firecracker is designed to be run securely, inside an execution jail, carefully set up by the jailer binary. This is how our integration test suite does it. However, if you just want to see Firecracker booting up a guest Linux machine, you can do that as well.&lt;/em&gt;" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;We need to first obtain an "uncompressed Linux kernel binary, and an ext4 file system image (to use as rootfs)" ; great, these are two things that we need to seek out before we move forward in our 'adventure' (&lt;em&gt;this really feels like a "quest" of some sort, like the ones that they forced you to play on Runescape back in the days&lt;/em&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to Decompress Linux Kernel&lt;/strong&gt; (explicit instructions to be honest here) - &lt;a href="https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-5.html" rel="noopener noreferrer"&gt;https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-5.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linux-Hardened Kernel&lt;/strong&gt; - &lt;a href="https://github.com/anthraxx/linux-hardened" rel="noopener noreferrer"&gt;https://github.com/anthraxx/linux-hardened&lt;/a&gt; (this is something that they're all still actively working on at this very point in time) &lt;/p&gt;

&lt;p&gt;They also say that we need an 'ext4 file system image' (where do we obtain this from?) - found it &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full Guide on How to Create an EXT4 filesystem image here&lt;/strong&gt; -&lt;a href="https://fabianlee.org/2020/01/13/linux-mounting-a-loopback-ext4-xfs-filesystem-to-isolate-or-enforce-storage-limits/" rel="noopener noreferrer"&gt;https://fabianlee.org/2020/01/13/linux-mounting-a-loopback-ext4-xfs-filesystem-to-isolate-or-enforce-storage-limits/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Assuming that the above has been handled, the directions insist that we create two separate shell prompts, (one to run Firecracker, and another one to control it [by writing to the API socket]; both shells have to run "in the same directory where the firecracker binary was placed")&lt;/p&gt;

&lt;p&gt;^^ What? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This is a pain in the ass because this is something that they should've mentioned earlier (obv. everyone is going to move a binary where the rest of their binaries go ; and you're not going to just load up some random project to be used in that manner) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not even sure what the end goal of opening up an API socket here would really be &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But fuck it, let's just assume that we play ball and we adhere to all of these (additional) steps that we're being put through (just for the setup up this virtualization tool!). &lt;/p&gt;

&lt;h3&gt;
  
  
  Following Through on the Next Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ensuring that Firecracker can create its own API: &lt;code&gt;rm -f /tmp/firecracker.socket&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then start Firecracker: &lt;code&gt;./firecracker --api-sock /tmp/firecracker.socket&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;^^ That's just for the "first CLI window" ; for the second one, we must do the following. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Set the guest kernel (assuming you are in the same directory as the above script was run)"; they're saying this because they provided code for folks that don't have the necessary kernel image to be running this out of the gate - but we will be picking up a kernel from elsewhere. Either way, the following code should be copasthetic
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arch=`uname -m`
kernel_path=$(pwd)"/hello-vmlinux.bin"

if [ ${arch} = "x86_64" ]; then
    curl --unix-socket /tmp/firecracker.socket -i \
      -X PUT 'http://localhost/boot-source'   \
      -H 'Accept: application/json'           \
      -H 'Content-Type: application/json'     \
      -d "{
            \"kernel_image_path\": \"${kernel_path}\",
            \"boot_args\": \"console=ttyS0 reboot=k panic=1 pci=off\"
       }"
elif [ ${arch} = "aarch64" ]; then
    curl --unix-socket /tmp/firecracker.socket -i \
      -X PUT 'http://localhost/boot-source'   \
      -H 'Accept: application/json'           \
      -H 'Content-Type: application/json'     \
      -d "{
            \"kernel_image_path\": \"${kernel_path}\",
            \"boot_args\": \"keep_bootcon console=ttyS0 reboot=k panic=1 pci=off\"
       }"
else
    echo "Cannot run firecracker on $arch architecture!"
    exit 1
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;"Set the guest rootfs"
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rootfs_path=$(pwd)"/hello-rootfs.ext4"
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/drives/rootfs' \
  -H 'Accept: application/json'           \
  -H 'Content-Type: application/json'     \
  -d "{
        \"drive_id\": \"rootfs\",
        \"path_on_host\": \"${rootfs_path}\",
        \"is_root_device\": true,
        \"is_read_only\": false
   }"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;"Start the guest machine"
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/actions'       \
  -H  'Accept: application/json'          \
  -H  'Content-Type: application/json'    \
  -d '{
      "action_type": "InstanceStart"
   }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;side note&lt;/strong&gt;: seeing 'curl' here reminded me that that's something that needs to be downloaded &amp;amp; instantiated on our default Docker images (Rust version specifically) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From here, they state, "Going back to your first shell, you should now see a serial TTY prompting you to log into the guest machine" (guessing that this will be the case for us too - basic Ubuntu image should be more than necessary) &lt;/p&gt;

&lt;p&gt;Also, "&lt;em&gt;When you're done, issuing a reboot command inside the guest will actually shutdown Firecracker gracefully. This is due to the fact that Firecracker doesn't implement guest power management.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;They also include this one note: "&lt;em&gt;The default microVM will have 1 vCPU and 128 MiB RAM.&lt;/em&gt;" ; this obviously isn't enough for what we want to do - but that's no problem as this can be configured w relative ease. &lt;/p&gt;

&lt;p&gt;They state, "&lt;strong&gt;If you wish to customize that (say, 2 vCPUs and 1024MiB RAM), you can do so before issuing the InstanceStart call, via this API command&lt;/strong&gt;" (that's annoying that we need to use API commands here for that, but that's cool):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --unix-socket /tmp/firecracker.socket -i  \
  -X PUT 'http://localhost/machine-config' \
  -H 'Accept: application/json'            \
  -H 'Content-Type: application/json'      \
  -d '{
      "vcpu_count": 2,
      "mem_size_mib": 1024,
      "ht_enabled": false
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring the microVM Without Sending API Requests
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;they must have read my mind!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"&lt;em&gt;If you'd like to boot up a guest machine without using the API socket, you can do that by passing the parameter --config-file to the Firecracker process. The command for starting Firecracker with this option will look like this:&lt;/em&gt;" &lt;code&gt;./firecracker --api-sock /tmp/firecracker.socket --config-file &amp;lt;path_to_the_configuration_file&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;They claim that the &lt;code&gt;path_to_configuration_file&lt;/code&gt;, "should represent the path to a file that contains a JSON which stores the entire configuration for all of the microVM's resources" (okay this is fair enough). &lt;/p&gt;

&lt;p&gt;Also, they stipulate, "&lt;strong&gt;The JSON must contain the configuration for the guest kernel and rootfs, as these are mandatory, but all of the other resources are optional, so it's your choice if you want to configure them or not. Because using this configuration method will also start the microVM, you need to specify all desired pre-boot configurable resources in that JSON.&lt;/strong&gt;" &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File Names for the Pre-Boot Resources&lt;/strong&gt; (included within the greater repo here): &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;firecracker.yaml&lt;/code&gt; - Names of resources are contained here ; 'file and the names of their fields are the same that are used in API requests' (cool) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tests/framework/vm_config.json&lt;/code&gt; (boilerplate config file to guide us - great) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From here: &lt;em&gt;"After the machine is booted, you can still use the socket to send API requests for post-boot operations."&lt;/em&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Somewhat of a pain in the ass (just looking through the directions); the fact that we'd have to go grab a uncompressed kernel image + file system image (`) is kind of a fucking hassle / burden. &lt;/p&gt;

&lt;p&gt;Was hoping for a solution more akin to Docker where it can just be spun up real quick &amp;amp; then deployed. But they claim that this 'jailer' feature (that they keep hyping) will &lt;strong&gt;ensure&lt;/strong&gt; (I guess?) that whatever is done within the container will remain within the container (and not escape). &lt;/p&gt;

&lt;p&gt;I haven't seen anything that sticks out about this project that leads me to believe that it possesses that capability, but I definitely don't want to rule it out. &lt;/p&gt;

&lt;h3&gt;
  
  
  Extra Documentation + Information
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OSv Running on 'Firecracker'&lt;/strong&gt; (yay more work though) - &lt;a href="http://blog.osv.io/blog/2019/04/19/making-OSv-run-on-firecraker/" rel="noopener noreferrer"&gt;http://blog.osv.io/blog/2019/04/19/making-OSv-run-on-firecraker/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Building OSv Images Using Docker&lt;/strong&gt; - &lt;a href="http://blog.osv.io/blog/2015/04/27/docker/" rel="noopener noreferrer"&gt;http://blog.osv.io/blog/2015/04/27/docker/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;firecracker containerd&lt;/strong&gt; (this is something that's probably important for the overall mission of what we want to accomplish here) - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Firecracker Containerd
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt; - "&lt;code&gt;firecracker-containerd&lt;/code&gt; enables &lt;code&gt;containerd&lt;/code&gt; to manage containers as Firecracker microVMs*"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"This repository enables the use of a container runtime, &lt;code&gt;containerd&lt;/code&gt;, to manage Firecracker microVMs. Like traditional containers, Firecracker microVMs offer fast start-up and shut-down and minimal overhead. Unlike traditional containers, however, they can provide an additional layer of isolation via the KVM hypervisor." &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;They Also Identify Potential Use-Cases in the Repo Such as&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Sandbox a partially or fully untrusted third party container in its own microVM. This would reduce the likelihood of leaking secrets via the third party container, for example.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Bin-pack disparate container workloads on the same host, while maintaining a high level of isolation between containers. Because the overhead of Firecracker is low, the achievable container density per host should be comparable to running containers using kernel-based container runtimes, without the isolation compromise of such solutions. Multi-tenant hosts would particularly benefit from this use case.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Really interesting feature of this repo here is: "&lt;em&gt;A root file filesystem image builder that constructs a firecracker microVM root filesystem containing &lt;code&gt;runc&lt;/code&gt; and the &lt;code&gt;firecracker-containerd&lt;/code&gt; agent.&lt;/em&gt;" (that could save a lot of time on that whole filesystem image thing that they were mentioning prior) &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional Links of Importance&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Getting Started Guide&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/getting-started.md" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/getting-started.md&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quickstart Guide&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/quickstart.md" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/quickstart.md&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A Root Filesystem Image Builder&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/tools/image-builder" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/tools/image-builder&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Runtime Linking Containerd&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/runtime" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/runtime&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Documentation All Located Here&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/tree/main/docs" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/tree/main/docs&lt;/a&gt; (definitely fucking needed because there's a lot here to wrap one's head around) &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design Approaches Doc&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/design-approaches.md" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/design-approaches.md&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shim Architecture&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/shim-design.md" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-containerd/blob/main/docs/shim-design.md&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Launching 4k VMs Using Firecracker&lt;/strong&gt; - &lt;a href="https://github.com/firecracker-microvm/firecracker-demo" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firecracker-demo&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;firectl&lt;/code&gt; (CLI options for manipulating this tool from terminal ; this is important as well) - &lt;a href="https://github.com/firecracker-microvm/firectl" rel="noopener noreferrer"&gt;https://github.com/firecracker-microvm/firectl&lt;/a&gt;  [damn, there's a lot that came with this here!]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Monero Wallet Backdoor Attempt</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Wed, 05 Oct 2022 23:33:54 +0000</pubDate>
      <link>https://forem.com/librehash/monero-wallet-backdoor-attempt-3omg</link>
      <guid>https://forem.com/librehash/monero-wallet-backdoor-attempt-3omg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This was originally composed and published circa April/May 2021 on the Librehash blog and shared widely across several social media platforms; this piece served as the seminal entry point to a series of deep-dives and research into the Monero protocol and its shortcomings as a privacy coin&lt;/em&gt; (specifically, 'shortcomings' refer to vectors of compromise and in this context 'compromise' refers to transaction traceability) &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL of the Git Repo in question that got torn to pieces in this write-up&lt;/strong&gt; = &lt;a href="https://github.com/tevador/monero-seed"&gt;https://github.com/tevador/monero-seed&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before I go into the reasons for why I strongly believe that this is a backdoor, I'm going to start off by just pointing out a few thing wrong with this wallet implementation. &lt;/p&gt;

&lt;p&gt;I'm doing this to establish that I did not arrive at this conclusion about this user's potentially nefarious intentions after misreading their potential incompetence, lack of qualifications for the project that they're attempting to undertake. &lt;/p&gt;

&lt;p&gt;Also, since we're here, we might as well point out all of the facets of the wallet implementation that are inexcusably insecure &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Embedded wallet birthday to optimize restoring from the seed&lt;/em&gt;" (this makes the wallet markedly more insecure then it needs to be by including unnecessary information  that essentially leaks more info that should've otherwise been left private)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;advanced checksum based on Reed-Solomon linear code&lt;/code&gt; &amp;lt;-- this is another baffling break from convention here that's inferior to the standard used (CRC32) [this is the &lt;strong&gt;modern&lt;/strong&gt; standard currently] / "&lt;em&gt;Some file formats, particularly archive formats, include a checksum (most often CRC32) to detect corruption and truncation and can employ redundancy or parity files to recover portions of corrupted data.&lt;/em&gt;" /// Not to mention that CRC32 is typically used for "digital networks and storage devices to detect accidental changes to raw data" ; this is the most likely vector of compromise for users in this context [attacker gains nothing by corrupting the underlying data]&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Unexplained Departure From BIP32/39 Convention
&lt;/h3&gt;

&lt;p&gt;The URL for the BIP39 construction:  &lt;a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki"&gt;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The link above has the original specification for BIP39 (mnemonics, which is what is the construction that this individual claims to be adhering to BIP39); evidence of this claim below from the user's repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tK77LACs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nraj6w787tqkuw677erl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tK77LACs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nraj6w787tqkuw677erl.png" alt="Image description" width="880" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incorrect Mnemonic Word Count Selection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm not sure if this individual thought the mnemonic phrase word count was an arbitrary choice, but it isn't. &lt;/p&gt;

&lt;p&gt;Entropy is used to generate a binary strong of 128 -bits (depending on the user's specific implementation). After appending the checksum (4-bits additional), the words are generated from the binary string - with strict mappings to the BIP39 dictionary. &lt;/p&gt;

&lt;p&gt;This is mandated by the BIP39 specification (as seen below): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3IbHh9wh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6mmpy2155seushohn6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3IbHh9wh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6mmpy2155seushohn6l.png" alt="Image description" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They use 14 mnemonic words (which deviates entirely from the normal convention). &lt;/p&gt;

&lt;p&gt;They state that the phrase contains "154 bits of data", which are used for "future use", "wallet birthday', "128-bits for the private key seed", and "11 bits for checksum". &lt;/p&gt;

&lt;p&gt;This is extraordinarily incorrect. Normally a BIP32/39 key is derived by: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Generating 128 bits of entropy (for example) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hashing the entire 128 bits of entropy (with the chain's hash algo); then extracting the first 4-bits and appending that to the end of the 132 bits of entropy (that's the checksum; this person didn't even specify how they were going to derive the checksum) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Those 132 bits is supposed to be divided by 11 equal parts (resulting in 12 different "words"). Every 3 words = 32-bits of entropy; there are 4 groups of 32, which calculates back up to 128 (can't forget the additional 4 bits for the checksum). &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Explanations For Decisions Make Zero Sense
&lt;/h3&gt;

&lt;p&gt;Not only has this individual deviated significantly from the standard (which I had qualms with as is, but that's aside from the point). &lt;/p&gt;

&lt;p&gt;Under the "reserved bits" section, they make statements that diverge from any logical cryptographic sense entirely. &lt;/p&gt;

&lt;p&gt;I'm not sure why they're under the impression that bits can be "reserved" for some other purpose (what the fuck does that mean?). This entropy is part of the normal BIP39 construction that generates the entropy for the purpose of having users pipe the UTF-8 NKFD result into the PBKDF-HMAC-512 construction to &lt;strong&gt;derive a key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There is no such thing as "reserving bits". Either bits are being used or they aren't. &lt;/p&gt;

&lt;h4&gt;
  
  
  Statements Made About the 'Bits' Reflect a Fundamental Failure to Understand EDDSA
&lt;/h4&gt;

&lt;p&gt;The subheading for this section may seem a bit harsh, but its honestly an understatement at this point in time. &lt;/p&gt;

&lt;p&gt;Also, what is meant by a "flag to differentiate betwen normal and 'short' address format"? &lt;/p&gt;

&lt;p&gt;The public Monero address is a concatenation of the public spend key + public view key. They're both derived as two different valid points on the Edwards' Curve. &lt;/p&gt;

&lt;p&gt;The publication, 'Zero to Monero' corroborates this as well: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x_ymRXhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uaswg03t5tys0vllbbjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x_ymRXhe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uaswg03t5tys0vllbbjx.png" alt="Image description" width="880" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two different sets of coordinates used because ed25519 keys can be used for both encryption and signing (unlike ecdsa / secp256k1). Monero takes advantage of this fact and does this by essentially granting individuals a public key that individuals can encrypt to (public view key) ; the public spend key is how they derive a subaddress based on what they know (the mission-critical nature of these addresses can't be understated since this all ties into the construction that Monero uses to protect against double spend attempts) &lt;/p&gt;

&lt;p&gt;So I'm puzzled at why this user proposed having the "view key equal to the spend key"; not only does this make zero fucking sense, it also would make Monero exponentially less secure by orders of magnitude. &lt;/p&gt;

&lt;p&gt;In fact, at a glance, this would entirely erode nearly all of the privacy on the protocol. &lt;/p&gt;

&lt;h3&gt;
  
  
  Where This User's Actions Make Me Believe They Are Setting Up a Backdoor
&lt;/h3&gt;

&lt;p&gt;If you scroll down that GitHub page link that I provided, you'll see a header that says, 'Private key seed'. &lt;/p&gt;

&lt;p&gt;This is the first spot where I observed that this user had reduced the security of the key derivation function (for no apparent reason). &lt;/p&gt;

&lt;p&gt;See below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---EzDfbJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3c5e7ifsdn65gog36448.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---EzDfbJ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3c5e7ifsdn65gog36448.png" alt="Image description" width="880" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically they state: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The private key is derived from the 128-bit seed using PBKDF2-HMAC-SHA256 using 4096 iterations. The wallet birthday and the 5 reserved/feature bits are used as a salt. 128-bit seed provides the same level of security as the elliptic curve used by Monero"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ah! No! All of this is wrong &amp;amp; almost maliciously so. &lt;/p&gt;

&lt;p&gt;Let's start from the top though. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This User Weakened the Key Stretching Function From BIP39&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;There is no conceivable reason for them taking this action (and this is actually something that would unique compromise users on the chain and I'll explain how). &lt;/p&gt;

&lt;p&gt;First, let me establish that this individual did indeed weaken the strength of this key stretching function (PBKDF2-HMAC construction). &lt;/p&gt;

&lt;p&gt;Below is a specification from BIP39 (Bitcoin): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qMRKVWNY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/145eru5gfjm54pdiqig2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qMRKVWNY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/145eru5gfjm54pdiqig2.png" alt="Image description" width="880" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going further, if we look at the key length / bit / strength information provided by a matrix table from Wikipedia (these values were cross-referenced with the NIST specifications; this can be done independently by anyone reading along as well): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O6gmCp-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9srtcmx8wsfdur523yi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O6gmCp-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9srtcmx8wsfdur523yi.png" alt="Image description" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please keep in mind that security in the sense of cryptography refers to the strength in 'n' bits (hence the security against collision attacks). &lt;/p&gt;

&lt;p&gt;Therefore, the difference between 256-bit strength and 128-bit strength &lt;strong&gt;is a hell of a lot more than 2x&lt;/strong&gt;; the difference is probably several hundred million times (and that's more than likely me low-balling it hard as fuck; i.e., 2&lt;sup&gt;128&lt;/sup&gt; vs. 2&lt;sup&gt;256&lt;/sup&gt;) &lt;/p&gt;

&lt;h4&gt;
  
  
  Weird Nuance in the HMAC Convention Would Cause Collisions With Their Proposal
&lt;/h4&gt;

&lt;p&gt;Since they elected to go with PBKDF2 - HMAC256 (vs. 512 variant), we need to take care to consider the length of the input being piped into this hash function. &lt;/p&gt;

&lt;p&gt;Specifically, according to RFC2104: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Keys longer B bytes are first hashed using H"&lt;/em&gt;  [source = &lt;a href="https://tools.ietf.org/html/rfc2104"&gt;https://tools.ietf.org/html/rfc2104&lt;/a&gt;]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This, notably creates a seeming collision, where the sha256 of the input is the same as its HMAC (in essence); this essentially nulls the purpose of the HMAC in the first place. &lt;/p&gt;

&lt;p&gt;This is detailed in this post here = &lt;a href="https://mathiasbynens.be/notes/pbkdf2-hmac"&gt;https://mathiasbynens.be/notes/pbkdf2-hmac&lt;/a&gt; (the individual  provided NodeJS + Python code for the reader to attempt to simulate on their own machines if they wanted to - very benign article) &lt;/p&gt;

&lt;h4&gt;
  
  
  It Appears That This User Neutered the HMAC Portion Entirely
&lt;/h4&gt;

&lt;p&gt;This is a real problem at this point. And the omission of HMAC in this scheme the user is designing &lt;strong&gt;cannot be chucked up to ignorance&lt;/strong&gt; or "&lt;strong&gt;not knowing&lt;/strong&gt;". &lt;/p&gt;

&lt;p&gt;Again, as shown above in the prior section, this user's reference to BIP39 shows that they  have had exposure to the specification.&lt;/p&gt;

&lt;p&gt;So there's no conceivable reason for removing the HMAC (key stretching) function from this scheme they're crafting. &lt;/p&gt;

&lt;h4&gt;
  
  
  Individual's Claim About the Strength of the Entropy vs. Strength of Curve Are 100% False
&lt;/h4&gt;

&lt;p&gt;Under the same section as the dubious private key entry, the user states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"128-bit seed provides the same level of security as the elliptic curve used by Monero."&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Monero doesn't use elliptic curves &lt;/li&gt;
&lt;li&gt;No it fucking doesn't &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Entropy is not "security", nor is it ever factored into the bit-strength of the "elliptic curve" or the 'Edwards Curve' in this case. &lt;/p&gt;

&lt;p&gt;These curves are geometric functions that depend on the assumed hardness of the discrete logarithm problem as their security assurance. &lt;/p&gt;

&lt;p&gt;This is well known information... &lt;/p&gt;

&lt;h4&gt;
  
  
  Downgrading of Argon2 to PBKDF2
&lt;/h4&gt;

&lt;p&gt;This one is inexcusable in any universe. &lt;/p&gt;

&lt;p&gt;The commit was made on June 14th, 2020: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HcbHwsLq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5coi8jd53aorqjckb9j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HcbHwsLq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5coi8jd53aorqjckb9j1.png" alt="Image description" width="880" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/tevador/monero-seed/commit/f1c7829f043322849c0323f58aa0a46352de4e02"&gt;https://github.com/tevador/monero-seed/commit/f1c7829f043322849c0323f58aa0a46352de4e02&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visiting the commit directly, we can see this individual &lt;strong&gt;adding PBKDF2 to the project&lt;/strong&gt; while simultaneously &lt;strong&gt;removing Argon2&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H7-BhqeM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9htyky2qkh1de9hvgzs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H7-BhqeM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9htyky2qkh1de9hvgzs.png" alt="Image description" width="880" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DaPSleX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuuk83ju39z0lhvvbgdx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DaPSleX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuuk83ju39z0lhvvbgdx.png" alt="Image description" width="880" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--taPNG0vz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/taaw6andoxnr1z4z2in0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--taPNG0vz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/taaw6andoxnr1z4z2in0.png" alt="Image description" width="880" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nevermind the fact that this is oddly coded in 'C', which is a curious language choice for a simple library (there are many, much lighter weight and easier ways to implement this). &lt;/p&gt;

&lt;p&gt;One particular qualm about 'C' is that its &lt;strong&gt;not memory safe&lt;/strong&gt; ; which means that we aren't afforded protection from the program overflowing (which is more than realistic and, perhaps plausible, considering the input block length) &lt;/p&gt;

&lt;h4&gt;
  
  
  Explaining Why the Argon2 Swap Was Ludicrous
&lt;/h4&gt;

&lt;p&gt;If you were to ask &lt;strong&gt;any security professional&lt;/strong&gt; on planet earth what their opinion was on the best hash algorithm (for ensuring your information remains behind an impenetrable fortress. &lt;/p&gt;

&lt;p&gt;For those familiar with mining, you may remember that hash algorithm - after all, its used in Monero. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Password Hashing Competition&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Recently, there was an international competition that sought to find the latest and greatest in the world as it pertains to KDFs (key-derivation functions). &lt;/p&gt;

&lt;p&gt;While said competition may seem a bit preposterous, it did indeed exist. And it was hosted, followed and adjudicated &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fwzZqqHw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4piz7snkyifdzmeh2hxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fwzZqqHw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4piz7snkyifdzmeh2hxp.png" alt="Image description" width="880" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://www.password-hashing.net/"&gt;https://www.password-hashing.net/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  No Conceivable Reason For the Replacement of Argon2
&lt;/h4&gt;

&lt;p&gt;Argon2 is exponentially stronger than PBKDF2. &lt;/p&gt;

&lt;p&gt;Multiple experts in the field of cryptography and elsewhere have vouched for it as being the strongest password-hashing algorithm out there. &lt;/p&gt;

&lt;p&gt;And we just so happen to find ourselves in a situation where we're deriving a key that we need to keep secret. &lt;/p&gt;

&lt;p&gt;Which means that there would be &lt;strong&gt;no better KDF to use&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of How to Derive a Monero Address From an Argon2 KDF&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There's live (open source) code on the internet that can be audited and/or compiled to test the veracity of this construction. &lt;/p&gt;

&lt;p&gt;Any reader visiting the link will be taken to a cool module built from the WarpWallet principle utilized by Keybase. &lt;/p&gt;

&lt;p&gt;Here's the URL = &lt;a href="https://patcito.github.io/mindwallet"&gt;https://patcito.github.io/mindwallet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QFpdYr7_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4yqr6k88r9lnne2l8pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QFpdYr7_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4yqr6k88r9lnne2l8pm.png" alt="Image description" width="880" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0UXj5a8u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w4fvpnhopd1wepd4njw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0UXj5a8u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w4fvpnhopd1wepd4njw.png" alt="Image description" width="880" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Address generation process is deterministic (just like ed25519), so that's good for this scheme. The entire code runs client side and is available for users to download at their leisure to deploy Golang / Python as your preferred language to interact with &lt;/p&gt;

&lt;h4&gt;
  
  
  Reed-Solomons Code Weakens the Mnemonic Selection
&lt;/h4&gt;

&lt;p&gt;See below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HLg-jR4y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xm6bczsjg9f1hlhpqjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HLg-jR4y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xm6bczsjg9f1hlhpqjl.png" alt="Image description" width="880" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should be wholly impossible if the key is constructed properly. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ian Coleman's Library&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Ian is one of the most prolific PoC composers this space will ever know. &lt;/p&gt;

&lt;p&gt;And lucky for us - he has one for BIP39 as well, which should allow us to get a general gist of the security of this assumption&lt;/p&gt;

&lt;p&gt;Below is a screen of the site: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4JpyDcmO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7fwhrc7632h5sacxtffs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4JpyDcmO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7fwhrc7632h5sacxtffs.png" alt="Image description" width="880" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://iancoleman.io/bip39/"&gt;https://iancoleman.io/bip39/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notably, Ian's specifications for the mnemonic word options mirror the actual implementation too: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t9NK0ckB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mspyf4oxct4oyizuql91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t9NK0ckB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mspyf4oxct4oyizuql91.png" alt="Image description" width="880" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we utilize the 'BIP39 Split Mnemonic' feature, that's when we'll see a concise estimate of how long it would take to break to crack a wallet where the user has submitted in some of their too much for a second ("cards")&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SMNezJiS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3udd0irajb3j9v81o2wc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SMNezJiS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3udd0irajb3j9v81o2wc.png" alt="Image description" width="880" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Brief (Really) Breakdown on Reflection Token Smart Contracts</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Wed, 05 Oct 2022 23:13:45 +0000</pubDate>
      <link>https://forem.com/librehash/brief-really-breakdown-on-reflection-token-smart-contracts-j6a</link>
      <guid>https://forem.com/librehash/brief-really-breakdown-on-reflection-token-smart-contracts-j6a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;this was originally written and published back last November&lt;/em&gt; (2021); &lt;em&gt;obviously, we've learned a decent amount about such smart contracts in the time since - so keep this in mind when reading&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this was the write-up that got crushed when my computer froze ; 16GB of RAM on her, but with nearly 2-years under her belt, its time to put her out to pasture soon enough -- not today, though! So let's fucking get to it without wasting any more time&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was mentioned before in the Discord, but some individuals from Binance(?) under the guise of 'Huh Token' reached out to give me a few tasks. &lt;/p&gt;

&lt;p&gt;I'm going to take some time briefly to summarize those tasks to: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Give readers a better sense of the expertise of the one proposing this project idea &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A better understanding of the concept of 'reflection tokens', overall &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An intuitive understanding of just how difficult it is to instantiate such a project (for those that may be wondering, 'If this is such a good idea, how come everyone is not doing it?')&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A sense of the general smart contract auditing pipeline for those that are unfamiliar with it. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Starting with the Certik Audit
&lt;/h2&gt;

&lt;p&gt;This encounter was actually the first time I had ever come face-to-face with a smart contract that had been audited by Certik. &lt;/p&gt;

&lt;p&gt;As we all know, Certik has caught a ton of flack over the last year or so after several projects they reportedly audited ended up having their smart contracts exploited / plundered (for one reason or another). Reviewing their audit was an activity I found to be enlightening because it ended up &lt;strong&gt;shifting my opinion&lt;/strong&gt; on Certik from them being an incompetent auditing firm to them being a firm that has received unnecessary flack. &lt;/p&gt;

&lt;p&gt;If that statement is surprising, then you should continue reading into the next section. &lt;/p&gt;

&lt;h3&gt;
  
  
  Spotting Simple Errors in the Smart Contract
&lt;/h3&gt;

&lt;p&gt;Before taking a look at the Certik audit, I decided to delve into the smart contract code directly myself. &lt;/p&gt;

&lt;p&gt;Specifically, I wanted to take a look at the 'HuhFlattenToken.sol' contract they had under the git repo (forked / branched over to my account). &lt;/p&gt;

&lt;p&gt;You can find that here: &lt;a href="https://github.com/Librechain/HuhToken/blob/main/contracts/HuhTokenFlatten.sol" rel="noopener noreferrer"&gt;https://github.com/Librechain/HuhToken/blob/main/contracts/HuhTokenFlatten.sol&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll notice the errors begin around line 532 (we'll start from the BEP20 interface)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function distributeDividend(address shareholder) private {
    if (shares[shareholder].amount == 0)
        return; 

    uint256 amount = getUnpaidEarnings(shareholder);
    if (amount &amp;gt; 0) {
        totalDistributed = totalDistributed.add(amount);
        (bool success,) = payable(shareholder).call{value: amount, gas: 30000}("");
        require(success, "distributeDividend: Could not transfer funds!");

        shareholderClaims[shareholder] = block.timestamp;
        shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
        shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's check out some of the comments that were made in that Certik Audit. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7mi0jvz5ty12y8lddpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7mi0jvz5ty12y8lddpo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the same code was identified &amp;amp; Certik is indeed correct here in stating that there is a &lt;strong&gt;major flaw here in the smart contract code that could lead to the draining of the smart contract&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Toward the beginning of the audit, a summary of the details uncovered can be found. Within that summary, we can see that the team had done little to nothing to rectify all of the issues published by Certik at the time (&lt;em&gt;likely this is still the case since they do not have the expertise on hand to rectify all of the problem issues they identified&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2ylwfiids2jd6j1977e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2ylwfiids2jd6j1977e.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above, we can see that the vast majority of issues (of all severities) that were identified by the Certik team were &lt;strong&gt;not addressed&lt;/strong&gt; (even though the project owners told me they were planning on launching at any moment). &lt;/p&gt;

&lt;p&gt;This is indicative of how lazy + sloppy many smart contracts are 'in the wild' of blockchain (esp. as it pertains to BSC  projects). &lt;/p&gt;

&lt;p&gt;To be clear, the contract that I was looking at had:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Various 'reentrancy' flaws&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No sanitized inputs for the contract&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No implementation of 'SafeMath' (safemath.sol) to prevent buffer overflows on the reads (which would lead to memory corruption)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Main issue (from the Certik audit) was their failure to make sure that they 'zero out' the intermediate address balance of whomever has been granted permission to make a call on the contract (doing this is also necessary to make sure that the smart contract cannot be drained). &lt;/p&gt;

&lt;h2&gt;
  
  
  Addressing the Remaining Tasks Assigned for the Smart Contract
&lt;/h2&gt;

&lt;p&gt;They threw me this very complex smart contract where they were looking to provide a "referral" for buyers of the token in the form of $BNB.&lt;/p&gt;

&lt;p&gt;Referrers get 10% of the purchase amount from the contract. They also need to have their addresses whitelisted (+ referrer code; they insisted). Additionally, there is a tax applied to sellers to incentivize folks not selling any of this .&lt;/p&gt;

&lt;p&gt;Normal seller tax = 15%; but if someone is a whistelisted seller, then the tax reduces itself down to 10% (in $BNB).&lt;/p&gt;

&lt;p&gt;That tax then gets redistributed to those that are "providing liquidity". Some portion goes to those that are whitelisted referrers, then another portion goes to those that are "holders" of the &lt;br&gt;
token. &lt;/p&gt;

&lt;p&gt;And this all needed to be mounted up on a DEX (PancakeSwap specifically).&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific Requests / Tasks to be Completed
&lt;/h3&gt;

&lt;p&gt;Set things up so that this all would occur automatically (assuming someone possesses the requisite 'referral code' pointing back to th e referee).&lt;/p&gt;

&lt;p&gt;I guess as an added twist, they failed to give me the actual smart contract code for the token / contract they were looking to launch.&lt;/p&gt;

&lt;p&gt;They also didn't tell me who was responsible for creating the code that they already had in place at the time they asked me if I could do this. So there was nobody I was able to speak to about the situation to "catch up" and see where they were at with things.&lt;/p&gt;

&lt;p&gt;So had to find the contract &amp;amp; then start out from scratch.&lt;/p&gt;

&lt;p&gt;This wasn't all though. &lt;/p&gt;

&lt;p&gt;Once I did find the actual code for the smart contracts (on GitHub), I had to walk through the smart contracts to get a sense for what it was doing / not doing (never seen one like this before).&lt;/p&gt;

&lt;p&gt;There were some new functions in the code that I had never seen before (this is for Binance Smart Chain; not Ethereum).&lt;/p&gt;

&lt;p&gt;Essentially they said their problem is that when a user made a call on the contract, there would be no automated transactions (this is impossible w blockchain anyway); but then they said whenever they made a subsequent transaction (initiated as the contract owner), that's when they would see the referral fees get paid out (but only during this event).&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the Contract's Critical Function
&lt;/h3&gt;

&lt;p&gt;When they said that, I knew I needed to look specifically at the part of the code that defined a regular, garden-variety transfer.&lt;/p&gt;

&lt;p&gt;That's when I noticed the functions I had never seen before.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_rOwned&lt;/code&gt; &amp;amp; &lt;code&gt;_tOwned&lt;/code&gt; ; never seen that construction in my fucking life in a smart contract. So that's when I went a-hunting.&lt;/p&gt;

&lt;p&gt;Turns out that this concept derives from some project launched this year called 'reflect finance' ; &lt;a href="https://reflect.finance/" rel="noopener noreferrer"&gt;https://reflect.finance/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hardly any information on their website detailing what these functions are supposed to be doing in the code. Its important for me to figure this out because these "r"-prefixed balances were all over the place in the code. &lt;/p&gt;

&lt;h3&gt;
  
  
  Other Developers Stumped on these 'rToken' Values as Well
&lt;/h3&gt;

&lt;p&gt;When I attempted to search online to glean more information about these variables in the code, I was surprised to find that there were others in the same boat as I seeking the same information. &lt;/p&gt;

&lt;p&gt;One potent example can be found here - &lt;a href="https://forum.openzeppelin.com/t/reflect-finance-variables/6888" rel="noopener noreferrer"&gt;https://forum.openzeppelin.com/t/reflect-finance-variables/6888&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ymmkp1r6cg0ji9henr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ymmkp1r6cg0ji9henr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first response that this user received, however (from a 'Top Contributor'), was a bit disheartening. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3calnoqi4fw55wfd472.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3calnoqi4fw55wfd472.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Worst yet, it appeared that not even the modertors for the token had a firm understanding of what these variables mean/meant. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqj3pa8318x3x3mifmb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqj3pa8318x3x3mifmb1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reading through more replies, it became immediately apparent that there were few that truly understood the code at all (since there are no 'code notes' &amp;amp; the documentation for 'RFI' is non-existent at the time of writing, which is highly unusual). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41nskdpxbuf5vvgznp08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41nskdpxbuf5vvgznp08.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the 'Holy Grail'
&lt;/h3&gt;

&lt;p&gt;Fortunately for us, there is one user out there that decided to take the intiative of dissecting the functions in their entirety via a whitepaper. &lt;/p&gt;

&lt;p&gt;That post on OpenZeppelin can be found here - &lt;a href="https://forum.openzeppelin.com/t/a-technical-whitepaper-for-reflect-contracts/14297" rel="noopener noreferrer"&gt;https://forum.openzeppelin.com/t/a-technical-whitepaper-for-reflect-contracts/14297&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed9ulr4k4ujw9squca3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed9ulr4k4ujw9squca3j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, this resource has long since been saved since it will serve infinitely useful in the mid-to-long-term as we parse out more information from here for inclusion into the whitepaper itself. &lt;/p&gt;

&lt;p&gt;The URL for this whitepaper can be found here - &lt;a href="https://reflect-contract-doc.netlify.app/" rel="noopener noreferrer"&gt;https://reflect-contract-doc.netlify.app/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining Reflect Tokens
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The paper starts off by providing the following helpful introduction to these token balance types&lt;/strong&gt;: "&lt;em&gt;Before diving into the contract, a new concept must be introduced: t-space and r-space values, along with tTotal and rTotal. tTotal, which belongs to t-space, represents tokens in circulation or total supply of a token. On the other hand, rTotal, which belongs to r-space, is a reflected value of tTotal. The term “reflected” cannot be easily explained in words but one interpretation of rTotal is token supply in reserve. Furthermore, values in t-space can easily be converted to r-space form, and vice versa using formula&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As well as&lt;/strong&gt;: "&lt;em&gt;Stakers are users who earn passive income by holding native token. In contrast, non-stakers do not earn rewards. Router contracts, pair contracts, dev wallets are usually excluding from staking in order to fully reward users.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr89f7r5b30i5a7ju45kt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr89f7r5b30i5a7ju45kt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This results in the following graph (showing the 'workflow' for these types of tokens). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17yrdo4pd0h870z796cx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17yrdo4pd0h870z796cx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85ofwhl3i4rx3w93azdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85ofwhl3i4rx3w93azdk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is powered by the following deflationary mechanism: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9z6fyy3j0148746qot41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9z6fyy3j0148746qot41.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creating a Secure, Sandboxed Docker Container</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Wed, 05 Oct 2022 23:04:48 +0000</pubDate>
      <link>https://forem.com/librehash/creating-a-secure-sandboxed-docker-container-23hi</link>
      <guid>https://forem.com/librehash/creating-a-secure-sandboxed-docker-container-23hi</guid>
      <description>&lt;p&gt;All of the information on how one would go about doing this can be found here: &lt;a href="https://gvisor.dev/docs/user_guide/quick_start/docker/"&gt;https://gvisor.dev/docs/user_guide/quick_start/docker/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Breakdown on What This is
&lt;/h2&gt;

&lt;p&gt;We're installing the gVisor here  so that it can be run alongside any Docker container that is launched. There is significant reason for why this should be done (&lt;em&gt;as it appears that Docker has been getting fried over the past year or so and we have the entire app portal running through the Docker at the time of writing ; therefore, we need to consider using this as a means of mitigating any potential vulnerabilities that could arise as a result of system calls being made outside of the sandbox + I'm not going to trust these mother fuckers up at Cloudron to be my last line of defense for this because I'm not entirely sure that they know what they're doing when it comes to&lt;/em&gt; &lt;strong&gt;ensuring security for Docker containers and we need to make sure that we are ultimately responsible for the security of our instance in a way that can't be covered by another 3rd-party configuration&lt;/strong&gt;) &lt;/p&gt;

&lt;p&gt;A guide on the actual architecture of this container can be found here = &lt;a href="https://gvisor.dev/docs/architecture_guide/security/"&gt;https://gvisor.dev/docs/architecture_guide/security/&lt;/a&gt; (this is a meaningful read so that we can brief ourselves on how we're able to securitize against a number of potential vulnerabilities by using this tool)&lt;/p&gt;

&lt;h3&gt;
  
  
  Discussing Some of the Mitigations Afforded by the gVisor
&lt;/h3&gt;

&lt;p&gt;On a personal PC level, we need to watch out for L1TF vulnerabilities (which come with older processors, hence the need for us to ensure that we're utilizing the latest generation ones;  would prefer that it be AMD vs. Intel because it appears that they are more resistant to Spectre attacks overall, but this is still up for alteration contingent on what further information / research is uncovered to support / contradict this decision. &lt;/p&gt;

&lt;p&gt;We will always go in the direction of empirical research. &lt;/p&gt;

&lt;p&gt;Specifically, the project states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"gVisor was created in order to provide additional defense against the exploitation of kernel bugs by untrusted userspace code."&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally enlightens us to the fact that bugs within the System API happen to be the most exploitable of all the bugs that are found within the kernel at a given point in time. &lt;/p&gt;

&lt;p&gt;Mentions the incidence of hardware side channels, which we've already provided numerous mitigations for (on the home system; not entirely certain about what can be done for the 'away system' or the server setup itself -- this will come down, in part, to the hardware that the server is being ran on as long as we have it on a hosted server like Linode or something else) &lt;/p&gt;

&lt;p&gt;Its a shame that the servers that we have running can't be ported over to OpenBSD, but that's also a fact of life created by OpenBSD since they're incompatible with virtualization (&lt;em&gt;to a large extent; there is bhyve, but have never really explored that as something that can be viably used for anything meaningful -- perhaps this is a mistake of sorts, but there is nothing to my knowledge that this can be leveraged for ... perhaps this is worth looking into though /// will make sure to open a portion of the notes that are dedicated to address whether this should be the case or not&lt;/em&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  First Step: Actually Installing Docker and Configure it Appropriately (takes two seconds max)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download docker.io: &lt;code&gt;sudo apt-get install docker.io whalebuilder subuser sen skopeo sen rootlesskit rkt docker-clean docker-compose docker-doc docker-registry&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once step one is complete, that's when a user must then run the following commands to ensure that Docker is setup and ready to go (added a few extra commands that are just useful to have in general): &lt;code&gt;sudo systemctl enable docker&lt;/code&gt; then &lt;code&gt;sudo systemctl start docker&lt;/code&gt; (one can add their user to the docker group, then 'cd' to the root [running &lt;code&gt;cd /&lt;/code&gt;], and then run the command &lt;code&gt;exec bash&lt;/code&gt; &amp;amp; that should refresh the terminal, allowing them to run commands via docker as a regular user instead of having to use 'sudo' all the time - cool) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Installing gVisor&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This is actually the next step in the list that needs to be followed first (in order to get the runsc configuration setup) &lt;/p&gt;

&lt;p&gt;Page can be found here: &lt;a href="https://gvisor.dev/docs/user_guide/install/"&gt;https://gvisor.dev/docs/user_guide/install/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Have to run this clunky ass code in order to make it all work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(
  set -e
  URL=https://storage.googleapis.com/gvisor/releases/release/latest
  wget ${URL}/runsc ${URL}/runsc.sha512 \
    ${URL}/gvisor-containerd-shim ${URL}/gvisor-containerd-shim.sha512 \
    ${URL}/containerd-shim-runsc-v1 ${URL}/containerd-shim-runsc-v1.sha512
  sha512sum -c runsc.sha512 \
    -c gvisor-containerd-shim.sha512 \
    -c containerd-shim-runsc-v1.sha512
  rm -f *.sha512
  chmod a+rx runsc gvisor-containerd-shim containerd-shim-runsc-v1
  sudo mv runsc gvisor-containerd-shim containerd-shim-runsc-v1 /usr/local/bin
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming that the above step completes itself without any issue (again, this would be within a containerized container to begin with), then the next steps need to be run, which are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/local/bin/runsc install
sudo systemctl restart docker
docker run --rm --runtime=runsc hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't need to necessarily run that last command, but that's simply to ensure that runsc has successfully been ran (this must be done after docker is installed) &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Note&lt;/strong&gt;: Have to 'cd' into /usr/bin then check on the presence of runsc using 'fzf' (or just &lt;code&gt;ls | grep runsc&lt;/code&gt; to see if its in a path where executables can be ran ; this is important, otherwise the other commands that need to be ran with 'runsc' won't be able to be ran from that point moving forward) &lt;/p&gt;

&lt;h3&gt;
  
  
  Believe That This is an Additional Step
&lt;/h3&gt;

&lt;p&gt;So when I was initially running this in the container, I wasn't sure whether this step was an alternate means of downloading gVisor or supplementary to everything that had been done, but I just followed the step anyway because...why not ? (it didn't create any errors, conflicts or yield messages indicating re-installation of packages which = wasted time &amp;amp; resources). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step One&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update &amp;amp;&amp;amp; \
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configuring the key for the signed archives and ofc adding the repo where gVisor is held at (so that we can pull it down via apt when we're finished)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fsSL https://gvisor.dev/archive.key | sudo apt-key add -
sudo add-apt-repository "deb https://storage.googleapis.com/gvisor/releases release main"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once all of the above has been completed, then 'runsc' can simply be installed via the packages (like a normal package at that point): &lt;code&gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y runsc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And boom, voila. &lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring Docker to Use Runsc
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Just need to run &lt;code&gt;sudo runsc install&lt;/code&gt; first. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then run &lt;code&gt;sudo systemctl restart docker&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Starting Up a Docker Container With the Runsc Runtime
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We just need to specify it on the command line by adding in the '--runtime=runsc' directive amidst the usual commands that one would run with the docker container; for example: &lt;code&gt;docker run --runtime=runsc --rm -it ubuntu /bin/bash&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The command above should take us to a bash shell of an Ubuntu pull from their docker repos (read up later on Docker security as it pertains to tightening Docker to ensure that there are no "breaches" that occur as a result of pulling a bad image from a repository (there are fake / malware images out there that have been fucking people up ; additionally, we need to actually lockdown the Docker network to ensure that there are no compromises that occur through there either // following the CIS benchmark requisites should help -- again that will be touched on in a different piece) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>OpenSea / Wyvern Protocol Notes (Draft - Unfinished)</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Wed, 05 Oct 2022 22:58:05 +0000</pubDate>
      <link>https://forem.com/librehash/opensea-wyvern-protocol-notes-draft-unfinished-2bpm</link>
      <guid>https://forem.com/librehash/opensea-wyvern-protocol-notes-draft-unfinished-2bpm</guid>
      <description>&lt;p&gt;Somewhat complex how this works. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;OpenSea = lazy minting (doesn't mint until you actually execute the sale; seems like this is what got those users when looking at the stack trace of those transactions) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"It never tells you why and for what purpose you are signing transactions!" (curious; &lt;a href="https://forum.openzeppelin.com/t/eli5-how-opensea-nft-works/7645" rel="noopener noreferrer"&gt;https://forum.openzeppelin.com/t/eli5-how-opensea-nft-works/7645&lt;/a&gt;) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"OpenSea uses the WyvernProtocol, an (audited, battle tested) system that creates a personal proxy contract for each user. We dont' control the proxies that get created, and you have to approve access to each ERC721 contract individually (and some contracts, like CryptoKitties, you have to approve each asset individually) before the proxy can access any of your assets."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Once a proxy contract is approved, you can sign orders indicating you are willing to sell a given asset for a specific price. The logic of the exchange contract only allows it to transfer an asset from your proxy only if A) you have signed an order, and B) it is properly matched by a buyer paying the appropriate funds. So not only does your asset never leave your wallet, it's only allowed to be swapped if an order you create is properly matched." #foodforthoughts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"The proxy addresses are created programmatically and can't be changed" &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Quotes above are from a Reddit where someone answered about the way Wyvern Protocol works - &lt;a href="https://www.reddit.com/r/opensea/comments/a3tax6/opensea_security/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/opensea/comments/a3tax6/opensea_security/&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  More Information about Creation of Proxy Contract by WyvernProtocol
&lt;/h3&gt;

&lt;p&gt;Some decent information here - &lt;a href="https://victoryeo-62924.medium.com/wyvern-protocol-in-opensea-nft-marketplace-b0cef9a9143a" rel="noopener noreferrer"&gt;https://victoryeo-62924.medium.com/wyvern-protocol-in-opensea-nft-marketplace-b0cef9a9143a&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mainly: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Every user has a proxy smart contract" (apparently this is created for them by the WyvernProtocol itself; so each proxy smart contract address should be unique to a given user on the OpenSea platform - cool, got it) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Each item which is traded on OpenSea is owned by a Proxy smart contract of a user" (okay, more food for thoughts) &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Curious Facts Regarding the Mandatory Use of Proxy Contracts for Authorizing Trade
&lt;/h3&gt;

&lt;p&gt;As stated above, the Wyvern Protocol is responsible for generating unique proxy addresses for each user on the platform. These proxy addresses are what are ultimately responsible for granting / revoking permissions. &lt;/p&gt;

&lt;p&gt;Specifically, one particular function seemed to be a source of trouble for many users on the OpenSea platform and that was the &lt;code&gt;isApprovedForAll&lt;/code&gt; function (&lt;em&gt;which is auto-overrided in the current Wyvern v3 spec&lt;/em&gt;). Specifically, that function was found within the ERC1155 and ERC721 smart contracts for OpenSea's platform. &lt;/p&gt;

&lt;p&gt;The function was written as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isApprovedForAll(address owner, address operator)
    public 
    view 
    override 
    returns (bool) 
{
    // allows gasless trading on OpenSea 
    return super.isApprovedForAll(owner, operator) || isOwnersOpenSeaProxy(owner, operator); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Extracted this code from here&lt;/em&gt; = &lt;a href="https://gist.github.com/dievardump/483eb43bc6ed30b14f01e01842e3339b/revisions" rel="noopener noreferrer"&gt;https://gist.github.com/dievardump/483eb43bc6ed30b14f01e01842e3339b/revisions&lt;/a&gt; (&lt;em&gt;underneath the 'revisions' because the user that published these gists later redacted them out of concern for end-user compromise in lieu of the permissions granted by this type of smart contract&lt;/em&gt;) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More information about how this function works can be found directly on OpenSea's site: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67rij3p9sk9mp3csio98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67rij3p9sk9mp3csio98.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://docs.opensea.io/docs/1-structuring-your-smart-contract#opensea-whitelisting-optional" rel="noopener noreferrer"&gt;https://docs.opensea.io/docs/1-structuring-your-smart-contract#opensea-whitelisting-optional&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Worth noting here is the statement, "&lt;em&gt;Additionally, the&lt;/em&gt; &lt;code&gt;ERC721Tradable&lt;/code&gt;&lt;em&gt;and&lt;/em&gt; &lt;code&gt;ERC1155Tradable&lt;/code&gt; &lt;em&gt;contracts whitelist the proxy accounts of OpenSea users so that they are automatically able ot trade any item on OpenSea&lt;/em&gt; (without having to pay gas for additional approval)." &lt;/p&gt;

&lt;p&gt;Essentially what this means is that when a user purchases an NFT on OpenSea (i.e., &lt;em&gt;they receive a&lt;/em&gt; &lt;code&gt;ERC721Tradable&lt;/code&gt; / &lt;code&gt;ERC1155Tradable&lt;/code&gt;) that user would typically need to grant explicit permission to their proxy contract before being allowed to trade any given NFT (&lt;em&gt;within a collection&lt;/em&gt;). Making that request explicitly would require a separate transaction in itself (&lt;em&gt;in addition to the one necessary to sell the NFT&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Thus, OpenSea allowed users to 'whitelist' their proxy address via the &lt;code&gt;isApprovedForAll&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;From here, we're going to double back over to the WyvernProtocol code specification for their smart contracts, which you can find here: &lt;a href="https://docs.projectwyvern.com/docs/ProxyRegistry/" rel="noopener noreferrer"&gt;https://docs.projectwyvern.com/docs/ProxyRegistry/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically, we're going to take a look at the &lt;code&gt;registerProxy&lt;/code&gt; function (&lt;em&gt;represented by function&lt;/em&gt;: &lt;code&gt;ddd81f82&lt;/code&gt;), which allows one to, "&lt;em&gt;register a proxy contract with this registry&lt;/em&gt;" (i.e., &lt;em&gt;registry being OpenSea / Wyvern&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Registering a proxy contract with the registry requires the express permission of the user (&lt;em&gt;via signature via Metamask&lt;/em&gt;). As we read above, each user on OpenSea has a proxy address provisioned for them. And in order for a user to save on gas / allow gasless listings &amp;amp; sales on OpenSea, they only need to forego overriding the &lt;code&gt;isApprovedForAll&lt;/code&gt; function within the ERC standard contract (&lt;em&gt;either 1155 or 721; depending on the type of NFT&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Remember that excerpt from OpenSea's website: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijl51k5my027e74x967o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijl51k5my027e74x967o.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is likely the point at which users were actually phished&lt;/strong&gt;, because this access here is what facilitated the actual theft of NFTs from users at a latter point in time. That claim about this access being the inflection point for wallet compromise is proven via examination of transactions related to affected users. Specifically, the stack trace gives us more than enough information to begin pinpointing the culprit here. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brief Note&lt;/strong&gt;: &lt;em&gt;The smart contract(s) that played a key role in the compromise of affected OpenSea users are not marked on Etherscan; the only exception is the smart contract that's used in the orchestration that's obviously attached&lt;/em&gt; (i.e., it actually emits various event during the execution of the transaction itself) &lt;/p&gt;

&lt;p&gt;The specification for the WyvenProxyRegistry can be found here: &lt;a href="https://abidocs.dev/contracts/0xa5409ec958c83c3f309868babaca7c86dcb077c1" rel="noopener noreferrer"&gt;https://abidocs.dev/contracts/0xa5409ec958c83c3f309868babaca7c86dcb077c1&lt;/a&gt; (check out the contract name in the URL)&lt;/p&gt;

&lt;p&gt;Below is the necesssary code template for those looking make this call on a smart contract (&lt;em&gt;for whatever reasons&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function registerProxy()
    public
    returns (OwnableDelegateProxy proxy) 
{
    require(proxies[msg.sender] == address(0)); 
    proxy = new OwnableDelegateProxy(msg.sender, delegateProxyImplementation, abi.encodeWithSignature("proxies"[msg.sender] = proxy; 
    return proxy; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A reference for functions attached to OpenSea's smart contract orchestration can be found here as well: &lt;a href="https://abidocs.dev/dapps/opensea" rel="noopener noreferrer"&gt;https://abidocs.dev/dapps/opensea&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Specifically, we're going to take a look at how one may want to make use of that function (&lt;em&gt;vs. any of the myriad of other choices they have&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sx6yz72h1ctfrkrrnnt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sx6yz72h1ctfrkrrnnt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As one can see: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;registerProxy&lt;/code&gt; doesn't have &lt;code&gt;onlyOwner&lt;/code&gt; attached it. Functions that do have this modifier attached to them can &lt;strong&gt;only&lt;/strong&gt; be called by the owner of the proxy contract. Yet as we can see one does not have to be the owner to call &lt;code&gt;registerProxy&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is not an event, so nothing is emitted when this function is called &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Within the context of normal OpenSea marketplace behavior, this function is only used when a user is lookiong to purchase an NFT. According to OpenSea "if you're buying an item on Ethereum, the transaction will show as 'registerProxy' / &lt;code&gt;Register Proxy&lt;/code&gt;". &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Proxy contracts exist underneath the umbrella of upgradable contracts. That's why you'll find the variable &lt;code&gt;OwnableDelegateProxy&lt;/code&gt; littered throughout the example code we outlined above. &lt;/p&gt;

&lt;p&gt;Let's take a look at some example code OpenZeppelin gives us for a vanilla contract proxy (&lt;em&gt;will have some minor variances, but the gist is the same&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This code has not been professionally audited, therefore I cannot make any promises about
// safety or correctness. Use at own risk.
contract Proxy {

    address delegate;
    address owner = msg.sender;

    function upgradeDelegate(address newDelegateAddress) public {
        require(msg.sender == owner);
        delegate = newDelegateAddress;
    }

    function() external payable {
        assembly {
            let _target := sload(0)
            calldatacopy(0x0, 0x0, calldatasize)
            let result := delegatecall(gas, _target, 0x0, calldatasize, 0x0, 0)
            returndatacopy(0x0, 0x0, returndatasize)
            switch result case 0 {revert(0, 0)} default {return (0, returndatasize)}
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;ignore the function that deals with&lt;/em&gt; &lt;code&gt;external payable&lt;/code&gt;, &lt;em&gt;we're not going to discuss any assembly code yet at this point&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice there's access restriction in that code excerpt. This access restriction is created by defining &lt;code&gt;address owner = msg.sender&lt;/code&gt; then &lt;code&gt;require(msg.sender == owner)&lt;/code&gt;. On the contrary, for the OpenSea &lt;code&gt;registerProxy&lt;/code&gt; the market is forced to forego this logic in its implementation, instead opting for, &lt;code&gt;require(proxies[msg.sender] == address(0))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason why OpenSea must forego this access restriction is because the buyer is the one making this call (&lt;em&gt;thus, the buyer is the 'sender' in this instance; confusing but stick with me here&lt;/em&gt;). The lack of access restriction is to prevent NFT listers from scamming those who buy their NFTs by yanking them back after receiving payment. &lt;/p&gt;

&lt;p&gt;Remember the function definitions we found for OpenSea's marketplace smart contracts. Specifically, we saw that &lt;code&gt;onlyOwner&lt;/code&gt; was not a modifier attached to the &lt;code&gt;registerProxy&lt;/code&gt; function (&lt;em&gt;since the buyer needs to be able to propose whichever smart contract they desire&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Now let's go back to one of the transactions involving an affected user from February 19th/20th (&lt;em&gt;when folks were getting their NFTs taken left &amp;amp; right, it seemed&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Let's use this TX for reference: 0xfd3ac0804b9f8af8e0185ecc43c855867a04ed10eede2d80295174e5a7024038 &lt;/p&gt;

&lt;p&gt;Specifically, we're going to pipe that TX into 'ethtx.info' (&lt;em&gt;first time ever including tihs site in a report, but I really like it; great for getting the granular details of an Ethereum transaction for reports like these&lt;/em&gt;). Once we pipe that address in to the search, we should wind up here: &lt;a href="https://ethtx.info/mainnet/0xfd3ac0804b9f8af8e0185ecc43c855867a04ed10eede2d80295174e5a7024038/" rel="noopener noreferrer"&gt;https://ethtx.info/mainnet/0xfd3ac0804b9f8af8e0185ecc43c855867a04ed10eede2d80295174e5a7024038/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More than likely your screen will show you the following at the top of the page: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr4wxfmnrnzv63g7l4pp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr4wxfmnrnzv63g7l4pp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's scroll down until reach something called the 'execution trace'. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1rne50ttybcjw2yn7hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1rne50ttybcjw2yn7hn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what gives us information about the various updated states of the transaction as it was processed by nodes / miners on the Ethereum network (&lt;em&gt;this work here is what the gas payments are for; i.e., the more work that needs to do + more congested the network gets, the more one must pay in gas to have their transaction cleared - thus, the commodity for $ETH is gwei at the end of the day&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;This may seem intimidating, but we're going to tackle this one slowly (&lt;em&gt;easier than you think&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Check out what we have below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqgq7polibddbkfg0wwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqgq7polibddbkfg0wwo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the second state update, the 'execution trace' shows us &lt;code&gt;[receiver] 0xa2c0946ad444dccf990394c5cbe019a858a945bd.0x8a10f9ce(call_data=0x000000000000000000000000c99f70bfd82fb7c8f8191fdfbfb735606b...000000) =&amp;gt; ()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Before we pick apart what this means, let's go take a look at that smart contract listed as the &lt;code&gt;[receiver]&lt;/code&gt; there as this was the one smart contract everyone was talking about on Twitter while the actual heist was going on. &lt;/p&gt;

&lt;p&gt;For this, we'll refer to Etherscan: &lt;a href="https://etherscan.io/address/0xa2c0946ad444dccf990394c5cbe019a858a945bd" rel="noopener noreferrer"&gt;https://etherscan.io/address/0xa2c0946ad444dccf990394c5cbe019a858a945bd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen0dhv6h14il7ql0wk03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen0dhv6h14il7ql0wk03.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see above, Etherscan is already all over this address - labeling it &lt;code&gt;Fake_Phishing5176&lt;/code&gt;. However, a more accurate name for this smart contract would be &lt;code&gt;Phisher_GetAwayDriver&lt;/code&gt; or something to that extent &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;mini-rant&lt;/strong&gt;: &lt;em&gt;seriously though, there should be a more standardized method for labeling addresses &amp;amp; smart contracts identified as being a facilitator of some widely known hack / theft / compromise in the community&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's see if we can view the contract code on Etherscan. First, we'll scroll down and click the 'contract' tab. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlsqlcnll8197nn5992l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlsqlcnll8197nn5992l.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it appears (maybe) that there's no such luck for us: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63ewh1o4wyugtfrnjcqy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63ewh1o4wyugtfrnjcqy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, the obvious assumption is that whomever uploaded this contract did so in this manner (&lt;em&gt;no source code available&lt;/em&gt;) with the explicit intent of foiling "armchair investigators" like myself and (the few) others that bother to take any time examining these things. &lt;/p&gt;

&lt;p&gt;However, this may not have been the case. If we revisit that brilliant guide breaking down 'proxy delegates', we'll see that inline assembly was likely a requisite for the attackers to pull off a successful theft of NFT assets from impacted users. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhui9lrgarx70gwgqb9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhui9lrgarx70gwgqb9a.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically we want to note the part where it states, "&lt;em&gt;When using the call in the context of a proxy, however, we are interested in the actual return value of the function call. To overcome this limitation, inline assembly (inline assembly allows for more precise control over the stack machine, with a language similar to the one used by the EVM and can be used within solidity code) has to be used. With the help of inline assembly we are able to dissect the return value of&lt;/em&gt; &lt;code&gt;delegatecall&lt;/code&gt; &lt;em&gt;and return the actual result of the caller&lt;/em&gt;." &lt;/p&gt;

&lt;p&gt;Remember, in order for an NFT sale to execute on OpenSea's platform, there must be a matched buy &amp;amp; sell order. This is validated via examining whether the sender (i.e., 'buyer') of the NFT has properly signed the "call data" created by the seller's proposed sale price. &lt;/p&gt;

&lt;p&gt;This is the Wyvern smart contract that governs that exchange process: &lt;a href="https://github.com/ProjectWyvern/wyvern-ethereum/blob/master/contracts/exchange/ExchangeCore.sol" rel="noopener noreferrer"&gt;https://github.com/ProjectWyvern/wyvern-ethereum/blob/master/contracts/exchange/ExchangeCore.sol&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Critically, the code notes for this contract state, "&lt;em&gt;Buy-side and sell-side orders each provide&lt;/em&gt; &lt;code&gt;calldata&lt;/code&gt; (&lt;em&gt;bytes&lt;/em&gt;) - &lt;em&gt;for a sell-side order, the state transition for sale, for a buy-side order, the state transition to be bought.&lt;/em&gt;" Also, "&lt;em&gt;Along with the calldata, orders provide&lt;/em&gt; &lt;code&gt;replacementPattern&lt;/code&gt;: &lt;em&gt;a bytemask indicating which bytes of the calldata can be changed&lt;/em&gt; (e.g. NFT destination address)." &lt;/p&gt;

&lt;p&gt;That's curious. To digress for a moment, is it possible that users were 'phished' legitimately purchasing NFTs on OpenSea's platform? Before you answer, hold that thought. There's more. &lt;/p&gt;

&lt;p&gt;"&lt;em&gt;When a buy-side and sell-side order are matched, the desired calldatas are unified, masked with the bytemasks, and checked for agreement. This alone is enough to implement common simple state transitions, such as&lt;/em&gt; 'transfer my CryptoKitty to any address' &lt;em&gt;or&lt;/em&gt; 'buy any of this kind of nonfungible token'." &lt;/p&gt;

&lt;p&gt;This is what the &lt;code&gt;atomicMatch_&lt;/code&gt; function we see called on the Wyvern smart contract is emitted for. &lt;/p&gt;

&lt;p&gt;The answer as to how users may have been compromised may lie in a potential instance of proxy collisions as well as the non-upgraded Wyvern contract's acceptance of &lt;code&gt;isValidSignature&lt;/code&gt;  before upgrade vs. after. &lt;/p&gt;

&lt;p&gt;To get a better idea of what's being referred to here, check out the following update to the Wyvern Protocol smart contract orchestration (pushed Jan 31st, 2022; just a couple of weeks before the changes were merged upstream with OpenSea). &lt;/p&gt;

&lt;p&gt;Check them out here: &lt;a href="https://github.com/wyvernprotocol/wyvern-v3/commit/403f866940b4ef304d24c2147bd9503e89e1cec7" rel="noopener noreferrer"&gt;https://github.com/wyvernprotocol/wyvern-v3/commit/403f866940b4ef304d24c2147bd9503e89e1cec7&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Specifically under &lt;code&gt;ExchangeCore.sol&lt;/code&gt;, we can see that the &lt;code&gt;bytes4 constant internal EIP_1271_MAGICVALUE&lt;/code&gt; was changed from &lt;code&gt;0x20c13b0b&lt;/code&gt; to &lt;code&gt;0x1626ba7e&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii8d8oepw13kcj89olx8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii8d8oepw13kcj89olx8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically, the code used to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract ExchangeCore is ReentrancyGuarded, StaticCaller, EIP712 {

    bytes4 constant internal EIP_1271_MAGICVALUE = 0x20c13b0b;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it reads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract ExchangeCore is ReentrancyGuarded, StaticCaller, EIP712 {

    bytes4 constant internal EIP_1271_MAGICVALUE = 0x1626ba7e;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those that do not know, smart contracts do not come with associated private keys. The only type of addresses on Ethereum that come with private keys are EOAs (externally owned accounts). EOAs = regular Joe Blow Ethereum addresses (i.e., no smart contract logic or anything fancy; regular ETH address you generate when you create a new account w Metamask or some other wallet provider). &lt;/p&gt;

&lt;p&gt;So instead there must be another means of validating a signature if its passed from a smart contract. For OpenSea / Wyvern Protocol, that method was governed by ERC1271. &lt;/p&gt;

&lt;p&gt;If you're not familiar with that smart contract standard, look no further than here: &lt;a href="https://eips.ethereum.org/EIPS/eip-1271" rel="noopener noreferrer"&gt;https://eips.ethereum.org/EIPS/eip-1271&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those curious enough to follow the link above, you may have noticed that the suggested magic number for EIP-1271 under the specification = &lt;code&gt;0x1626ba7e&lt;/code&gt; (&lt;em&gt;dating back to solidity 0.5.0; this was written in 2018&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Specifically the sample code given under this EIP is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity ^0.5.0;

contract ERC1271 {

  // bytes4(keccak256("isValidSignature(bytes32,bytes)")
  bytes4 constant internal MAGICVALUE = 0x1626ba7e;

  /**
   * @dev Should return whether the signature provided is valid for the provided hash
   * @param _hash      Hash of the data to be signed
   * @param _signature Signature byte array associated with _hash
   *
   * MUST return the bytes4 magic value 0x1626ba7e when function passes.
   * MUST NOT modify state (using STATICCALL for solc &amp;lt; 0.5, view modifier for solc &amp;gt; 0.5)
   * MUST allow external calls
   */ 
  function isValidSignature(
    bytes32 _hash, 
    bytes memory _signature)
    public
    view 
    returns (bytes4 magicValue);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason for the variation in the &lt;code&gt;bytes4 magicValue&lt;/code&gt; in the Wyvern Protocol (older contract) and the one specified in EIP1271 are the structs that are included under each. &lt;/p&gt;

&lt;p&gt;Judging from the commits to the Wyvern Protcol smart contracts on GitHub, it appears that the biggest change was made with regards to smart contract authentication for validating access restrictions related to calls made on the main smart contract. &lt;/p&gt;

&lt;p&gt;We can see this under the &lt;code&gt;contracts/exchange/ExchangeCore.sol&lt;/code&gt; contract underneath the main repo for WyvernProtocol: &lt;a href="https://github.com/wyvernprotocol/wyvern-v3/commit/403f866940b4ef304d24c2147bd9503e89e1cec7" rel="noopener noreferrer"&gt;https://github.com/wyvernprotocol/wyvern-v3/commit/403f866940b4ef304d24c2147bd9503e89e1cec7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The contract used to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract ExchangeCore is ReentrancyGuard, StaticCaller, EIP712 {
    bytes4 constant internal EIP_1271_MAGICVALUE = 0x20c13b0b;
    bytes internal personalSignPrefix = "\x19Ethereum Signed Message:\n";
// skipping about 150 lines to line 185 
        if (isContract) {
            if (ERC1271(maker).isValidSignature(abi.encodePacked(calculatedHashToSign), signature) == EIP_1271_MAGICVALUE) {
                return true; 
            }
            return false; 
        }
        (uint8 v, bytes32 r, bytes32 s) = abi.decode(signature, (uint8, bytes32, bytes32));
        if (signature.length &amp;gt; 65 &amp;amp;&amp;amp; signature[signature.length-1] == 0x03) {
            if (ecrecover(keccak256(abi.encodePacked(personalSignPrefix,"32",calculatedHashToSign)), v, r, s) == maker) {
                return true; 
            }
        }
    }
// last bracket added for cohesiveness 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two lines that were deleted in the code were: &lt;/p&gt;

&lt;p&gt;(a) &lt;code&gt;if (ERC1271(maker).isValidSignature(abi.encodePacked(calculatedHashToSign), signature) == EIP_1271_MAGICVALUE) {&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(b) &lt;code&gt;bytes4 constant internal EIP_1271_MAGICVALUE = 0x20c13b0b;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;They were replaced with &lt;/p&gt;

&lt;p&gt;(aa) &lt;code&gt;bytes4 constant internal EIP_1271_MAGICVALUE = 0x1626ba7e;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(bb) &lt;code&gt;if (ERC1271(maker).isValidSignature(calculatedHashToSign, signature) == EIP_1271_MAGICVALUE) {&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The swap from &lt;code&gt;abi.encodePacked(calculatedHashtoSign)&lt;/code&gt; to &lt;code&gt;calculatedHashtoSign&lt;/code&gt; was a critical change in the authentication mechanism for smart contracts attempting to make cals calls on the &lt;code&gt;exchange.sol&lt;/code&gt; contract deployed by Wyvern Protocol. &lt;/p&gt;

&lt;h4&gt;
  
  
  Keccak Caching
&lt;/h4&gt;

&lt;p&gt;All contracts deployed before solidity version 0.8.3 were impacted by a bug called &lt;code&gt;KeccakCaching&lt;/code&gt;; according to Etherscan, "&lt;em&gt;The bytecode optimizer incorrectly re-used previously evaluated Keccak-256 hashes. You are unlikely to be affected if you do not compute Keccak-256 hashes in inline assembly&lt;/em&gt;." &lt;/p&gt;

&lt;p&gt;Coincidentally, that's exactly what the malicious smart contract (labeled &lt;code&gt;phishing_contract5961&lt;/code&gt; on Etherscan), did. The source code was not published on Etherscan, but there are plenty of tools in the wild that allow us to decompile the smart contract's ABI (decoding) as well as the involved transactions to get a general feel for how this compromise was executed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi75xxu8wqvo9iebr1e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi75xxu8wqvo9iebr1e0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This bug was not discovered / published about publicly until March 20th 2021 (approx.) on the 'SolidityLang' blog. &lt;/p&gt;

&lt;p&gt;That post can be viewed here: &lt;a href="https://blog.soliditylang.org/2021/03/23/keccak-optimizer-bug/" rel="noopener noreferrer"&gt;https://blog.soliditylang.org/2021/03/23/keccak-optimizer-bug/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the basic gist of how this bug works: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Solidity’s bytecode optimizer has a step that can compute Keccak-256 hashes, if the contents of the memory, over which the Keccak-256 built-in function is invoked, are known during compilation time.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;This step also has a mechanism to determine that two Keccak-256 hashes are equal even if the values in memory are not known during compile time&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;This step had a bug where Keccak-256 hashes of the same memory content, but of different sizes were considered equal.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To synthesize those details, this bug essentially allowed for asserting that a keccak256 hash of some data (i.e., &lt;code&gt;keccak256(0, 32)&lt;/code&gt; or let's say.... &lt;code&gt;keccak256(add(array, 0x20), size)&lt;/code&gt;) [&lt;strong&gt;hint&lt;/strong&gt;: &lt;em&gt;that latter function is located at line 656 of Wyvern's Exchange smart contract&lt;/em&gt; (earlier version; deprecated now), &lt;em&gt;and is also explicitly calculated via in-line assembly, making the contract ripe for those looking to compromise users via OpenSea's market at the time this was the deployed standard&lt;/em&gt;]&lt;/p&gt;

&lt;h4&gt;
  
  
  Making an Educated Guess (Hypothesis)
&lt;/h4&gt;

&lt;p&gt;At this point, what I believe happened is that users that bought certain NFTs (i.e., &lt;code&gt;Bored Ape Yacht Club&lt;/code&gt; NFTs), signed calldata well in &lt;/p&gt;

&lt;p&gt;We'll soon find out that the phishing attack was more than likely executed via the NFTs themselves, but not in the simplistic way originally visioned by 'Checkpoint Research' (all credit to those researchers for exposing various site vulnerabilities that would pull in malicious html code appearing to originate from the same site). &lt;/p&gt;

&lt;p&gt;This attack vector identified by 'Checkpoint Research' is still potent, to be clear. But it is only just one among a gamut of compromise techniques being leveraged against the NFT ecosystem (&lt;em&gt;appears that there is a potent threat actor that's been wreaking havoc on the protocol&lt;/em&gt;). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is still unfinished, so there's no conclusion in here yet and this research doesn't get to the crux of how the compromise of user NFTs was executed back in February 2022; with that said, don't extrapolate anything from what's written above yet. This is just here as a placeholder&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Do Not Purchase CoinKite Hardware Products (Part 1)</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Thu, 04 Nov 2021 03:42:58 +0000</pubDate>
      <link>https://forem.com/librehash/do-not-purchase-coinkite-hardware-products-part-1-3oh</link>
      <guid>https://forem.com/librehash/do-not-purchase-coinkite-hardware-products-part-1-3oh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;originally published on the Librehash blog&lt;/em&gt; (flagship) &lt;em&gt;here&lt;/em&gt; - &lt;a href="https://librehash.org/do-not-purchase-coinkite-hardware-products-part-1/"&gt;https://librehash.org/do-not-purchase-coinkite-hardware-products-part-1/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Their products are vaporware from top to bottom and their premise makes &lt;strong&gt;absolutely zero fucking sense&lt;/strong&gt; (tantamount to pure security theater at times). &lt;/p&gt;

&lt;h2&gt;
  
  
  Starting With 'OpenDime'
&lt;/h2&gt;

&lt;p&gt;There are numerous different product offerings under the 'CoinKite' flagship, so we're going to one by one here in our series, starting with 'OpenDime'.&lt;/p&gt;

&lt;p&gt;Their main site = &lt;a href="https://opendime.com"&gt;https://opendime.com&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Upon visiting the site, visitors are presented with a huge, ugly orange "Buy Now" button which one would presumably click if they wished to order the "OpenDime 4.0" USB device (at the time of writing).&lt;/p&gt;

&lt;p&gt;But let's hold our horses a sec. We need to dig into what this protocol is really about before we make any affirmative decisions. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Quick Note/Observation&lt;/strong&gt;: &lt;em&gt;Whenever 'open' prefixes any product in the tech space, the implication is that the product being provided is "open" as in "open source". Unfortunately, that's far from the case here (seems they just labeled it 'open' for the sake of instilling that association in customers)&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  "The Bitcoin Credit Stick"
&lt;/h3&gt;

&lt;p&gt;Confused on what that means? You aren't the only one. &lt;/p&gt;

&lt;p&gt;On the site, underneath those words, there are various phrases, written in bold, that unravel themselves in succession that describe the alleged characteristics of this device. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1CKQSZMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_84f573968792ac3787f82153dd9a73c5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1CKQSZMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_84f573968792ac3787f82153dd9a73c5.gif" alt="" width="880" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't have the time to sit through all of the animations (you probably don't), no problem - that's what Librehash is for. &lt;/p&gt;

&lt;p&gt;Below is a complete list of all of the unraveled phrases on the site underneath 'The Bitcoin Credit Stick' title (which, itself, is located in the panel beneath the top one, which contains the ugly 'buy now' button we were mentioning prior.&lt;/p&gt;

&lt;p&gt;Next to each one of these phrases, there will be some comment provided. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Internal Private Key"&lt;/strong&gt; = &lt;em&gt;Not sure what's meant by this. Assumption here is that the device stores the private key...internally (where else would it be stored?); guess this is good reassurance though for those that were questioning this..&lt;/em&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"USB Flash Drive"&lt;/strong&gt; = &lt;em&gt;Not the words you want to read. Yes, it may look like a USB device at the end of the day, but it should not literally be a garden-variety USB device. You want to use a device that has some sort of secure, well-developed cryptographic module attached to the chip responsible for the light device's operation. There are some open source options available out there for this (we've already covered a couple of those in the &lt;a class="mentioned-user" href="https://dev.to/librechain"&gt;@librechain&lt;/a&gt;
 channel already); it appears that these guys never consulted those sources though&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Verify Offline"&lt;/strong&gt; = &lt;em&gt;Its impossible to "verify offline", if we're talking about transactions. Crafting a transaction is a&lt;/em&gt; &lt;strong&gt;stateless process&lt;/strong&gt;, &lt;em&gt;which means it can be done entirely offline without running a full node or polling any information from any full node. Thus, the process is independent and mutually exclusive of the functionality of the underpinning blockchain network. This is why new transactions submitted to the chain or the wallet balances of other peers / users that one interacts with claiming to have $BTC must have their balances validated on the internet...&lt;/em&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Off-chain &amp;amp; 100% Private"&lt;/strong&gt; = &lt;em&gt;Bitcoin is not private, therefore this solution isn't either. Period. Also, all transactions confirmed on the Bitcoin blockchain are "on-chain", full stop. So, not sure what is meant or implied with the "off-chain" promo&lt;/em&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"First Bitcoin Bearer Instrument"&lt;/strong&gt; = &lt;em&gt;Have no clue what the fuck this means; looking deeper into this site, next to this same title (Bitcoin Bearer Instrument), is the following excerpt&lt;/em&gt;: "Opendime is a small USB stick that allows you to spend Bitcoin like a dollar bill. Pass it along multiple times. Connect to any USB to check balance. Unseal anytime to spend online. Trust no one." [&lt;strong&gt;so many problems here&lt;/strong&gt;; (a) what is meant by, 'allows you to spend BItcoin like a dollar bill'? (b) "Pass it along multiple times"? so much for '100% privacy', right? ( c ) "connect to any USB to check balance" &lt;a href="https://dev.tod"&gt;&lt;em&gt;so much for 'Verify Offline', right?&lt;/em&gt;&lt;/a&gt; "Unseal anytime to spend online" (unseal what?) (d) "Trust no one" [&lt;em&gt;Bitcoin is already trustless by design, so how could any Bitcoin-based product claim to provide such a benefit as if its not already being enjoyed by users of the protocol?&lt;/em&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Pass it Along Multiple Times"&lt;/strong&gt; = &lt;em&gt;At first glance, no clue what's meant here by this phrase; pass 'what' along?&lt;/em&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Trust No One!"&lt;/strong&gt; = &lt;em&gt;Repeat after me, "Bitcoin is trustless"; 'decentralization' + the concept of architecting the protocol so that the nodes would (or were supposed to be) distributed was a&lt;/em&gt; &lt;strong&gt;means to an end&lt;/strong&gt; (&lt;em&gt;that 'end'&lt;/em&gt; = &lt;strong&gt;trustlessness&lt;/strong&gt;) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You've been lied to and told that 'decentralization' is the innovation of BItcoin. This could not be further from the truth. The internet itself, architecturally and by design, is &lt;strong&gt;decentralized&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluating OpenDime's Features
&lt;/h2&gt;

&lt;p&gt;On the same site where we found all of these bold claims about this USB stick are a host of purported features afforded to users that elect to waaste their money on this crap (if you visited the site, you just need to scroll down a bit to run into said features). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bcweTCkV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_15b0d00199d2be1f3037ce3738eb9240.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bcweTCkV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_15b0d00199d2be1f3037ce3738eb9240.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E9_DoP2v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_cda7e5f6c71cd706d20be399260f7f26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E9_DoP2v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_cda7e5f6c71cd706d20be399260f7f26.png" alt="" width="880" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically, the features (as listed above), are: &lt;/p&gt;

&lt;p&gt;A) &lt;strong&gt;USB Drive&lt;/strong&gt; - "&lt;em&gt;Acts like a read-only USB flash drive. Works with any computer, laptop, or phone. A QR Image and Text files inside contain Bitcoin address and helpful information.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;B) &lt;strong&gt;Ultra Secure&lt;/strong&gt; - "&lt;em&gt;The private key is generated inside the device, and is never known to any human, not even you!&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;C) &lt;strong&gt;No Trust&lt;/strong&gt; - "&lt;em&gt;Given an OpenDime to anyone and they don't need to worry that you can take back the funds later. The private key is strictly in the device itself.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;D) &lt;strong&gt;Free to Use&lt;/strong&gt; - "&lt;em&gt;This is physical Bitcoin as it was meant to be: just hand it to someone and they've got it! Pass it on multiple times! As simple as a handshake. No miner fees, no confirmation delays.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;E) &lt;strong&gt;Open Standards&lt;/strong&gt; - "&lt;em&gt;Uses Bitcoin message signing, normal (non HD) bitcoin payment addresses and payment keys in WIF format.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;F) &lt;strong&gt;Compatibility&lt;/strong&gt; - "&lt;em&gt;The Bitcoin world changes fast but OpenDime is built on the fundamental Bitcoin features that haven't changed in  five years.&lt;/em&gt;" &lt;/p&gt;

&lt;h3&gt;
  
  
  Premature Assessment of These 'Features' = Fucking Terrible
&lt;/h3&gt;

&lt;p&gt;There are a &lt;strong&gt;ton of fucking issues&lt;/strong&gt; with each and every single purported 'feature' of this project from: (a) the listing of some of these items as 'features' or 'benefits' at all (b) Multiple contradictions in the description of these benefits, from one to another (c) Inaccurate statements (d) Exaggerated / untrue claims made (e) Pseudo-features; i.e., for virtually all of the alleged benefits provided for the end user, none of the "issues" supposedly addressed by these features are legitimate issues / threat vectors for Bitcoin users at all &lt;/p&gt;

&lt;p&gt;However, rather than nitpick from a distance, we're going to go through each one of these alleged features with a fine-toothed comb and pick them apart in one of the subsequent articles for this series. &lt;/p&gt;

&lt;p&gt;For now though, we're going to focus on some of the major deficits in the 'OpenDime' product offering. &lt;/p&gt;

&lt;h1&gt;
  
  
  Carving Open 'OpenDime'
&lt;/h1&gt;

&lt;p&gt;"Zooming out" for a second, its critical for users to adjudicate any hardware-based "Bitcoin wallet" product they purchase / are offered through the scope of that product's efficacy in handling any &amp;amp; all sensitive cryptographic data. &lt;/p&gt;

&lt;p&gt;Bitcoin / cryptocurrencies aren't the only thing in life that are underpinned by cryptographic keys or sensitive cryptographic material that must be highly secured &amp;amp; protected. &lt;/p&gt;

&lt;h2&gt;
  
  
  HSMs are Effectively the World's Best Hardware Wallets
&lt;/h2&gt;

&lt;p&gt;HSM stands for, 'Hardware Security Module'. In a nutshell, "The hardware security module (HSM) is a special 'trusted' network computer performing a variety of cryptographic operations: key management, key exchange, encryption, etc." (source - &lt;a href="https://www.cryptomathic.com/news-events/blog/understanding-hardware-security-modules-hsms"&gt;https://www.cryptomathic.com/news-events/blog/understanding-hardware-security-modules-hsms&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Also, see this description for an 'HSM' provided by Thales (to parity the sources used for this critical task of defining these devices): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZQRCVl8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_0ff870f9690726aac5f976372b66a688.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZQRCVl8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_0ff870f9690726aac5f976372b66a688.png" alt="" width="880" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://cpl.thalesgroup.com/encryption/hardware-security-modules"&gt;https://cpl.thalesgroup.com/encryption/hardware-security-modules&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Effectively, it does everything that Bitcoin hardware wallets market themselves as providing ; the only difference is that these solutions are **exponentially more secure than what you see out of your 'garden variety' Bitcoin hardware wallets. &lt;/p&gt;

&lt;p&gt;As we'll see in the next section, there are a number 'boxes' that must be "checked" before we can declare an HSM device (effectively what these products are), to be secure in any capacity. &lt;/p&gt;

&lt;h2&gt;
  
  
  Properties of a Secure HSM Device
&lt;/h2&gt;

&lt;p&gt;One of the best guides for this you'll find anywhere online is located here - &lt;a href="https://wiki.opendnssec.org/display/DOCREF/HSM+Buyers%27+Guide"&gt;https://wiki.opendnssec.org/display/DOCREF/HSM+Buyers%27+Guide&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We're going to briefly summarize some of the finer points included in this document below (as a mini-criteria for what someone should want out of their HSM device)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are four tiers of 'HSM' devices that one can obtain (based on scale of operation, required usage, and features / properties of the HSM device in question necessary for whatever its being purchased for) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J0rP6dyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9d5f7a0dedb7a9e65d4db9301139a67d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J0rP6dyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9d5f7a0dedb7a9e65d4db9301139a67d.png" alt="" width="863" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X6GQhU-V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_51b6188f5c91dfd1c89825bee8aaf0e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X6GQhU-V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_51b6188f5c91dfd1c89825bee8aaf0e6.png" alt="" width="880" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any HSM worth its salt should be compatible with PKCS #11 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X58z0t4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_1067922ef9f839d8e0ba2f579ec78a4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X58z0t4m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_1067922ef9f839d8e0ba2f579ec78a4a.png" alt="" width="880" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The HSM device in question should be audited (by a legitimate security firm qualified to conduct such audits); this audit, in specific, is different from what we have come to expect in the crypto space in relation to "smart contract audits". Instead of being commissioned for the purpose of finding any bugs/glitches/exploits/etc., audits of mission-critical hardware/software like this is usually commissioned and subsequently published publicly for the purposes of providing assurance to the general public via a trusted, reputable 3rd-party source that the construction of the device reflects the type of development / cryptographic acumen a device of this nature must possess. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Device should be compliant with National &amp;amp; International security standards established by the world's foremost Standards Organizations&lt;/strong&gt; (i.e., 'NIST', 'FIPS', 'ISO/IEC', etc.) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;This list is far from comprehensive, but if you're wondering what the most popular compliance standards are that companies seek to align with that are providing a product like this&lt;/strong&gt; (&lt;strong&gt;HSM&lt;/strong&gt;): GDPR, eIDAS, FIPS 140-2 (level 3) , Common Criteria, HIPAA, PCI-DSS, NITES, ANSI X9.24, ISO 13491, ISO 27799, ISO 27002, FedRAMP, GLBA, HIPAA, PIPA, PDPA, UIDAI, PSD2 (&lt;em&gt;among others that aren't listed but compliance with the standard could still be considered desirable, contingent on the use case of the device &amp;amp; the corresponding context of the situation&lt;/em&gt;) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To be clear this 'compliance' label is usually cleared by the standards organization before the manufacturer makes this claim (&lt;em&gt;simply asserting that one's device conforms to these standards without going through this process would do significantly more harm than good in the eyes of the prospective end-user / consumer if that were to ever be discovered &amp;amp; exposed&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is a screenshot of a real certificate (given to Thales by the NIST), certifying that their HSM was FIPS 140 complaint (Level 2). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i8j4_852--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_4630e6f9cc5e3f3e9b3b102c1a645cc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i8j4_852--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_4630e6f9cc5e3f3e9b3b102c1a645cc3.png" alt="" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KMyAGffq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_8ca7bdc9a6178cdd92b78d7e40b2103c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KMyAGffq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_8ca7bdc9a6178cdd92b78d7e40b2103c.png" alt="" width="880" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3205"&gt;https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3205&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Picture of the actual 'Certificate' provided by the U.S. government for the product deemed to meet the threshold requirements of an FIPS-certified device. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oNrBG6Kl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_e7ee0b37f03e7fb4ca64cf6c52e2656e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oNrBG6Kl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_e7ee0b37f03e7fb4ca64cf6c52e2656e.png" alt="" width="880" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/certificates/JuneCertFinal.pdf"&gt;https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/certificates/JuneCertFinal.pdf&lt;/a&gt;&lt;/em&gt; (ignore the quality here; this is the best that the gov't provided on its site of this certificate for whatever reason) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The certificate shown in the screenshot above is simply the first page of a pdf document (linked directly from the NIST website). This next screenshot (from 'page 2' of that same pdf), provides a more granular outlook of the different facets of the HSM that needed to be adjudciated for certification (shown to give readers an idea of how meticulous this process is). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xDtOXE0G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_8139f3ff51fecd25a98c417bd3c3edcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xDtOXE0G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_8139f3ff51fecd25a98c417bd3c3edcb.png" alt="" width="880" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can HSMs be Used for Blockchain?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In Two Words?&lt;/strong&gt;: Hell yes. &lt;/p&gt;

&lt;p&gt;In fact, there are a number of HSM manufacturers out there that have went out of their way to publish documentation on their products' respective site(s), outlining how their device can be purposed for securing one's blockchain addresses / funds. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example One: 'Ultimaco'&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w27pWGEu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_85e030f5885515cf328a855371c2279f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w27pWGEu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_85e030f5885515cf328a855371c2279f.png" alt="" width="880" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://hsm.utimaco.com/blog/why-hsm-is-vital-to-the-blockchain-technologies/"&gt;https://hsm.utimaco.com/blog/why-hsm-is-vital-to-the-blockchain-technologies/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More relevant information can be found here - &lt;a href="https://hsm.utimaco.com/blog/the-key-role-of-hsms-and-key-management-in-secure-permissioned-blockchains-for-banking-and-payment-services-an-overview/"&gt;https://hsm.utimaco.com/blog/the-key-role-of-hsms-and-key-management-in-secure-permissioned-blockchains-for-banking-and-payment-services-an-overview/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Two - Thales Group HSMs&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Thales published an entire whitepaper covering how their HSM devices could be used to provide elite protection for those looking to store $ETH / $BTC keys. &lt;/p&gt;

&lt;p&gt;The prelude to the whitepaper (on their site), states: "&lt;em&gt;Secure cold storage of cryptocurrencies such as Bitcoin or Ethereum, is a difficult and complex challenge. Traditional paper wallet-based solutions may be effective for the most basic use cases, but they present a substantial challenge for more complex environments as they do not scale, or address compliance requirements for strong key management.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;That whitepaper can be found here - &lt;a href="https://cpl.thalesgroup.com/sites/default/files/content/solution_briefs/field_document/2020-03/Securing_Blockchain_Ledger_ProtectServer_HSM_SB_v8.pdf"&gt;https://cpl.thalesgroup.com/sites/default/files/content/solution_briefs/field_document/2020-03/Securing_Blockchain_Ledger_ProtectServer_HSM_SB_v8.pdf&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0CBH0-cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_161567bf496c690446c320039142d722.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0CBH0-cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_161567bf496c690446c320039142d722.png" alt="" width="880" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://cpl.thalesgroup.com/resources/encryption/blockchain-protectserver-hsm-solution-brief"&gt;https://cpl.thalesgroup.com/resources/encryption/blockchain-protectserver-hsm-solution-brief&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below is an excerpt from that whitepaper (pdf document): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cMFR2RtS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2a9f81a1924311f6866fdf6507ae4a2e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cMFR2RtS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2a9f81a1924311f6866fdf6507ae4a2e.png" alt="" width="880" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source HSM Solutions (for cheap)
&lt;/h2&gt;

&lt;p&gt;The best commercially available HSM solution out there, hands down (for those that don't want to get into tinkering with chips &amp;amp; hardware), is the 'Nitrokey 3'. &lt;/p&gt;

&lt;p&gt;You can read about the features that come with this key here - &lt;a href="https://www.nitrokey.com/news/2021/new-nitrokey-3-nfc-usb-c-rust-common-criteria-eal-6"&gt;https://www.nitrokey.com/news/2021/new-nitrokey-3-nfc-usb-c-rust-common-criteria-eal-6&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TMRgE0I8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_932d349e78fef65b2cd523c631b18b7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TMRgE0I8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_932d349e78fef65b2cd523c631b18b7b.png" alt="" width="880" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;these are some pretty significant features, right?&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;^^ That summary doesn't provide a comprehensive list of the benefits afforded by one of these devices. &lt;/p&gt;

&lt;p&gt;Those benefits are presented below (screen'd from the site): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k9gmg5T---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_4bffa31dd6d059d8567622f51df653c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k9gmg5T---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_4bffa31dd6d059d8567622f51df653c3.png" alt="" width="880" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TDmd6u-G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b21537c6d28af3585032e78ac247427b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TDmd6u-G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b21537c6d28af3585032e78ac247427b.png" alt="" width="880" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eq2UUQP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_153d5a5c7a4481b331c26193fd9873bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eq2UUQP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_153d5a5c7a4481b331c26193fd9873bd.png" alt="" width="880" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's not all though, Nitrokey also provides a breakdown of the security technology embedded in these devices (and each component's respective role in the greater design of this mini-HSM product). &lt;/p&gt;

&lt;p&gt;Fortunately for NitroKey users, the project is &lt;strong&gt;entirely open source&lt;/strong&gt; (both the firmware &lt;strong&gt;and&lt;/strong&gt; hard ware provided; 'OpenDime' only open sourced their firmware, which does little to provide us with the assurance one would desire when entrusting a device to effectively secure &lt;strong&gt;all of your hard-earned crypto funds&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;The above referenced 'Security Technology' is outlined in the screenshots published below form the site, for convenience: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lSVI6480--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_94a579be91011e7ab477accbeda41b04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lSVI6480--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_94a579be91011e7ab477accbeda41b04.png" alt="" width="880" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5Unrhstb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_ee2386dcac26fe74a93c67bc0e4a0807.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Unrhstb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_ee2386dcac26fe74a93c67bc0e4a0807.png" alt="" width="880" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait, there's more&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;If you visit the product page of NitroKey's site, you'll find a list of some of the general security assurances their devices afford users across the board (regardless of what is purchased). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Of-73Ive--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_20ea59a1d267fdabd731a1c40a5d809f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Of-73Ive--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_20ea59a1d267fdabd731a1c40a5d809f.png" alt="" width="880" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xTMUpA0t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_5181e1cb0bde4818874b17010722599a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xTMUpA0t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_5181e1cb0bde4818874b17010722599a.png" alt="" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XIVhTv0q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_53af143cd6fd0909e80bd8abe69e3948.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XIVhTv0q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_53af143cd6fd0909e80bd8abe69e3948.png" alt="" width="880" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kYcXPm8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_18bfd3a6b99ac0946356e14d005eab56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kYcXPm8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_18bfd3a6b99ac0946356e14d005eab56.png" alt="" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3qEo3PTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_351b6d612a27bd289ad82384fee96ac9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3qEo3PTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_351b6d612a27bd289ad82384fee96ac9.png" alt="" width="880" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Revisit the 'OpenDime' Features Again
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cSJop7tg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_27c886bf45cfc5e415be7100ac24996c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cSJop7tg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_27c886bf45cfc5e415be7100ac24996c.png" alt="" width="880" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;from the main site&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://opendime.com/"&gt;https://opendime.com/&lt;/a&gt;&lt;/em&gt; (non-descript, vague "features" that are effectively unable to be verified beyond the statements on the website itself)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hard to argue that this device provides a compelling and/or competitive use case in light of what we just learned in this article. But - who knows? Maybe this product makes up for it in its pricing (comparatively). &lt;/p&gt;

&lt;p&gt;Fortunately, we don't have to speculate on this as the companies responsible for bringing each respective product to market have the price point for these items published online at the time of writing. &lt;/p&gt;

&lt;h4&gt;
  
  
  Price of 'OpenDime' / ColdCard Device
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--it1maHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bc832780ff156a63688d5999a25cb09f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--it1maHjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bc832780ff156a63688d5999a25cb09f.png" alt="" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://store.coinkite.com/store/opendime"&gt;https://store.coinkite.com/store/opendime&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As we can see in the screenshot above, the price of an 'OpenDime' &lt;strong&gt;disposable USB device&lt;/strong&gt; (3-pack) at the time of writing is approximately, $49-59. &lt;/p&gt;

&lt;p&gt;Let's see how much the NitroKeys are going for. &lt;/p&gt;

&lt;h4&gt;
  
  
  Price of NitroKey 3 HSM
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WN6CL-iI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_97993e7553a3757be6aa983f968a745d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WN6CL-iI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_97993e7553a3757be6aa983f968a745d.png" alt="" width="880" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://shop.nitrokey.com/shop/product/nk3cn-nitrokey-3c-nfc-148"&gt;https://shop.nitrokey.com/shop/product/nk3cn-nitrokey-3c-nfc-148&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Per the screenshot above, it appears that this key is going for 49 &lt;strong&gt;euros&lt;/strong&gt;, which equates to ~$56 at the time of writing. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vbwx8oIv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a673c9b82b5cd7b2dde06391cb3f6f91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vbwx8oIv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a673c9b82b5cd7b2dde06391cb3f6f91.png" alt="" width="880" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There is none, this is only part one. We have a hell of a lot more to discuss here. &lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>security</category>
    </item>
    <item>
      <title>Brief ETH Wallet Security Guide</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Sun, 17 Oct 2021 16:05:33 +0000</pubDate>
      <link>https://forem.com/librehash/brief-eth-wallet-security-guide-2m4d</link>
      <guid>https://forem.com/librehash/brief-eth-wallet-security-guide-2m4d</guid>
      <description>&lt;p&gt;I would recommend taking a look at some of the following links (if you're interested); wouldn't bash Metamask for no reason, but there are just certain facets of their wallet app that make it wholly insecure (in my opinion &amp;amp; in that of most security researchers 'in the wild', I would imagine): &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/librehash/status/1339040262753038343?s=20"&gt;https://twitter.com/librehash/status/1339040262753038343?s=20&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/librehash/status/1361214665519423488?s=20"&gt;https://twitter.com/librehash/status/1361214665519423488?s=20&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are many more reasons that can be listed, but I won't get into those here. &lt;/p&gt;

&lt;p&gt;Let's just move forward toward ensuring that we can generate a secure Ethereum address. &lt;/p&gt;

&lt;h3&gt;
  
  
  Securing a Metamask Wallet
&lt;/h3&gt;

&lt;p&gt;Despite all of the drawbacks and negatives listed above, there is a way to ensure that your Metamask wallet is a &lt;strong&gt;secure construction&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The first step to doing so would be downloading Ian Coleman's BIP39 site, located here: &lt;a href="https://iancoleman.io/bip39/"&gt;https://iancoleman.io/bip39/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon visiting the site, you should see something like the following: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--skECoEGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_042dd3e94859490750e1d3acef330542.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--skECoEGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_042dd3e94859490750e1d3acef330542.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to download this tool (safely) for use offline, we're going to visit the official GitHub repo for this page. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dHcSxCP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b0b67423ce37c3bcd7ebff144c01f603.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dHcSxCP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b0b67423ce37c3bcd7ebff144c01f603.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Specifically, we're going to visit: &lt;a href="https://github.com/iancoleman/bip39"&gt;https://github.com/iancoleman/bip39&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;From there, we're going to check out the latest releases (&lt;a href="https://github.com/iancoleman/bip39/releases/tag/0.5.3"&gt;https://github.com/iancoleman/bip39/releases/tag/0.5.3&lt;/a&gt;). &lt;/p&gt;

&lt;h4&gt;
  
  
  Ian Coleman Values Our Security
&lt;/h4&gt;

&lt;p&gt;If we checkout the releases, we'll notice that there's an attached PGP signed message accompanying each release (SHA-512) published by Ian Coleman. &lt;/p&gt;

&lt;p&gt;The PGP  message specifically clear signs the sha256 checksum of the bip39-standalone.html page that gets produced after we download &amp;amp; unzip the relevant files. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MSGQ1Gz8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9a58bd0d2b04317d664a6dfa7ef17f9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MSGQ1Gz8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9a58bd0d2b04317d664a6dfa7ef17f9f.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the option of either downloading the standalone html file or the entire source code for the file (either or works; we're going to go with the source in this instance though). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x5HFBd03--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9af1135ee577fb17669fd0ba5e7e838c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x5HFBd03--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9af1135ee577fb17669fd0ba5e7e838c.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Unpacking the Source and Running the Code
&lt;/h3&gt;

&lt;p&gt;This can all be done in a couple simple commands. &lt;/p&gt;

&lt;p&gt;If you're a terminal person, these next steps are for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-tlsv1&lt;/span&gt;.3  https://github.com/iancoleman/bip39/archive/refs/tags/0.5.3.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming that this doesn't work for whatever reason, that simply means that the latest version of 'curl' likely needs to be installed on one's computer (there's going to be a little bit of footwork mandated with this portion of things if you're truly interested, but its all encapsulated within one concise script for those that need it). &lt;/p&gt;

&lt;h4&gt;
  
  
  Installing Curl
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;this step is only for people that want to ensure that they have an insane level of security in their default setups; never a bad idea to do this though and ensure that you have the latest versions of all of the best libraries that are needed to build the requisite tools needed to stay on the cutting edge of security&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The below script can be saved to a file (with any name) on the terminal, then subsequently activated via chmod +x (filename).(ending) in order to ensure that it can be ran at some point in the future.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; upgrade &lt;span class="c"&gt;# hopefully there are no funky problems on the machine that you're using ; could loop this through a command that first checks out the OS that someone is running first, then uses the appropriate packet manager based on the grepped &amp;amp; saved response (to a fd of some sort in the intermediate; random one preferably I suppose) &lt;/span&gt;
&lt;span class="c"&gt;# assuming ubuntu / debian for the rest of the commands here &lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;astyle cmake gcc ninja-build libssl-dev python3-pytest python3-pytest-xdist unzip xsltproc doxygen graphviz build-essential 
wget https://curl.se/download/curl-7.77.0.tar.gz
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvf&lt;/span&gt; curl-&lt;span class="k"&gt;*&lt;/span&gt;.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;curl-&lt;span class="k"&gt;*&lt;/span&gt;
./configure &lt;span class="nt"&gt;--with-openssl&lt;/span&gt; &lt;span class="nt"&gt;--with-libssh2&lt;/span&gt; &lt;span class="nt"&gt;--with-zlib&lt;/span&gt; &lt;span class="nt"&gt;--with-brotli&lt;/span&gt; &lt;span class="nt"&gt;--with-zstd&lt;/span&gt; &lt;span class="nt"&gt;--with-gssapi&lt;/span&gt; &lt;span class="nt"&gt;--with-gsasl&lt;/span&gt; &lt;span class="nt"&gt;--enable-tls-srp&lt;/span&gt; &lt;span class="nt"&gt;--enable-threateded-resolver&lt;/span&gt; &lt;span class="nt"&gt;--enable-ipv6&lt;/span&gt; &lt;span class="nt"&gt;--enable-unix-sockets&lt;/span&gt; &lt;span class="nt"&gt;--enable-manual&lt;/span&gt; &lt;span class="nt"&gt;--enable-sspi&lt;/span&gt; &lt;span class="nt"&gt;--enable-ldaps&lt;/span&gt; &lt;span class="nt"&gt;--enable-rtsp&lt;/span&gt; &lt;span class="nt"&gt;--enable-librtmp&lt;/span&gt; &lt;span class="nt"&gt;--with-libmetalink&lt;/span&gt; &lt;span class="nt"&gt;--with-libpsl&lt;/span&gt; &lt;span class="nt"&gt;--with-nghttp2&lt;/span&gt; &lt;span class="nt"&gt;--disable-telnet&lt;/span&gt; &lt;span class="nt"&gt;--enable-libcurl-option&lt;/span&gt; &lt;span class="nt"&gt;--with-libmetalink&lt;/span&gt; &lt;span class="nt"&gt;--with-ngtcp2&lt;/span&gt; &lt;span class="nt"&gt;--with-quiche&lt;/span&gt; &lt;span class="nt"&gt;--enable-mime&lt;/span&gt; &lt;span class="nt"&gt;--enable-netrc&lt;/span&gt; &lt;span class="nt"&gt;--enable-get-easy-options&lt;/span&gt; &lt;span class="nt"&gt;--enable-dnsshuffle&lt;/span&gt; &lt;span class="nt"&gt;--enable-hsts&lt;/span&gt; &lt;span class="nt"&gt;--enable-sspi&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;make 
&lt;span class="nb"&gt;sudo &lt;/span&gt;make &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="c"&gt;# sudo make check &lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;make &lt;span class="nb"&gt;install&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, we need to look for where the 'curl' binary is at (more than likely, we didn't replace the previous longstanding curl binary with this command ; not a problem though) &lt;/p&gt;

&lt;p&gt;We'll just have to run the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh &lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/Downloads/backups/
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; ~/.bashrc ~/Downloads/backups/.bashrcbackup
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt;&amp;gt;~/.bashrc
curl() {
    location/of/newlydownloaded/curl "&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="sh"&gt;"
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="c"&gt;# at this point the little curl command path we included above should be the path that's consulted first &lt;/span&gt;
&lt;span class="nb"&gt;exec &lt;/span&gt;bash &lt;span class="c"&gt;# this should renew the bash terminal &lt;/span&gt;
which &lt;span class="nt"&gt;-a&lt;/span&gt; curl &lt;span class="c"&gt;# this should tell us which curl will be used ultimately but if not then we can use the next cmd &lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$curl&lt;/span&gt; &lt;span class="c"&gt;# the result of this command should mimic what we just appended ~/.bashrc with &lt;/span&gt;
&lt;span class="c"&gt;# could add extra code that saves the output of either command above to assess whether they match what should be expected from a string we extract from the ~/.bashrc that gets grepped out but...too lazy, do it yourself if you are a reader &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this script is done executing, one just needs to type 'type curl' and the result should be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl is a &lt;span class="k"&gt;function 
&lt;/span&gt;curl&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    /path/to/new/curlsrc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this is the case, then you're good to go. Now all you have to do is run the necessary code to extract the ian coleman repo from its place on GitHub. &lt;/p&gt;

&lt;p&gt;That would be (make sure to double check the URLs on your end):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh &lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/tmpdownload
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/tmpdownload
curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-tlsv1&lt;/span&gt;.3 https://github.com/iancoleman/bip39/archive/refs/tags/0.5.3.tar.gz &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; iancole.tar.gz
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvf&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;bip39-&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="c"&gt;# from here we're going to open up the webpage using firefox (assuming everyone has that downloaded)&lt;/span&gt;
firefox &lt;span class="nt"&gt;--new-instance&lt;/span&gt; &lt;span class="nt"&gt;--browser&lt;/span&gt; &lt;span class="nt"&gt;--private-window&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/src/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;All of the scripts above could be included in one bigger script, or there could just be a larger script created that calls each of these (or we can just create each one of the scripts above in one greater script). Doesn't really matter which choice we opt with.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressing any and All Concerns Associated with the Browser Use of the Script
&lt;/h3&gt;

&lt;p&gt;The command that I used to open the 'index.html' in firefox:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firefox &lt;span class="nt"&gt;--new-instance&lt;/span&gt; &lt;span class="nt"&gt;--browser&lt;/span&gt; &lt;span class="nt"&gt;--private-window&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/src/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command: &lt;/p&gt;

&lt;p&gt;a) calls firefox &lt;/p&gt;

&lt;p&gt;b) ensures that a new instance is instantiated &lt;/p&gt;

&lt;p&gt;c) ensures that the browser is called (vs. the headless version) &lt;/p&gt;

&lt;p&gt;d) private window ensures that no cookies / history is saved at all &lt;/p&gt;

&lt;p&gt;e) $(pwd)/src/index.html = location of the file we want to open up in the browser ; we want to make sure to only run this command from the root directory, otherwise we need to specify the explicit path that must be followed to enable these commands. &lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerizing the Application
&lt;/h3&gt;

&lt;p&gt;For those that may be even more paranoid than the most paranoid (assuming they are the ones that would have followed the above precautions), it would be recommended to dockerize or otherwise sandbox the application itself to ensure some level of isolation from the root / bare-metal / OS layer. &lt;/p&gt;

&lt;p&gt;Regardless, there's a full guide that breaks this down for anybody that's curious as well (that will be included separately). &lt;/p&gt;

&lt;h3&gt;
  
  
  Assuming Everything Went Right and the Page is Offline
&lt;/h3&gt;

&lt;p&gt;This is when we'll go ahead and generate a new 24-word mnemonic from the app itself. &lt;/p&gt;

&lt;p&gt;We can do this one of two ways - we can either generate it using a random mnemonic (which it pulls from secure sources) or we can generate it from a hexadecimal source. &lt;/p&gt;

&lt;p&gt;If you're not sure what either of those things means, then follow us on a brief journey below as we craft our own secure Ethereum wallet, starting with the Ian Coleman webpage that we downloaded initially. &lt;/p&gt;

&lt;h4&gt;
  
  
  Setting the Stage: Step One
&lt;/h4&gt;

&lt;p&gt;Once you visit the Ian Coleman page, you should be greeted with a screen that looks like this one: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hR8VcXgm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_dff2f401d8e20b1b831c464e763f2aca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hR8VcXgm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_dff2f401d8e20b1b831c464e763f2aca.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once there, you're going to click on the dropdown menu where the number '15' is located and select '24' instead. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n4ouNi_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2e715e06836fc42d54d1caefd25f09e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n4ouNi_k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2e715e06836fc42d54d1caefd25f09e7.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that's selected, we will then press the button that says, 'Generate'. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iSakE1A9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_ea78b4ea67444ff5ac0a87adfe13b205.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iSakE1A9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_ea78b4ea67444ff5ac0a87adfe13b205.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you may have expected, 24 words will be generated (at random*) in the box below. &lt;/p&gt;

&lt;p&gt;Check out the 24 words that were given to us: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b7Eygj6r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9af55a67f73af0cbef7879a630c794dd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b7Eygj6r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9af55a67f73af0cbef7879a630c794dd.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;report concert educate dirt door sorry season inject manual mixture logic item text indicate square wrap strike welcome permit frost sweet twelve round warrior &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we scroll a bit further, we can see that we're presented with other information, such as our wallet seed and our BIP32 root key. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yb-CoVIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bb07facb90590fe30e03ff80f0572698.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yb-CoVIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bb07facb90590fe30e03ff80f0572698.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you notice, there's also a section where one can select the specific coin that they wish to use. This was left on 'Bitcoin' on purpose to  allow this section to be a reminder that &lt;strong&gt;we need to adjust the coin to Ethereum if we're going to be producing a wallet for Metamask&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KRnhn7Yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_35a2c995ddc9a4b60c93172256cf491c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KRnhn7Yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_35a2c995ddc9a4b60c93172256cf491c.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;if you're curious why this is, the reason is that Ethereum uses a different hash operation in the creation of its addresses than Bitcoin does (pre-finalized version of the Keccak hash algorithm)&lt;/em&gt;; Certain apps and blockchains use an entirely different word list than the BIP39 prevailing defalt 2048 word, word-list. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What was just demonstrated above was the "easy" way to create an Etheruem address. &lt;/p&gt;

&lt;p&gt;This method is still secure, for the most part, but it does put the formation of your address up to some level of "chance" (i.e., contingent on the quality of the source of randomness used). &lt;/p&gt;

&lt;h3&gt;
  
  
  Quality of the Randomness Source
&lt;/h3&gt;

&lt;p&gt;This si something that is critically important for anyone that's looking to generate a secure wallet (that won't be compromised at any point in the foreseeable future). &lt;/p&gt;

&lt;p&gt;If you're thinking to yourself, 'What are the chances that someone could possibly guess my private key?', the answer is "Significant" if your source of randomness is &lt;strong&gt;not sufficiently random&lt;/strong&gt; (i.e., someone is able to deduce the range / realm of results that the random number generator you're using tends to produce).&lt;/p&gt;

&lt;h4&gt;
  
  
  Prior Incidents
&lt;/h4&gt;

&lt;p&gt;Back in 2013, there were a slew of Bitcoin users that ended up losing their funds. The one commonality among all of the thefts was the app that produced the compromised wallet addresses at the time. &lt;/p&gt;

&lt;p&gt;Cybersecurity firm, 'Sophos' covered the incident at the time. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://nakedsecurity.sophos.com/2013/08/12/android-random-number-flaw-implicated-in-bitcoin-thefts/"&gt;https://nakedsecurity.sophos.com/2013/08/12/android-random-number-flaw-implicated-in-bitcoin-thefts/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;What's curious about this situation is that the wallets were not inherently compromised by the way that the formed, but rather by the signatures. &lt;/p&gt;

&lt;p&gt;Since this is outside of the scope of what we're doing (since we're only creating a secure address vs. using it in a secure manner), this guide is going to go ahead and omit details about using it in a secure manner. &lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>cryptography</category>
      <category>security</category>
    </item>
    <item>
      <title>Mina Protocol Debunked </title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Sun, 17 Oct 2021 14:51:20 +0000</pubDate>
      <link>https://forem.com/librehash/mina-protocol-debunked-303c</link>
      <guid>https://forem.com/librehash/mina-protocol-debunked-303c</guid>
      <description>&lt;p&gt;Since it appears that this project is garnering a ton of attention on social media recently (on TikTok, specifically), it felt incumbent upon Librehash to ensure that due diligence is performed on this once-in-a-lifetime opportunity to obtain a cryptocurrency of epic proportions. &lt;/p&gt;

&lt;p&gt;Despite the hype around this project on TikTok, there isn't too much information out about it (outside of its official channels), so that's where we'll start for good measure. &lt;/p&gt;

&lt;h3&gt;
  
  
  Visiting the Mina Protocol Website
&lt;/h3&gt;

&lt;p&gt;The official Mina Protocol website can be found here: &lt;a href="https://minaprotocol.com" rel="noopener noreferrer"&gt;https://minaprotocol.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Per their site, Mina Protocol states that they are, "The world's lightest blockchain, powered by participants" (aren't all blockchains de facto powered by participants as part of the 'peer-to-peer' characteristic that they're all supposed to feature?). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_fa1811b0125340ead832fd453abeb28f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_fa1811b0125340ead832fd453abeb28f.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The website goes on to state that: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Mina is building a privacy-preserving gateway between the real world and crypto - and the infrastructure for the secure, democratic future we all deserve." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The website goes on to boast the blockchain's tiny size (comparative to that of other blockchains that are currently in existence), in another statement on the site proclaiming, "By design, the entire Mina blockchain is about 22kb - the size of a couple of tweets. So participants can quickly sync and verify the network." &lt;/p&gt;

&lt;h3&gt;
  
  
  Deconstructing the Claim Mina Protocol is Making About Size
&lt;/h3&gt;

&lt;p&gt;When it comes to blockchain, size is largely an inevitability since the blockchain itself is supposed to serve as a &lt;strong&gt;ledger&lt;/strong&gt; for any and &lt;strong&gt;all transactions that have been mined in a block from its Genesis&lt;/strong&gt; (first block) to the present time of examination. &lt;/p&gt;

&lt;p&gt;However, even with this in mind, this still doesn't explain to us why blockchains are so large in size. &lt;/p&gt;

&lt;p&gt;Below are the total blockchains sizes of a few popular Proof of Work-based projects: 340.21 GB&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bitcoin&lt;/strong&gt; - 340.21 GB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Litecoin&lt;/strong&gt; - 44.81 GB &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ethereum&lt;/strong&gt; - 6.9 TB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bitcoin Cash&lt;/strong&gt; - 192.38 GB &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You get the picture at this point. &lt;/p&gt;

&lt;h3&gt;
  
  
  Prime Contributors to the Block Size
&lt;/h3&gt;

&lt;p&gt;It may be known that the sheer volume of transactions on these chains contributes to their overall block size, but that doesn't tell us what the prime contributor is. &lt;/p&gt;

&lt;p&gt;Fortunately, that answer is easy to source. &lt;/p&gt;

&lt;h4&gt;
  
  
  Cryptography Signatures and Public Keys
&lt;/h4&gt;

&lt;p&gt;Let's take a second and evaluate exactly how a Bitcoin wallet is constructed (on a technical level). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First step is to generate a random seed (usually from entropy; "randomness")&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We're going to pipe that random seed into the ecdsa (secp256k1) formula to generate a private key for ourselves. Assuming that we're iterating Bitcoin keys in their 'compressed' form, the key that's generated &lt;strong&gt;must be 32 bytes&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_f027628efef06a179839934fd968630c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_f027628efef06a179839934fd968630c.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Above is a screenshot from the 'Bitcoin Forgein' tool, located here&lt;/strong&gt;: &lt;a href="https://improvein.github.io/bitcoin-forge/#/cryptography/keys" rel="noopener noreferrer"&gt;https://improvein.github.io/bitcoin-forge/#/cryptography/keys&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As we all know, the private key does not get stored on the protocol but rather a &lt;strong&gt;representation of the public key&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To be specific: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The public key is generated from the private key (by calculating the corresponding 'y' coordinate point for the 'x' [private key; generated from the 'G' generator point multiplied by the 'r' random value [derived from entropy] to [hopefully] manifest a "random" point on the curve) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The public key &lt;strong&gt;is a signed integer&lt;/strong&gt; (i.e., you must decide whether its negative or positive). If you opt to make the public key positive, then you need to prefix it with '02', otherwise '03' must be prefixed to symbolize a negative value for the public key. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iterate the SHA256 operation over the public key &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compress the public key down to 20 bytes by performing a ripemd160 operation on the SHA256 output &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prepend a version byte to signify the network the key is being generated for (i.e., '0x00' for the Bitcoin mainnet) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You then SHA256 hash the ripemd160 output (with the 0x00 byte prepended to it) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SHA256 the output of number six. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take the first four bytes of the output of number seven (that's the first 8 characters in hexadecimal); write down these bytes on a piece of paper or take a mental note of them &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember the original 20-byte output we generated from stage '4'? We're going to append those '4' bytes to the end of that output (keep the 0x00 prepended to the front of the ripemd160 result) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Serialize the address using base58check encoding (this is a special construction created just for Bitcoin &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Other Facets of  a Transcation
&lt;/h4&gt;

&lt;p&gt;Let's take a quick look at your 'typical' run of the mill transaction to refresh ourselves: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_067d5ce61cbc0bbcf2d5af59b90cbeab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_067d5ce61cbc0bbcf2d5af59b90cbeab.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://bitaps.com/831d8df2136ef7ede3e20c366bfa1ce5c45d67afef664b4cbb1cbf5736c1b90d" rel="noopener noreferrer"&gt;https://bitaps.com/831d8df2136ef7ede3e20c366bfa1ce5c45d67afef664b4cbb1cbf5736c1b90d&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the screenshot above, the following can be observed: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There's one input transaction (sender) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are six output transactions &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fortunately, Bitaps provides us with greater transaction details (i.e., the scripts involved), which allow us to count the total size taken up by just the addresses alone: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_e9781af315ab222a90c583b6197d65bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_e9781af315ab222a90c583b6197d65bd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;For the input, we can see that a total of 136 bytes alone &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The output addresses, combined, account for 120 bytes &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Altogether the addresses in this transaction account for 256 bytes. &lt;/p&gt;

&lt;p&gt;However, this does not represent the totality of the transaction itself - we still need to identify how much size is taken by the signature in this transaction (mandatory for the transaction to go through; we know this because there is a 'op_equalverify', 'op_checksig' opcode directive at the end of 4 of those addresses. &lt;/p&gt;

&lt;p&gt;Below is an illustration of the 'Script' smart contracting language for Bitcoin for transactions such as these: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c521b82b3015f7499f1155489c7de8a0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c521b82b3015f7499f1155489c7de8a0.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, transactions like only resolve when the mandate for a signature that corresponds with the identified public key has been met. &lt;/p&gt;

&lt;p&gt;Since BIP64, all Bitcoin cryptographic-related material is supposed to be encoded in 'DER' format. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_a1758e70589bf4cd37e3529d43944f82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_a1758e70589bf4cd37e3529d43944f82.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://en.bitcoin.it/wiki/BIP_0062" rel="noopener noreferrer"&gt;https://en.bitcoin.it/wiki/BIP_0062&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, the size of a transaction for a Bitcoin transaction &lt;strong&gt;must be 64 bytes&lt;/strong&gt; (anything lower than that is a malformed signature): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_2a2cddaad397f40523f641988fcf5ff1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_2a2cddaad397f40523f641988fcf5ff1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, the &lt;strong&gt;average transaction&lt;/strong&gt; for Bitcoin will come to a size of about 150-250 bytes (for a first-time send with no more than one input and one output [no change address]). &lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluating the Preposterous Nature of Mina Protocol's Claim
&lt;/h3&gt;

&lt;p&gt;In light of what was explained above, we should be incredulous of Mina Protocol's claim that they've figured out how to compress the size of their network's blockchain to no more than 2.2Kb total. &lt;/p&gt;

&lt;p&gt;This total represents 14.5 of the smallest Bitcoin transactions (one input &amp;amp; one output). If we're looking at the gamut of transactions that have passed through the Bitcoin protocol, there are singular transactions that have exceeded this limit. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compression World Records&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;To date, the world record for compression condenses information from sample Wikipedia pages (to serve as an ample writing sample to test the prowess of the compression algorithm submissions' effectiveness against bricks of real, legitimate English text). &lt;/p&gt;

&lt;p&gt;Fabrice Bellard (world-renowned computer scientist), was only able to compress the sample down to roughly 10% of its total size. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_fc436ac4ba486c0848fac2a18e642e17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_fc436ac4ba486c0848fac2a18e642e17.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://bellard.org/nncp/readme-gpt2tc.txt" rel="noopener noreferrer"&gt;https://bellard.org/nncp/readme-gpt2tc.txt&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Taking all of this into consideration, we should be sufficiently excited to read into how the Mina Protocol has managed to expand former theoretical constraints for what was considered possible in the field of computing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Recursive Snarks?
&lt;/h3&gt;

&lt;p&gt;Upon clicking the link located on the Mina Protocol frontpage (titled, 'See the Tech'), we're taken to the following page: &lt;a href="https://minaprotocol.com/tech" rel="noopener noreferrer"&gt;https://minaprotocol.com/tech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is on this page where the 'secret' to the Mina Protocol's extraordinary compression ratio secrets are revealed: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_d716c82a86552639ba4512f4a339d7c2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_d716c82a86552639ba4512f4a339d7c2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the photo above, the Mina Protocol team states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Rather than apply brute computing force, Mina users advanced cryptography and recursive zk-SNARKs to deliver true decentralization at scale." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Gaining a Better Understanding of Why Mina Protocol Believes Their Blockchain Can Be 2.2Kb
&lt;/h4&gt;

&lt;p&gt;The misconception here is a bit comical (and very much akin to the one that Coda Protocol had a few years ago). &lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluating Similar Claims by the Coda Protocol
&lt;/h3&gt;

&lt;p&gt;For those that remember, the Coda Protocol similarly claimed that they were able to compress the size of the blockchain to just a few kb due to their use of Snarks. &lt;/p&gt;

&lt;p&gt;Specifically, in their whitepaper (Abstract) Coda stated: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We introduce the notion of a succinct blockchaikn, a replicated machine in which each state transition (block) can be efficiently verified in constant time regardless of the number of prior transactions in the system." &lt;/p&gt;

&lt;p&gt;"Traditional blockchains require verification time linear in the number of transitions. We show how to construct a succinct blockchain using &lt;strong&gt;recursively composed succinct non-interactive arguments of knowledge (SNARKs).&lt;/strong&gt;" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_1080b51711d77ade623930973e12a221.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_1080b51711d77ade623930973e12a221.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://eprint.iacr.org/2020/352.pdf" rel="noopener noreferrer"&gt;https://eprint.iacr.org/2020/352.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Coda IS Mina Protocol
&lt;/h3&gt;

&lt;p&gt;Turns out that, that faintly reminiscent feeling that struck us as we were reviewing the construction of the Mina Protocol wasn't just a feeling. &lt;/p&gt;

&lt;p&gt;Public reporting from various 3rd-party sources reflect that, at some point during 2020, Coda decided to rebrand itself as the Mina Protocol. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_9bb8c08a5873c38ca3ab533df96c5553.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_9bb8c08a5873c38ca3ab533df96c5553.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://medium.com/minaprotocol/coda-protocol-relaunches-as-mina-the-worlds-lightest-blockchain-269636e4b044" rel="noopener noreferrer"&gt;https://medium.com/minaprotocol/coda-protocol-relaunches-as-mina-the-worlds-lightest-blockchain-269636e4b044&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sticking with that same press release (linked above), we can see that the Mina Protocol claims that, "Unlike first generation blockchains, such as Bitcoin or Ethereum, with heavy chains, Mina uses a chain that &lt;strong&gt;is, and always will be, 22 kb so participants can sync the entire chain in seconds.&lt;/strong&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Zero Knowledge Protocols
&lt;/h3&gt;

&lt;p&gt;In the example that we gave for Bitcoin above, we constructed something that's similar to a "zero knowledge protocol". &lt;/p&gt;

&lt;p&gt;In effect, by only mandating a signature that corresponds with a user's submitted public key (to spend a transaction), the blockchain is accepting the 'zero knowledge proof' that the holder of said public key &amp;amp; signature must also be in possession of the corresponding private key. &lt;/p&gt;

&lt;p&gt;This is because the 'proof' generated by the secp256k1 elliptic curve construction allow for the key holder to construct their own proof that, when solved, provides mathematical reassdurance that said proof could have only been proven (i.e., signature provided) by virtue of owning or having access to the corresponding private key (satisfying the imposed transaction conditions to spend whatever unspent transactions are in limbo at this stage of the transaction process). &lt;/p&gt;

&lt;h3&gt;
  
  
  Deconstructing zk-SNARKs
&lt;/h3&gt;

&lt;p&gt;zk-SNARKs stand for "Succinct Non-Interactive Argument of Argument" (in other words, a 'zero-knowledge proof'). &lt;/p&gt;

&lt;p&gt;However, rather than appealing to the inherent zero knowledge proof inherent in Bitcoin's construction, ZCash (the originators of this cryptographic scheme) decided to allow the sender of transactions to construct an entirely different (supposed more established) proof. &lt;/p&gt;

&lt;h3&gt;
  
  
  Digging into the Protocol's Technical Specifications
&lt;/h3&gt;

&lt;p&gt;The whitepaper on zk-SNARKs (&lt;a href="https://github.com/zcash/mpc/blob/master/whitepaper.pdf" rel="noopener noreferrer"&gt;published by the ZCash Foundation&lt;/a&gt;), provides us with the technical specifications necessary to discern what data, if any, must be kept on-hand to prove the proof was ever met itself, in the first place (otherwise the trustless construction of blockchain that's designed to prevent double-spending is undermined in this cryptographic scheme's assumptions. &lt;/p&gt;

&lt;h4&gt;
  
  
  Digging into the Mathematical Foundation of zk-SNARKs
&lt;/h4&gt;

&lt;p&gt;Per the whitepaper: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We always assume we are working with a field Fr for prime &lt;em&gt;r&lt;/em&gt; chosen according to a desired security parameter. We assume together that Fr we have generated groups G1, G2, Gt, all cyclic of order &lt;em&gt;r&lt;/em&gt;; which we write G1 and G2 in additive notation and Gt in multiplicative notation." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From the above, we can assume that the 'numbered' "G" instantiations are the different scalar multiplicative values for some public / private key that you're looking to kill me over (or with). &lt;/p&gt;

&lt;h3&gt;
  
  
  Proving the MPC Construction
&lt;/h3&gt;

&lt;p&gt;What makes zk-SNARKs unique as a zero-knowledge proof cryptographic scheme is that it instantiates a process know as 'MPC' (multi-party computation). &lt;/p&gt;

&lt;p&gt;Specifically, the whitepaper for zk-SNARKs states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The protocol is conducted by &lt;em&gt;n&lt;/em&gt; players, a coordinator, and a &lt;strong&gt;protocol verifier&lt;/strong&gt;." &lt;/p&gt;

&lt;p&gt;"In the implementation the role of the coordinator and protocol verifier can be played by the same server. We find it very useful to separate these roles, though, as the actions of the protocol verifier may be executed only after the protocol has terminated, if one wishes to reduce the time the players have to be engaged...." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most important part here: &lt;/p&gt;

&lt;p&gt;"...Any party wishing to &lt;strong&gt;check the validity of the transcript and generated parameters can do so solely with access to the protocol transcript.&lt;/strong&gt;" &lt;/p&gt;

&lt;p&gt;In total, the protocol consists of &lt;strong&gt;four total&lt;/strong&gt; 'round-robin' rounds. &lt;/p&gt;

&lt;p&gt;The rounds are delegated as follows: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Round One&lt;/strong&gt; = Commitments &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Round Two&lt;/strong&gt; = Revealing Commitments &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Round Three&lt;/strong&gt; = "After the random-powers subprotocol and the FFT, the MPC consists of a &lt;strong&gt;few invocations of the random-coefficient subprotocol.&lt;/strong&gt; These invocations add a total of two rounds to the MPC, as sometimes and random-coefficient subprotocol &lt;strong&gt;will need the output of a previous random-coefficient subprotocol as input&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Reconstructing the Zero Knowledge Proof
&lt;/h4&gt;

&lt;p&gt;It isn't enough to simply assert that the zero knowledge protocol has been iterated with a hash record acknowledging such. &lt;/p&gt;

&lt;p&gt;Coda, like any other blockchain, can only retain legitimacy of the derived results themselves are auditable (and ZCash is). &lt;/p&gt;

&lt;p&gt;Curiously, this auditability has been the &lt;strong&gt;primary contributor to ZCash's blockchain size&lt;/strong&gt; (see below): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_0656af258f077aeaad37a482f6525737.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_0656af258f077aeaad37a482f6525737.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://bitinfocharts.com/zcash/" rel="noopener noreferrer"&gt;https://bitinfocharts.com/zcash/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the chart above, we can see that ZCash, founded by Zooko (the creator of the zk-SNARKs concept) has a total blockchain size that well exceeds (22 kB). &lt;/p&gt;

&lt;p&gt;$ZEC is currently trading above $250 at the time of writing (and there's a Grayscale Investment Trust for it as well). &lt;/p&gt;

&lt;h4&gt;
  
  
  Transaction Sizes For ZCash
&lt;/h4&gt;

&lt;p&gt;Per ZCash's own website, we can see the average transaction sizes for both shielded and unshielded transactions: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_3eba6e84427fc1999123b5d77eea4d41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_3eba6e84427fc1999123b5d77eea4d41.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shielded Transactions&lt;/strong&gt; = 2000 bytes &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unshielded Transactions&lt;/strong&gt; = 500 bytes &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notably, &lt;strong&gt;shielded transactions&lt;/strong&gt; account for more data than &lt;strong&gt;unshielded ones&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Given this information, how is it that the "Mina Protocol" proposes that they'll be able to construct a blockchain that's exponentially smaller than that of ZCash's when $ZEC has an active implementation of the same zk-SNARKs construction that Mina proposes will shrink the size of its blockchain down to no more than 22kb (&lt;strong&gt;ever, at any given point in time&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;Going by ZCash's construction, that means that the maximum # of &lt;strong&gt;shielded&lt;/strong&gt; transactions that can ever be present on the Mina Protocol at any given point in time (before the data is irrevocably erased, one must assume), is &lt;strong&gt;11, tops&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Unfortunately for the crusaders of the Mina Protocol the plausibility of what they propose is out of the question (yet, ironically, creates several more questions about the integrity and competency of the 'Core' team behind Coda). &lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>zkproofs</category>
      <category>cryptography</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>Brief Dive into Ring Signatures</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Sun, 17 Oct 2021 14:45:26 +0000</pubDate>
      <link>https://forem.com/librehash/brief-dive-into-ring-signatures-15p</link>
      <guid>https://forem.com/librehash/brief-dive-into-ring-signatures-15p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Little write-up on Monero's "ring signature" construction; enjoy!&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below is a graphic showing what a "normal" transaction looks like (Bitcoin), for comparison: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bfuFOtC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bc2ebe802ece67db05cf80b98250c2df.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bfuFOtC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bc2ebe802ece67db05cf80b98250c2df.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see in the chart above, transactions can be finitely tied to addresses on blockchain (without a doubt). While it is true we may not always know the name of the identity behind a given address, there is zero doubt about where a given transaction came from. In fact, Bitcoin does just the opposite by enshrining quasi-permanent evidence on the blockchain akin to a living archive that one refer to as as proof that a certain address sent some form of payment on the blockchain. &lt;/p&gt;

&lt;p&gt;Specifically, when we mention proof - we're referring to the fact that virtually all transactions include a signature, which is cryptographically linked to the associated public key for the wallet address, removing virtually all doubt about the address of the sender. &lt;/p&gt;

&lt;p&gt;Below is a closer look at some of the granular information included within each transaction: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cn_Rd9TS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_db050790273b2cd1f3a9fbbe2422f12b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cn_Rd9TS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_db050790273b2cd1f3a9fbbe2422f12b.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How Ring Signatures Work
&lt;/h4&gt;

&lt;p&gt;Ring signatures are expressly different in that the sender of the transaction includes addresses of several other potential senders of the transaction. &lt;/p&gt;

&lt;p&gt;Out of all the addresses in a given ring signature construction, only &lt;strong&gt;one of them&lt;/strong&gt; is the actual sender of the transaction. Transaction amounts are also not included with transactions as a means of further removing information that observers could use to 'decode' the transaction and figure out the true sender. &lt;/p&gt;

&lt;p&gt;Despite there being several proposed candidates for the transaction (including the "real" one), only one signature is produced and verified by the blockchain as proof that the transaction is legitimate. This signature can be verified &amp;amp; validated as legitimate without knowing the identity of the "true" sender in the group. &lt;/p&gt;

&lt;p&gt;All of these characteristics are able to exist within this "ring signature" structure due to cryptographic principles premised on certain empirical mathematical proofs. For the sake of brevity, those cryptographic principles will not be elaborated upon in this write-up. &lt;/p&gt;

&lt;p&gt;Below is a visualized representation of a transaction constructedf rom a 'ring signature' setup: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ff8ZaNHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9a64c22530442e58f160bf21f230181c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ff8ZaNHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9a64c22530442e58f160bf21f230181c.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a mental snapshot of that photo above its going to be used in the next section where we uncover how 'MyMonero' rips this privacy model to shreds. &lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding How Decoys are Selected on Monero
&lt;/h3&gt;

&lt;p&gt;Few are familiar with how Monero works on a fundamental level (if you read the description), its clear in MyMonero's construction that there is zero privacy afforded to the end user. &lt;/p&gt;

&lt;p&gt;Reasons for this are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use of WebRTC&lt;/strong&gt;: This exposes the user's IP address to the server that they are connecting to. Also, this deviates from the JSON-RPC that is normally for RPC connections. Since there is one endpoint that is receiving the information, polling the blockchain and 'bookmarking' various points in the blockchain where transactions are stored, 'MyMonero' stands as one major central point of failure for anyone relying on their services. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deceptive Marketing Surrounding the Use of the View Key&lt;/strong&gt;: According to MyMonero's website, "only your view key" is shared with the server. Yet, in the very next sentence the service claims that they "keep no log". If that is the case, then there is no reason for any portion of any user's keys to be kept on the server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OpenAlias is Not Secure&lt;/strong&gt;: This goes down to the construction of OpenAlias itself as a protocol. While Monero claims that DNSSEC validation is provided for any and all URIs linked with OpenAlias, there is no documentation outlining exactly how this is done. Additionally, it is not clear in the codebase where (if anywhere) such validation takes place. That point aside, the DNS system was never designed to afford anonymity or privacy to those that use it (hence why 'TLS', 'dnscrypt', 'VPNs' etc., are so popular today). Thus, by taking a private protocol like Monero and tying one's address with a finite entity, the opsec risk incurred is enormous (potentially eroding privacy flat out for all users of the protocol). &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  False Claims Made on the Site
&lt;/h3&gt;

&lt;p&gt;On the site, there is a brief paragraph at the bottom of the page that makes the following claim: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Your app data is saved locally under strong encryption and only your "view key" is shared with the server. We keep no logs. You can also connect to your own server under Preferences." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, this statement is wholly inconsistent with one made at the top of the webpage where it states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"There's no Monero blockchain node to run. The MyMonero server does the heavy lifting for free. Forget spending days syncing the blockchain from your phone while waiting in line to pay for coffee. Get your entire transfer history instantly on any device with only your seed words."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Breaking Down Transaction Sending on the Monero Protocol
&lt;/h4&gt;

&lt;p&gt;The key to understanding the contradiction in the two quotes requires some understanding of how transactions are sent to users on the Monero protocol. &lt;/p&gt;

&lt;p&gt;When a user generates a Monero address they receive 5 different addresses in return: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fzk4uNIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_42ddbe5da71083dcb82b5f76bbf75777.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fzk4uNIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_42ddbe5da71083dcb82b5f76bbf75777.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The formatting of the webpage chomped up one of the inputs (use your imagination), but what a user will typically receive is their: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;private spend key &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;public spend key &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;private view key &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;public view key &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;concatenated Monero address &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Breaking Down the Spending Process
&lt;/h4&gt;

&lt;p&gt;Whenever someone wishes to send funds to another using Monero, they will send over their 96-byte Monero address. &lt;/p&gt;

&lt;p&gt;This address is a concatenation (combination) of both the public spend and view keys. &lt;/p&gt;

&lt;p&gt;The sender splits this 96-byte key into its two constituent parts, then derives a sub-address from the public spend key (first). This address is considered the stealth key. &lt;/p&gt;

&lt;p&gt;Once the stealth key has been created, a transaction is crafted by the sender that makes the payment to the stealth key, then that transaction is encrypted to the public spend key of the recipient. &lt;/p&gt;

&lt;p&gt;From that point, the recipient must scan each and every single transaction on the blockchain, attempting to decrypt each, until they find the correct one (i.ehttps://dev.to/librehash/rust-ephemeral-encrypted-containersfs-maybe-4jlk., the transaction that they are able to successfully decrypt). At that point the recipient can log the transaction in their wallet address as one that they've positively received (without finding this information, the payment is effectively "lost" [to everyone except the sender of the transaction]). &lt;/p&gt;

&lt;p&gt;This process requires the recipient to use their &lt;strong&gt;private view key&lt;/strong&gt;. Once the transaction has been retrieved, the recipient must use their &lt;strong&gt;private spend key&lt;/strong&gt; to actually spend it to someone else (spending the transaction requires the same process). &lt;/p&gt;

&lt;p&gt;Below is an illustration that captures this process succinctly: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6R-xBP_n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a8bd7b9290936c485607aebd09fe9ad0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6R-xBP_n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a8bd7b9290936c485607aebd09fe9ad0.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tying This into the Research Paper's Findings
&lt;/h3&gt;

&lt;p&gt;Let's go back to how someone sends a transaction on Monero. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First they receive the 96-byte address (or copy it from whatever website its hosted at). The address is the result of the concatenated public view &amp;amp; spend keys of the intended recipient. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once these two keys are extracted from the 96-byte address, a subkey is derived from the &lt;strong&gt;public view key&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTEh_10Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2fde1c1dc8cbc472bc1091a2cd93adda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTEh_10Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2fde1c1dc8cbc472bc1091a2cd93adda.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once that subkey is generated / derived from the public view key (using scalar multiplication ; leveraging commutative property), the subkey (public) is then encrypted to the recipient's &lt;strong&gt;public view key&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sender does not usually reveal &lt;em&gt;where&lt;/em&gt; they sent the transaction to. However, the sender does possess knowledge that will allow them to know when the transaction has been sent - the &lt;strong&gt;key image&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Image in Monero
&lt;/h3&gt;

&lt;p&gt;Every single transaction is accompanied with a 'key image' of some sort. That key image is &lt;strong&gt;necessary&lt;/strong&gt; for funds to be spent by the recipient of (whatever) transactions that they have received. &lt;/p&gt;

&lt;p&gt;The key image is unique for each and every single transaction on the blockchain. The key image is generated with each output, but the key image from that output is not seen in the actual chain until that output is spent (at some point). &lt;/p&gt;

&lt;p&gt;Thus, the sender is in a position where they're able to at least tell when/whether a recipient has spent the funds that they received by (a) retaining the derived public key that they generated &amp;amp; (b) also remembering the key image that was generated with the transaction itself (if given directly to the recipient, the 'key image' can be used as a means of bypassing the extensive process of scanning the entire blockchain &amp;amp; attempting to decrypt each output until one's key successfully does so). &lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplified in Documentation + Monero Construction
&lt;/h3&gt;

&lt;p&gt;By virtue of the cryptography that Monero uses, there exists a way for spenders to &lt;em&gt;prove&lt;/em&gt; that they spent funds from their wallet (w/o needing to enter the derived recipient address into the equation).&lt;/p&gt;

&lt;p&gt;Documentation (in laymen's terms), can be found here - &lt;a href="https://www.getmonero.org/resources/user-guides/prove-payment.html"&gt;https://www.getmonero.org/resources/user-guides/prove-payment.html&lt;/a&gt; (&lt;em&gt;not entirely sure about the veracity of this source, but from what I can see, it appears that the information on *this page&lt;/em&gt; was at least accurate; mentioning this because there are a substantial # of pages where the information was &lt;strong&gt;not accurate&lt;/strong&gt; for some reason). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Em_8FN0R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2d67588929a7e801009a177e91f95da4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Em_8FN0R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_2d67588929a7e801009a177e91f95da4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More information about 'proving' that one has made a payment can be found here as well - &lt;a href="https://www.monero.how/tutorial-how-to-prove-payment"&gt;https://www.monero.how/tutorial-how-to-prove-payment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Out of both links that were sent, however, this latest one provides the best 'proof' that a sender can tell when a transaction has been spent (by the recipient; assuming the sender kept all of the technical details of the send). &lt;/p&gt;

&lt;p&gt;Here is the link - &lt;a href="https://monerodocs.org/cryptography/asymmetric/key-image/"&gt;https://monerodocs.org/cryptography/asymmetric/key-image/&lt;/a&gt; (these are great docs)&lt;/p&gt;

&lt;p&gt;Specifically, this documentation notes that: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Key images prevent double spend attempts &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Funds are always spent to a one-time public key (derived from public spend key as sub-address / subkey) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each key image &lt;strong&gt;can only be spent once&lt;/strong&gt;, since it is related to the derived subaddress that was generated by the &lt;strong&gt;sender&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore if the sender sees that key image on the blockchain, then they can be assured that the transaction they sent is being spent at whatever block height where they've spotted the transaction. As an added bonus, once this deduction has been made, the observer (sender here), will also be able to rule out the subaddress they sent funds to if they see it in rings subsequent to identifying the spent generated key image. Thus, if and when they  do (if they're observing), they will retain the added benefit of striking off another mixin from the ring when they spot a re-use of the generated pubkey subaddress. &lt;/p&gt;

&lt;h3&gt;
  
  
  How Monero's Model Yields Way for Abuse
&lt;/h3&gt;

&lt;p&gt;If we go back to that pdf (have to upload it now since the Linode servers are suspended), we can see that the researchers publishing about the 'flood attack' came to what should be a fairly obvious consensus based on what we know - and that's that ring signatures on Monero can be decoded (to some extent) if someone is able to rule out some % of the mixins (accurately). &lt;/p&gt;

&lt;p&gt;Unfortunately for Monero users, validating / removing certain outputs via process of elimination is something that can be cross-referenced empirically (since this is all based on cryptography and mathematical proofs). &lt;/p&gt;

&lt;h3&gt;
  
  
  Undertanding the Mixin Process for Monero
&lt;/h3&gt;

&lt;p&gt;At the time of writing, Monero mandates 11 mixins per transaction (giving an observer a 1/12 chance in 'guessing' the true input). &lt;/p&gt;

&lt;p&gt;Below is an illustration that provides a bit more clarity on &lt;em&gt;how&lt;/em&gt; these mixins are slotted into future transactions. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tJWqVRkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_79c294b8c3d9db3c2549c002a4388fb3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tJWqVRkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_79c294b8c3d9db3c2549c002a4388fb3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The researchers that we're covering that published information about the transaction flooding deduced that if they could send enough transactions on Monero (in a short enough timeframe), then inevitably, some of the future blocks would contain public keys generated from them (via those sends), that they can later recognize &amp;amp; rule out. &lt;/p&gt;

&lt;p&gt;Since Monero has no provision that to combat this, this simple method of analysis is essentially 'checkmate' for the project until they change its construction entirely. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why This is Checkmate
&lt;/h3&gt;

&lt;p&gt;Some may be tempted to argue that Monero could simply add more 'mixins' to the equation to increase the difficulty of deciphering the "real" input. &lt;/p&gt;

&lt;p&gt;However, those individuals should keep in mind that additional mixins means additional selections must be made from the blockchain. Thus, if we're in a situation where there are 10 mixins (hypothetically) and the flood attacker is responsible for creating 5/10 of those mixins, it must be considered that tacking on an additional mixin (as a requirement), could result in another &lt;em&gt;attacker mixin&lt;/em&gt; being added (resulting in 6/11 vs. 5/10). &lt;/p&gt;

&lt;p&gt;Assuming there is an attacker using this technique (which evidence that we'll review later suggests there is), then the benefit of mandating any additional mixins could be negligible at best. In a worst case scenario where the attacker is able to maintain a TX flooding output that makes them responsible for 60%+ or more of transactions outputs, its quite possible that adding more mixins as a requirement could deteriorate the protections provided by the ring signature even further. &lt;/p&gt;

</description>
      <category>monero</category>
      <category>blockchain</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>Rust Ephemeral Encrypted Containers/FS (maybe) </title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Sun, 17 Oct 2021 14:41:09 +0000</pubDate>
      <link>https://forem.com/librehash/rust-ephemeral-encrypted-containersfs-maybe-4jlk</link>
      <guid>https://forem.com/librehash/rust-ephemeral-encrypted-containersfs-maybe-4jlk</guid>
      <description>&lt;h1&gt;
  
  
  Rust Ephemeral Encrypted Containers/FS (maybe)
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Running through the 'zboxfs' code and these are some notes. Should be able to spin it up &amp;amp; get the general gist from what's written here, enjoy!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Up With 'ZBoxFS'?
&lt;/h3&gt;

&lt;p&gt;ZBoxFS is a random project that I had came across a few times prior and logged in my notes somewhere. However, very recently when researching a few solutions for a blockchain-based wallet (agnostic) that I was devising for Librehash members, I stumbled back onto their main repo once again. &lt;/p&gt;

&lt;p&gt;You can all find that URL here - &lt;a href="https://github.com/zboxfs/zbox" rel="noopener noreferrer"&gt;https://github.com/zboxfs/zbox&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Breaking Down te ZboxFS Project
&lt;/h3&gt;

&lt;p&gt;The project caught my eye for a few reasons: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart Design&lt;/strong&gt; - The way its constructed actually makes sense &amp;amp; it appears to fit into a niche use case / purpose that no other app has fulfilled as of yet. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strong Cryptographic Algorithms&lt;/strong&gt; - We'll get to this part soon, but the cryptographic algorithms this project uses are 'strong', for lack of a better term. Truly that better term would be that the algorithms it employs in its orchestration are &lt;strong&gt;secure&lt;/strong&gt; (there are strong cryptographic algorithms / functions that can be vastly insecure when applied incorrectly or used in inappropriate situations). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuously Maintained&lt;/strong&gt; - The development is up to date on this project; as a rule of thumb, I generally don't touch 'dead projects' unless I have some sort of long-term plan to revive them in the future at some point (to be rebranded under Librehash when I can be sure that we have the resources to effecticely maintain the project w/o abandoning it ourselves). &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Describing the ZBoxFS Project
&lt;/h3&gt;

&lt;p&gt;In their 'readme', they state, "ZBoxFS is a zero-details, privacy-focused in-app file system. Its goal is to help application[s] store files securely, privately and reliably. By encapsulating files and directories into an encrypted repository, it provides a virtual file system and exclusive access to authorized application." &lt;/p&gt;

&lt;p&gt;Curiously, it goes on to state, "&lt;em&gt;Unlike other system-level file systems, such as ext4, XFS and Btrfs, which provide shared access to multiple processes, ZboxFS is a file system that runs in the same memory space as the application. It provides access to&lt;/em&gt; &lt;strong&gt;only one process at a time&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;Finally, the authors state, "&lt;em&gt;By abstracting IO access, ZboxFS supports a variety of underlying storage layers, including memory, OS file system, RDBMS and key-value object store.&lt;/em&gt;" &lt;/p&gt;

&lt;p&gt;This unique property means that not only does this app encrypt on the fly, it also provides some level of isolation from the other processes / facets of the filesystem (on the OS its deployed on). &lt;/p&gt;

&lt;h4&gt;
  
  
  Listed Features
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Everything is encrypted 🔒, including metadata and directory structure, no knowledge can be leaked to underlying storage&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;State-of-the-art cryptography: AES-256-GCM (hardware), XChaCha20-Poly1305, Argon2 password hashing and etc., powered by libsodium.&lt;/em&gt;"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Support varieties of underlying storages, including memory, OS file system, RDBMS, Key-value object store and more&lt;/em&gt;"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Files and directories are packed into same-sized blocks to eliminate metadata leakage&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Content-based data chunk deduplcation and file-based deduplication.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Data compression using LZ4 in fast mode, optional.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Data integrity is guaranteed by authenticated encryption primitives&lt;/em&gt; (AEAD crypto)" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;File contents versioning.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Copy-on-write (COW 🐮) semantics&lt;/em&gt;"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;ACID transactional operations.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;em&gt;Built with Rust.&lt;/em&gt;" &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The very last listed feature is a &lt;strong&gt;huge one&lt;/strong&gt;. Rust is our favorite language (up there with Golang, Python &amp;amp; C++ / C), for its memory-safety features as well as its robust community &amp;amp; surprisingly well-designed apps (which really feel like a 'hook up' everytime you run into one of them; this tool being case-in-point). &lt;/p&gt;

&lt;p&gt;What's there not to love here? (we'll get into that soon, which will explain the rabbit hole that we went down just to get to this point). &lt;/p&gt;

&lt;h3&gt;
  
  
  ZboxFS Architecture
&lt;/h3&gt;

&lt;p&gt;Below is one of the diagrams Zbox provides on their GitHub to help readers visualize the difference between the way their software is instantiated versus other well known file systems and tools. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_2c4c5fd9a31c2e391b6adf013e45a366.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_2c4c5fd9a31c2e391b6adf013e45a366.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which was then followed by a feature matrix. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c8e403de32b72b3a47540a73b22a0873.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c8e403de32b72b3a47540a73b22a0873.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is a feature matrix that shows the different storage backend options that come with Zbox. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_bae5d5b55a15d785bdcc765db745a899.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_bae5d5b55a15d785bdcc765db745a899.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rust-specific documentation can be found here at this link - &lt;a href="https://docs.rs/zbox/0.9.2/zbox/" rel="noopener noreferrer"&gt;https://docs.rs/zbox/0.9.2/zbox/&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Running Through Some of the Mock Rust Code for ZboxFS
&lt;/h3&gt;

&lt;p&gt;Since there are some easy-to-run examples provided right on their Rust project page, we'll extract those (in code blocks), for those that may be interested in running this code on their own personal machines (as they read). &lt;/p&gt;

&lt;p&gt;The following code is said to be designed with the intent of showcasing how to 'create and open a repo using memory as underlying storage' (sort of like tmpfs / ramfs).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;zbox&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;init_env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RepoOpener&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// initialise zbox environment, called first&lt;/span&gt;
&lt;span class="nf"&gt;init_env&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// create and open a repository&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RepoOpener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mem://my_repo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"your password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;File content IO using Read and Write traits&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Seek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;zbox&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OpenOptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// create and open a file for writing&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;OpenOptions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/my_file.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// use std::io::Write trait to write data into it&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// finish writting to make a permanent content version&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// read file content using std::io::Read trait&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"*Discovery navigation can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 and

 ```PathBuf```

. The path separator should always be "/", even on Windows.*"



```Rust 

let path = Path::new("/foo/bar");
repo.create_dir_all(&amp;amp;path).unwrap();
assert!(repo.is_dir(path.parent().unwrap()).is_ok());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cryptographic Primitives
&lt;/h3&gt;

&lt;p&gt;of the most ‘relevant’ ones for our endeavors (hint: most of them are going to be related to the memory handling of the k&lt;br&gt;
This is one of the most important features of this app (since we don't have time to play Daniel Bernstein to someone else's project). Information about the cryptographic schemes baked into this project can be found here - &lt;a href="https://docs.rs/zbox/0.9.2/zbox/enum.Cipher.html" rel="noopener noreferrer"&gt;https://docs.rs/zbox/0.9.2/zbox/enum.Cipher.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Among ciphers (encryption), users have the option of either going with AES256-GCM (known to be vulnerable to side-channel cache timing attacks; not good) or XChaCha20-Poly1305, which is considered to be highly secure; specifically, it is resilienit to the same side channel cache timing attacks that AES256-GCM could fall prey to. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption Parameters&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Key Size&lt;/strong&gt; - 256 bits &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nonce Size&lt;/strong&gt; - 192 bits &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Block Size&lt;/strong&gt; - 512 bits &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MAC Size&lt;/strong&gt; - 128 bits &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Up to this point, this write-up has failed to mention that one of the libraries baked into this program is 'libsodium'. For those that don't know, 'libsodium' is one of the best open-source cryptographic libraries available to programmers (hence why you its in use so frequently). &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Official GitHub repo for this library can be found here&lt;/strong&gt; - &lt;a href="https://github.com/jedisct1/libsodium" rel="noopener noreferrer"&gt;https://github.com/jedisct1/libsodium&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;website&lt;/strong&gt; - &lt;a href="https://libsodium.org/" rel="noopener noreferrer"&gt;https://libsodium.org/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;libsodium documentation&lt;/strong&gt; - &lt;a href="https://doc.libsodium.org/" rel="noopener noreferrer"&gt;https://doc.libsodium.org/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;libsodium audit&lt;/strong&gt; (sponsored by PIA before they were bought by an independent company) - &lt;a href="https://www.privateinternetaccess.com/blog/libsodium-audit-results/" rel="noopener noreferrer"&gt;https://www.privateinternetaccess.com/blog/libsodium-audit-results/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Critical libsodium Feature: 'Secure Memory'
&lt;/h4&gt;

&lt;p&gt;There's one portion of the documentation that provides extensive information on the code / syscalls / declarations one would need to use in order to provision 'secure memory'. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zeroing Memory&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sodium_memzero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;pnt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;"&lt;em&gt;After use, sensitive data should be overwritten, but&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 *and hand-written code can be silently stripped out by an optimizing compiler or by the linker.*" 

"*The*

 ```sodium_memzero()```

 *function tries to effectively zero*

 ```len```

 *bytes starting at*

 ```pnt```

, *even if optimizations are being applied to the code*." 
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Locking Memory&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sodium_mlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;"&lt;em&gt;The&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 function locks at least*

 ```len```

 *bytes of memory starting at*

 ```addr```

. *This can help avoid swapping sensitive data to disk*." 
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some additional recommendations given: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Totally disable swap partitions on machines processing sensitive data." &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;or &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Use encrypted swap partitions" &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Disabling Core Dumps When Running Crypto Code&lt;/strong&gt; (in order to ensure that sensitive data cannot be leaked out during the process itself). "&lt;em&gt;This can be achieved using a shell built-in such as&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 *or programmatically using*

 ```setrlimit (RLIMIT_CORE, &amp;amp;(struct rlimit) {0,0})```

. 

Its also recommended for folks to disable kernel dump as well if they find themselves in a situation where they're disabling swap partitions. 

**More Restrictions to Secure Memory** 

Its worth noting that all of these restrictions are ones that can be exercised w/o libsodium since they effectively mirror already existing Linux syscalls. 

For those curious, here is a link to all existing Linux syscalls (per the 5.14 kernel release at the time of writing) - https://elixir.bootlin.com/linux/latest/source/include/linux/syscalls.h (ignore the underlying source code for the syscalls here). 

Below are a list of the most 'relevant' ones for our endeavors (hint: most of them are going to be related to the memory handling of the kernel itself anyway). 

If this were the direction that we were electing to go in, then we would need to find a way to bind that 'C' code to be used with Rust (since this is at the heart of the program). 

### One Major Issue With the ZboxFS Setup 

Just when you thought everything was perfect! There's a little problem we run into here with the instantiation of this tool (zbox). To understand this problem, one must visit their website (https://zbox.io). 

![](https://notes.librehash.org/uploads/upload_53425baf8ee235f68ed6f6d3f5dd0350.png)

As we can see in the photo above, the site pivots this tool toward a paid model / subscription-based service rather than maintaining its posture as an open source tool / app for us to use. 

This is likely the reason for the restricting coding dictating the available backends (should be configurable vs. finite options). 

![](https://notes.librehash.org/uploads/upload_038eb311e5e9ed3204a0927c400221d4.png)

Also, rather than positioning itself as a mountable, custom fs (file system ) created on the fly for the purposes of local on-the-fly encryption, the website conveys that this tool is purposed to facilitate cloud storage (i.e., encrypt the data on one's desktop / locally, then store said data remotely). 

If the app fails to provide us with flexibility in the backend tools that we can provision, then all of its advertised 'features' are a mirage. 

![](https://notes.librehash.org/uploads/upload_ee8d85dbfbb9dbeacfb8d9ad98272ee7.png)

Further evidence that this app was designed to pivot developers &amp;amp; users alike toward their custom, proprietary storage setup can be found in the example code snippets they give on their main site. 

Below are two samples of code they give for creating an instance of 'zbox' and attaching it to a storage (cloud) backend via API (which of course has their site plugged in out-of-the-box, with no documentation on how one would effectively swap out their provided IPs for anther [custom one] provided on the backend). 

The first code sample is Javascript, second = Rust.



```javascript 
// create a Zbox instance
const zbox = new Zbox();

// initialise Zbox environment and turn on debug logs
await zbox.initEnv({ logLevel: 'debug' });

// open the repo
var repo = await zbox.openRepo({
  uri: 'zbox://yb2CCTcmEuxenZVuZhVKMCJD@AWCpPaNkvG6vVW',
  pwd: 'secret password',
  opts: { create: true }
});

// create a file and write content to it
var file = await repo.createFile('/hello_world.txt');
await file.writeOnce('Hello, World!');

// seek to the beginning of file and read all content
await file.seek({ from: Zbox.SeekFrom.Start, offset: 0 });
const str = await file.readAllString();

// close file, repo and exit Zbox
await file.close();
await repo.close();
await zbox.exit();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// initialise Zbox environment&lt;/span&gt;
&lt;span class="nf"&gt;init_env&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// create and open a repository&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RepoOpener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"zbox://yb2CCTcmEuxenZVuZhVKMCJD@AWCpPaNkvG6vVW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;"secret password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// create a file and write content to it&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;OpenOptions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/hello_world.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.write_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// seek to the beginning of file&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// read all content&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_80868749ad79573d8ff8f8e0d20f563b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_80868749ad79573d8ff8f8e0d20f563b.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, the kicker here is when they provide a preview of &lt;strong&gt;their architecture&lt;/strong&gt; (geo-distributed cloud storage); enticing users to create an account / node / storage pool that they host &amp;amp; maintain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_f584cd4c99d71b26104c1d632d1945aa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_f584cd4c99d71b26104c1d632d1945aa.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  App is Still Usable
&lt;/h3&gt;

&lt;p&gt;Fortunately for us, we can still definitely use the app spec as it is currently (but we're going to need to work at it a bit though first). &lt;/p&gt;

&lt;p&gt;Additionally, we can provision this app in a way where we can be sure that the remote server we authenticate with (i.e., not 'zbox.io', but something provisioned by Librehash), will be 100% ignorant of the content being stored on the server (hopefully to the extent of not revealing any metadata about what's being encrypted remotely). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ultimate Goal&lt;/strong&gt; - &lt;em&gt;Use this as an application backend for wallet apps &amp;amp; other similar tools where sensitive cryptographic operations are being performed&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Good News - API is Swappable
&lt;/h3&gt;

&lt;p&gt;The references to the remote server provided by Zbox in their code can be edited (with trivial ease) to be replaced with our custom backend (alongside some authentication mechanisms to provide significantly enhanced security assurances against a potential MITM attack [in case there were a malicious entity attempting to phish / impersonate our desired target remote server storage]). &lt;/p&gt;

&lt;p&gt;API reference can be found here - &lt;a href="https://docs.zbox.io/api/" rel="noopener noreferrer"&gt;https://docs.zbox.io/api/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Specifically, there is reference code for Javascript, Rust, and Android (Java). We're going to focus on the Javascript for the time being (despite the fact the app is written in Rust); there's a reason why we're doing this [that will be explained at a latter point]. &lt;/p&gt;

&lt;h4&gt;
  
  
  Diving into the API Reference
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c0ece4a1c8e2e4d036c7d5c811057fdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnotes.librehash.org%2Fuploads%2Fupload_c0ece4a1c8e2e4d036c7d5c811057fdc.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the picture above, we can deduce that the only palpable change that needs to be made here is in the URL where the data will be stored (we'll get to explaining exactly what the replacement backend storage will be shortly). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 'Calling' Style&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;As we can see below, the 'calling' style for this app (API; javascript), is very similar to what we've seen elsewhere (if you're someone that deals with API frequently). &lt;/p&gt;

&lt;p&gt;Below is some boilerplate code that was prepared to demonstrate the iterated call style for this app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Promise chaining&lt;/span&gt;
&lt;span class="nx"&gt;zbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openRepo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zbox://access_key@repo_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/foo/bar.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAll&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Async/await&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;asyncFunc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;zbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openRepo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zbox://access_key@repo_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/foo/bar.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, the app comes with 'error handling' as well (nothing that we're going to spend too much time focusing on anyway). &lt;/p&gt;

&lt;p&gt;The following configurations are relevantly important (this provisions the local / client-side encryption &amp;amp; derivation schemes via the provided KDF).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  opsLimit?: OpsLimit,    // default: OpsLimit.Interactive
  memLimit?: MemLimit,    // default: MemLimit.Interactive
  cipher?: Cipher,        // default: &lt;span class="o"&gt;(&lt;/span&gt;see below&lt;span class="o"&gt;)&lt;/span&gt;
  create?: boolean,       // default: &lt;span class="nb"&gt;false
  &lt;/span&gt;createNew?: boolean,    // default: &lt;span class="nb"&gt;false
  &lt;/span&gt;compress?: boolean,     // default: &lt;span class="nb"&gt;false
  &lt;/span&gt;versionLimit?: number,  // default: 1
  dedupChunk?: boolean,   // default: &lt;span class="nb"&gt;false
  &lt;/span&gt;readOnly?: boolean,     // default: &lt;span class="nb"&gt;false
  &lt;/span&gt;force?: boolean         // default: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>programming</category>
      <category>sandbox</category>
      <category>container</category>
      <category>rust</category>
    </item>
    <item>
      <title>Explaining the Difference Between Bitcoin and Ethereum Transcations (UTXO vs. Account-Based Transactions)</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Thu, 01 Apr 2021 07:29:26 +0000</pubDate>
      <link>https://forem.com/librehash/explaining-the-difference-between-bitcoin-and-ethereum-transcations-utxo-vs-account-based-transactions-2nkn</link>
      <guid>https://forem.com/librehash/explaining-the-difference-between-bitcoin-and-ethereum-transcations-utxo-vs-account-based-transactions-2nkn</guid>
      <description>&lt;p&gt;This breaks down the difference between account-based transactions (which Ethereum uses) and the UTXO-based transactions that Bitcoin, Litecoin, Bitcoin Cash and many others use.&lt;/p&gt;

&lt;p&gt;While both protocols are Proof of Work (at the time of writing), this difference in assessing / accounting for transactions dramatically alters the way that transactions are confirmed on each distinct protocol type. &lt;/p&gt;

&lt;h2&gt;
  
  
  First Step: Confirming the Exact Cryptographic Operations
&lt;/h2&gt;

&lt;p&gt;We need either documentation or an extensive resource - this is not information we want to extract from a run-of-the-mill crypto site that you find on Google. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Found a Reliable Source&lt;/strong&gt;: &lt;a href="https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html"&gt;https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html&lt;/a&gt; [Mastering Ethereum]&lt;/p&gt;

&lt;p&gt;This resource is verbose because it goes through the additional trouble of breaking down cryptography (waste of time at this point - if you're new to these concepts, then you won't be able to grasp the importance of the actual cryptographic primitives that are used to generate an Ethereum address - at least not at this point). &lt;/p&gt;

&lt;p&gt;&lt;em&gt;But We Found Out&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A) Ethereum uses the same elliptic curve that Bitcoin uses (secp256k1 ; Koblitz Curve on a 256-bit prime)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxpWTyL5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_e05942c1e92e2cacffa3afed63b6fc09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxpWTyL5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_e05942c1e92e2cacffa3afed63b6fc09.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(this needs to be cross-referenced with specific parameters for the generation of an Ethereum wallet, as provided by Ethereum developers because their implementation of the Keccak algorithm is different than what modern cryptographic libraries [i.e., OpenSSL or any other library that would be used to create such a wallet address would use]). &lt;/p&gt;

&lt;p&gt;Their implementation of the Koblitz curve, however is standardized - so that's not an issue. &lt;/p&gt;

&lt;p&gt;The 'Mastering Ethereum' book simply reiterates what we already know from the parameter standards published by SECG (&lt;a href="https://www.secg.org/sec2-v2.pdf"&gt;https://www.secg.org/sec2-v2.pdf&lt;/a&gt;), but below is a picture from the M.E. (Mastering Ethereum abbreviated - we'll use that from here out): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cGjCzz__--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_40cf5987e3f847ae18a6ef52b20b9e74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cGjCzz__--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_40cf5987e3f847ae18a6ef52b20b9e74.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the book acknowledges, modern cryptographic libraries (just about any on planet earth) possess this algoritihm: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--furW6Jxg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9567a37077092019e021ce10a478128e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--furW6Jxg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9567a37077092019e021ce10a478128e.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be clear, however, the library in question for this specific use case (client-side, in-browser cryptographic operations) - would be the 'WebCrypto API' (based on Mozilla's crypto library [NSS] or the crypto modules that Chrome uses). &lt;/p&gt;

&lt;p&gt;Both have possessed the capability to perform this type of operation within the browser for quite some time - we're not worried about this at all (our website certificate uses elliptic curve cryptography &amp;amp; was generated manually with a higher bit strength than secp256k1 ; our SCT pinning will soon be of a higher bit-size too [although we'd prefer ed25519 / ed448 key generation in place of these NIST-curves ; but that's another story for another day]). &lt;/p&gt;

&lt;h2&gt;
  
  
  Ethereum's Hashing Algorithm Choice
&lt;/h2&gt;

&lt;p&gt;The fact that Ethereum opted or Keccak-256 (SHA3) vs. SHA256 (which Bitcoin uses) is already widely known information and there is no problem with this choice. &lt;/p&gt;

&lt;p&gt;In fact, its probably a superior option - and not for the idea of an inherent security boost (although that's always a plus ; SHA256 is considered sufficiently secure though) or to mitigate malleability (although this was still an issue that needed to be separately addressed at a later point) ; its primary benefit is increased efficiency for x64 architecture (which virtually everything, even ARM devices, use these days). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mG17OE9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_292a82f70f24cd08da5d59150aa357f1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mG17OE9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_292a82f70f24cd08da5d59150aa357f1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More to the point though, this excerpt below is the most 'concerning' point here: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y4t59JZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_840469086bd458c860f9e6d16310b1b2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y4t59JZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_840469086bd458c860f9e6d16310b1b2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding in the tidbit about Edward Snowden is entirely irrelevant and there is nothing noble about Ethereum's refusal to swap out Keccak for the updated parameters provided by the NIST. &lt;/p&gt;

&lt;p&gt;The NSA, which works closely in concert with the NIST, has used the NIST as an instrument to include backdoors in published cryprographic algorithms before. This was not revealed by Snowden but rather cryptanalysis by external, independent cryptographers (&lt;a href="https://www.schneier.com/essays/archives/2007/11/did_nsa_put_a_secret.html"&gt;https://www.schneier.com/essays/archives/2007/11/did_nsa_put_a_secret.html&lt;/a&gt; ; long before news of the NSA Program, 'Bullrun' was leaked out - essentially confirming what cryptographers knew to be the truth years prior). &lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Hash Function is Important
&lt;/h3&gt;

&lt;p&gt;One notable feature of blockchain is that the resulting public keys (addresses ; public-facing alphanumeric identifiers used to mark recipients), is that they require a hash function during the &lt;strong&gt;creation&lt;/strong&gt; phase. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difference From PGP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most similar cryptographic system around that mirrors Bitcoin is PGP (GPG; whatever). &lt;/p&gt;

&lt;p&gt;The way PGP works is widely known &amp;amp; should be familiar to those that at least understand Bitcoin but aren't familiar with PGP.&lt;/p&gt;

&lt;p&gt;For that reason, we won't waste time climbing into that rabbit hole - but one thing must be brought up (to understand how all of this ties together). &lt;/p&gt;

&lt;p&gt;PGP restricts hashing to the signing / authenticating of messages in their cryptographic system (see below): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IW1PKVgp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_fb27181d2658d5e5026249fff3d3cfc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IW1PKVgp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_fb27181d2658d5e5026249fff3d3cfc8.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://users.ece.cmu.edu/%7Eadrian/630-f04/PGP-intro.html#p9"&gt;https://users.ece.cmu.edu/~adrian/630-f04/PGP-intro.html#p9&lt;/a&gt;&lt;/em&gt; ; site will give you an SSL warning in your browser - its just old, nothing can happen to you because you're just reading html / plain-text [&lt;strong&gt;pro-tip&lt;/strong&gt;: *no site that you visit on the 'darkweb' via Tor Browser has an authenticated certificate, barring some rare exceptions']]. &lt;/p&gt;

&lt;h2&gt;
  
  
  Specification for Bitcoin Wallet Generation
&lt;/h2&gt;

&lt;p&gt;This is technical, but put in simple enough terms to be understood if you sit down and read it (versus skimming it like a social media status): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BW4XSKd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_482ea161bd543be6e4220a9986ddbd21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BW4XSKd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_482ea161bd543be6e4220a9986ddbd21.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses"&gt;https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses&lt;/a&gt;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Notice that there is a hash operation that is performed immediately after the ECDSA operation (secp256k1; derived from the random seed phrase). &lt;/p&gt;

&lt;p&gt;You can ignore the RipeMD-160 as that was used primarily to shorten the output (length) of SHA256's hash function in order to make Bitcoin compatible with x32 architectures (which was a smart, reasonable decision back in 2007/2008 when Bitcoin as being designed &amp;amp; developed by Satoshi Nakamoto). &lt;/p&gt;

&lt;h2&gt;
  
  
  Specification for Ethereum Wallet Generation
&lt;/h2&gt;

&lt;p&gt;There are some major differences in this process for Ethereum vs. Bitcoin. &lt;/p&gt;

&lt;p&gt;Most of these differences derive from the fact that Ethereum's blockchain relies on 'account-based' balance verification vs. Bitcoin's 'UTXO-based' method. &lt;/p&gt;

&lt;p&gt;The main difference here is that the &lt;strong&gt;user&lt;/strong&gt;  is accounted or in Ethereum, whereas in Bitcoin, there is no concept of a "user" ; rather, Bitcoin is simply interested in ensuring compliance with protocol rules - namely the biggest one, which is avoidance of double spending (not counterfeiting ; that's already addressed off-chain, offline through the 'SCRIPT' language &amp;amp; C++ programming-like op-code functions used to evaluate whether the necessary conditions for spending unspent funds been fulfilled). &lt;/p&gt;

&lt;p&gt;Unfortunately, the best source of information on this process is the Ethereum Yellow Paper. &lt;/p&gt;

&lt;p&gt;The reason why the word 'unfortunately' is used is because it is &lt;strong&gt;extremely dense&lt;/strong&gt; in the language that's used. We don't think that it needs to be dense as it is (this is not to 'dumb it down', but simply to make the writing more fluid &amp;amp; intelligible ; but we'll dig into prose conversations later). &lt;/p&gt;

&lt;p&gt;See the first relevant excerpt below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_dGpu5-9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/%40attachment/Clipboard_2020-05-26-13-21-52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_dGpu5-9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/%40attachment/Clipboard_2020-05-26-13-21-52.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;Ethereum Yellow Paper&lt;/em&gt; ; its located all over the place, so access it from someone / somewhere you trust) &lt;/p&gt;

&lt;h2&gt;
  
  
  Attempting to Crawl Through the 'Thick' of the Ethereum Yellow Paper
&lt;/h2&gt;

&lt;p&gt;The excerpt above outlines an important reality of Ethereum. &lt;/p&gt;

&lt;p&gt;Since they use an &lt;strong&gt;account-based&lt;/strong&gt; means of accounting for spent vs. unspent currency, they must rely on a different means of &lt;strong&gt;authentication&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To be clear, this is &lt;strong&gt;different than validation&lt;/strong&gt; (the Proof of Work mining process). That is the method used to ensure that nobody cheated the process. &lt;/p&gt;

&lt;p&gt;What we're referring to is the process those miners are validating in the first process (hence the term, 'authentication').&lt;/p&gt;

&lt;h3&gt;
  
  
  State 'Nonce' Value
&lt;/h3&gt;

&lt;p&gt;Bitcoin 'stamps' transactions via block generation in a way that allows users on the network to quickly access the validity of spend attempts by simply polling which blockchain possesses the greatest Proof of Work. &lt;/p&gt;

&lt;p&gt;The limit here, however, is that the most up-to-date view of the blockchain is restricted to whichever chain has the greatest Proof of Work. And that Proof of Work total is only updated every 10 minutes (or so). Thus, anything that happens between updates (i.e., new blocks being published) is in limbo. &lt;/p&gt;

&lt;p&gt;There's no telling when a block will be created. &lt;/p&gt;

&lt;p&gt;For Ethereum, the 'limbo' is mitigated significantly (but the throughput is still limited ; that's a different conversation). &lt;/p&gt;

&lt;p&gt;In order to 'update' the blockchain, the blockchain maintains the 'state' value of each "account" by mandating an eternally increasing 'nonce' to delineate the blockchain's state at any given time. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the 'Nonce' Works&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Each time that an Ethereum account sends a transaction or performs an operation, the 'nonce' value increases (by just one integer). &lt;/p&gt;

&lt;p&gt;See below for a super simplified, super quick breakdown of how that works: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Account A sends 1st Transaction&lt;/em&gt;: Nonce state = 1 &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Account A sends 2nd Transaction&lt;/em&gt;: Nonce state = 2 &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Account A makes a call on some random contract&lt;/em&gt;: Nonce state = 3&lt;/p&gt;

&lt;p&gt;... (etc)&lt;/p&gt;

&lt;p&gt;As one can tell from what we showed above, the nonce state is an infinitely, ever-increasing value that is referenced in order to ensure that nodes on the chain are not accepting blockchain versions with competing 'versions' of how these nonce epochs played out. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The biggest benefit here is that this adds an additional layer of verification (on top of just using Proof of Work) and this is needed given the contract functionalities that are on Ethereum. &lt;/p&gt;

&lt;p&gt;(let's leave this here and move on with it). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check Out the Explainer Below From a Wonderful Medium Article That Digs Into Ethereum Blockchain Nonce Values&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C9wlxh56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_526773f762548b866521486b5bcef162.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C9wlxh56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_526773f762548b866521486b5bcef162.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;source&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://medium.com/swlh/ethereum-series-understanding-nonce-3858194b39bf"&gt;https://medium.com/swlh/ethereum-series-understanding-nonce-3858194b39bf&lt;/a&gt;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;This brings us all the way to the trouble with Ethereum wallet apps (and why you don't really see a ton of them in the same way that you do with Bitcoin). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Ethereum Wallet Apps are Almost Forced to be Insecure By Design&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This except below tells us all: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u4LMNu0D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_881c80d3eea5289787d936d55d7e36ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u4LMNu0D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_881c80d3eea5289787d936d55d7e36ca.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The example that was given above was merely a simplified way to explain this nonce concept. &lt;/p&gt;

&lt;p&gt;But in practice (for Ethereum) that increasing nonce value is determined, in part, by the state of the &lt;strong&gt;entire blockchain&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  MyEtherWallet Does Not Need to Account for 'Nonce' Total for Wallet Generation Though
&lt;/h2&gt;

&lt;p&gt;In specific, this increasing 'nonce' total is only relevant for &lt;strong&gt;trasactions&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conceptual Understanding of Wallets&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Even though we speak of wallets in terms of some concrete, tangible concept or item that can be manifested or created - the blockchain doesn't account for what addresses "exist" or not. &lt;/p&gt;

&lt;p&gt;In reality, the total number of addresses in existence is always equal to the total number of addresses that &lt;strong&gt;could be in existence&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The blockchain accounts for this ridiculously large sample space (impossible to create an array for) by &lt;em&gt;only tracking addresses that have been identified in a transaction on the blockchain&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What That Means&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;When you create a Bitcoin / Ethereum wallet address, the blockchain has no clue this happened. &lt;/p&gt;

&lt;p&gt;In fact, that address is as good as "invisible" / nothing until it is involved in a transaction - and at that point, its only significance derives from the fact that it will forever play a role in the accounting of legitimately spent / unspent funds going forward.&lt;/p&gt;

&lt;p&gt;This is also the reason for why the blockchain does not need to 'care' about what wallets exist and don't. &lt;/p&gt;

&lt;h2&gt;
  
  
  Digging Back into the Keccak Hash Function Used During Wallet Creation or Ethereum
&lt;/h2&gt;

&lt;p&gt;We don't need the Ethereum Yellow Paper for this one (fortunately). &lt;/p&gt;

&lt;p&gt;Let's take a look at how an Ethereum wallet address is created (per 'FreeCodeCamp' ; see below): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qg07MZ9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9088069d41124d79ff5af16871121fda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qg07MZ9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9088069d41124d79ff5af16871121fda.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;souce&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://www.freecodecamp.org/news/how-to-create-an-ethereum-wallet-address-from-a-private-key-ae72b0eee27b/"&gt;https://www.freecodecamp.org/news/how-to-create-an-ethereum-wallet-address-from-a-private-key-ae72b0eee27b/&lt;/a&gt;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Yes, its that simple. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Merged Mining With RSK: Deep Dive</title>
      <dc:creator>librehash</dc:creator>
      <pubDate>Thu, 01 Apr 2021 07:26:59 +0000</pubDate>
      <link>https://forem.com/librehash/merged-mining-with-rsk-deep-dive-3ejf</link>
      <guid>https://forem.com/librehash/merged-mining-with-rsk-deep-dive-3ejf</guid>
      <description>&lt;p&gt;Won't get into the technicalities of how merged mining works (just yet); just going to look at something that I found and we can go off there when I have the time one day. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yBIsEAaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b17410da32be3ca611213724fde48ddd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yBIsEAaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_b17410da32be3ca611213724fde48ddd.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a coinbase reward for this transaction here:  7a14dc3f8340c4d81cb29a5c1f49f56536a45030a5bfe659e4f27bce59a2e15e&lt;/p&gt;

&lt;p&gt;Using the 'EY Blockchain' tool, we can glean significantly more information about the transactions: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iansQ0v9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_74e53f2aea582a4f0fe8db6ba7063191.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iansQ0v9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_74e53f2aea582a4f0fe8db6ba7063191.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also have the benefit of seeing the details of each input in the transactions as well (shown below): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5bdYLQzb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a337f67715c5232ae59a94be37de39bb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5bdYLQzb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_a337f67715c5232ae59a94be37de39bb.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gCNTqjKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_90a8650f8c99334a71225e1d4a6ac984.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gCNTqjKi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_90a8650f8c99334a71225e1d4a6ac984.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AMXd8pAg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_293c468d33faa5f4ee25ac698691d715.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AMXd8pAg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_293c468d33faa5f4ee25ac698691d715.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above are all of the details of the op_return inputs that were fed into the transaction (remember this TX is a coinbase reward, so all inputs are generated "out of thin air"). &lt;/p&gt;

&lt;p&gt;The recipient address (1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY) had the following TX Script attached to it: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3wpr8gr0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9bc02a9a22e2ff340d39bb205e6809a1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3wpr8gr0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_9bc02a9a22e2ff340d39bb205e6809a1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Op_Return Flags Better
&lt;/h3&gt;

&lt;p&gt;I'm curious about the 'op_return' flags that were added to the transaction as well. &lt;/p&gt;

&lt;p&gt;See that below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QIo1g8T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_38f27a61262087a1899fc985bbe940b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QIo1g8T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_38f27a61262087a1899fc985bbe940b9.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Transaction ID (once again if not saved above) =  7a14dc3f8340c4d81cb29a5c1f49f56536a45030a5bfe659e4f27bce59a2e15e&lt;/p&gt;

&lt;p&gt;That means that the current documentation is (and has always been) wrong re: transactions on Bitcoin / Litecoin / other chains using op_return within a UTXO framework. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;question&lt;/strong&gt;: &lt;em&gt;is the documentation on op_return actually wrong or have I simply not read it closely enough to discern the difference?&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Some Links&lt;/strong&gt;: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Generalized Bitcointalk Link&lt;/em&gt;: &lt;a href="https://en.bitcoin.it/wiki/OP_RETURN"&gt;https://en.bitcoin.it/wiki/OP_RETURN&lt;/a&gt; (this provides a peripheral conversation re: merits of op_return) ; nothing in here explicitly suggests that op_return opcodes being added into the transaction somehow invalidate the entire transaction. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;General Documentation RE: 'op_return&lt;/em&gt;: Encompassed within the article, 'Script', published on the Bitcoin Wiki [&lt;a href="https://en.bitcoin.it/wiki/Script"&gt;https://en.bitcoin.it/wiki/Script&lt;/a&gt;]. Turns out that a TX that contains op_return in it, no longer burns data on the protocol??.. [could've sworn it was like this just a few weeks ago]. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Visiting the Bitcoin Core Reference Client Documentation&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;On the Bitcoin Core website there is a section dedicated to addressing some facet of 'op_return' (based on the 0.12 release, which featured more flexible options to be used in conjunction with op_return). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;source&lt;/strong&gt;: &lt;a href="https://bitcoin.org/en/release/v0.12.0#relay-any-sequence-of-pushdatas-in-opreturn-outputs-now-allowed"&gt;https://bitcoin.org/en/release/v0.12.0#relay-any-sequence-of-pushdatas-in-opreturn-outputs-now-allowed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Previously OP_RETURN outputs with a payload were only relayed and mined if they had a single pushdata. This restriction has been lifted to allow &lt;strong&gt;any combination&lt;/strong&gt; of data pushes and numeric constant opcodes (OP_1 to OP_16) after the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire serialized scriptPubKey, 83 bytes by default." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A2Lxburc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_677f8d5ab5a67299ab20a914b7cddb7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A2Lxburc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_677f8d5ab5a67299ab20a914b7cddb7a.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is even more interesting when considering the fact that there has been a wealth of information to suggest that this is simply not the case though...but okay. &lt;/p&gt;

&lt;p&gt;Hmm; in that case, this means that op_return only makes a specific transaction output unspendable (not the entire transaction, which is what we all had figured at one point in time... interesting; if there's anyone that's reading this that has anymore information on this, please reach out and provide some feedback on this). &lt;/p&gt;

&lt;h3&gt;
  
  
  RSK Merged Mining
&lt;/h3&gt;

&lt;p&gt;What makes 'bitaps' a great tool is the fact that it provides an ASCII translation of some of the information included within the transaction. &lt;/p&gt;

&lt;p&gt;See below if you're lost: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KE7Xq3d_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_1e412b18e7866a7ebffa97bc58c44c6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KE7Xq3d_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_1e412b18e7866a7ebffa97bc58c44c6f.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only intelligible portion of the blob circled in the picture above is 'RSKBLOCK'. &lt;/p&gt;

&lt;h3&gt;
  
  
  Clues to Discern the Meaning of This Block
&lt;/h3&gt;

&lt;p&gt;It appears that we don't need to look far since Sergio Damian Lerner and Jameson Lopp both provided their own dissection of the block (following a pretentious chastisement of the Federal Reserve for doing everything in their power to save the world from a financial apocalypse unlike any other): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/lopp/status/1259929075902222345?s=20"&gt;https://twitter.com/lopp/status/1259929075902222345?s=20&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That tweet bears no importance for us, but the following one by Sergio (longtime Bitcoin Core developer team member) does: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/SDLerner/status/1259954999305613315?s=20"&gt;https://twitter.com/SDLerner/status/1259954999305613315?s=20&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is RSK and How is Merged Mining Used With it?
&lt;/h3&gt;

&lt;p&gt;It seems prudent to start with their Twitter account (linked in Sergio's Twitter post), which can be found here: &lt;a href="https://twitter.com/RSKsmart"&gt;https://twitter.com/RSKsmart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In their bio, they claim to provide, "Smart contracts for ₿ [symbol for Bitcoin]"&lt;/p&gt;

&lt;p&gt;One tweet that really got our attention on their page was the following one: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/RSKsmart/status/1348721442339377156?s=20"&gt;https://twitter.com/RSKsmart/status/1348721442339377156?s=20&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;More than 50% of the Bitcoin hashing power has been leveraged for merged mining with RSK? That's a considerable amount, especially considering the fact that there are few (if any) individuals that mention RSK when talking about the features / benefits of Bitcoin&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What the Hell is "RSK" For Real?
&lt;/h3&gt;

&lt;p&gt;To learn more, we decided to visit the homepage of RSK to see what it is about this platform that's managed to garner &amp;gt;50% of the network's total hash rate. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---1EyAENl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_01d7a53ca1be2baa05c5f5bd4ec172ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---1EyAENl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_01d7a53ca1be2baa05c5f5bd4ec172ed.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This DeFi promise is obviously recent (more than likely added in response to the recent DeFi craze in the blockchain space). &lt;/p&gt;

&lt;p&gt;What we're looking for more information about can be found below: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yF3Fiv19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_7fdfdc799dfe3e3cd5d5525417ce1980.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yF3Fiv19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_7fdfdc799dfe3e3cd5d5525417ce1980.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For users that can't read the screenshot above (for whatever reason; contact the author if this is the case), it says: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"RSK is the most secure contract platform in the world. RSK's Contract goal is to add value and functionality to the bitcoin Contracts ecosystem by enabling smart contracts, near instant Contracts payments, and higher scalability."&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It then states (at the bottom, in bold): &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"RSK Blockchain is connected to Bitcoin through Merged Contractsr Mining and the two-way peg also known as the bridge&lt;/strong&gt;."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Interesting. &lt;/p&gt;

&lt;p&gt;Let's press that 'learn more' button to see get some details on how exactly this is supposed to work... &lt;/p&gt;

&lt;p&gt;Clicking said button takes us to this link here: &lt;a href="https://www.rsk.co/rsk-blockchain/"&gt;https://www.rsk.co/rsk-blockchain/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For All the Visual Learners Out There&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Before we even get into an explanation of how RSK Mining works (especially in lieu of its merged mining property), below is a GIF that effectively gives the general gist for how this merged mining works: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DMq78JMn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_fe1c5078d183cada594b3cced1d0f607.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DMq78JMn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://notes.librehash.org/uploads/upload_fe1c5078d183cada594b3cced1d0f607.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A  more verbose explanation of how it works: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tn-KGCwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bac61b31c9ed196eca01e914f0c1eb54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tn-KGCwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_bac61b31c9ed196eca01e914f0c1eb54.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still confused? Don't worry - so are we. So let's climb a bit deeper into this rabbit hole. &lt;/p&gt;

&lt;h3&gt;
  
  
  How the RSK Mining Two-Way Peg Works
&lt;/h3&gt;

&lt;p&gt;More information (documentation) on the ("POW"-peg as they term it), is located here: &lt;a href="https://developers.rsk.co/rsk/architecture/powpeg/"&gt;https://developers.rsk.co/rsk/architecture/powpeg/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;According to the documentation: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"RSK’s 2-way peg protocol, called “the **Powpeg&lt;/em&gt;&lt;em&gt;”, has  matured from its inception in 2018 as a federation to now include many  decentralized qualities. The new RSK Powpeg protects private keys stored in special purpose PowHSMs based on tamper-proof secure elements (SE).  Each PowHSM runs an RSK node in SPV mode, and so signatures can only be  commanded by chain cumulative proof of work. Security is established in  the Powpeg through the simplicity of a layered design we refer to as  defence-in-depth."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The explanation here is a bit convoluted, admittedly, and seems to be significantly inferior to a directly interopereable solution (such as what Librehash is attempting to do currently!). &lt;/p&gt;

&lt;h4&gt;
  
  
  General Gist of the 'Two-Way Peg' (as well as the overall protocol)
&lt;/h4&gt;

&lt;p&gt;Essentially, the documentation acknowledges a supposed shortcoming of the Bitcoin protocol by noting that it is Turing "incomplete" (although, this is also what allows Bitcoin transactions and addresses to be generated in a stateless manner; so this appears to be a fair tradeoff). &lt;/p&gt;

&lt;p&gt;RSK posits itself as an "extension" to the regular Bitcoin protocol. In order to utilize the supposed extended features that come with RSK, one must send their bitcoins to a "special address" (multi-signature as well) . &lt;/p&gt;

&lt;p&gt;This is because, RSK was designed to, "distribute trust among parties: multi-signatures."&lt;/p&gt;

&lt;p&gt;According to the documentation: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"With a multi-signature it is possible to give a group of notaries the task to protect locked bitcoins, tolerating a certain amount of malicious, hacked or unavailable parties."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;PoW-peg&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;According to the documentation, this was an evolution in the federated consensus standard that RSK was using previously. &lt;/p&gt;

&lt;p&gt;Per the documentation: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The Powpeg is a unique 2-way peg system that secures the locked bitcoins with the same Bitcoin hashrate that establishes consensus."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;[Merged mining, in essence]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The means by which this 'two-way peg' is created is a bit convoluted. &lt;/p&gt;

&lt;p&gt;Without wasting too much time, the specification for this facet of the protocol was grabbed from the documentation for time's sake (you can read this all directly if you really want to know more about the specifics of the specification): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4SQAVgHj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_acbbcdc20343c91cb5312e897ff64aa2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4SQAVgHj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.librehash.org/uploads/upload_acbbcdc20343c91cb5312e897ff64aa2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This setup honestly feels very convoluted, and what's still confusing here is that there does not seem to be &lt;strong&gt;any external / intrinsic reason why someone would want to help keep this network functioning&lt;/strong&gt; (specifically &amp;gt;50% of the hashrate on Bitcoin). &lt;/p&gt;

&lt;p&gt;The motivation that the documentation gives can be found here: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Since there is no collateral, the RSK Powpeg members are incentivized to participate by receiving a small portion of RSK transaction fees that  is automatically channeled to them. As seen in the Ethereum ecosystem,  transaction fees can eventually provide a sustained income for miners  and sometimes &lt;a href="https://coinmetrics.io/ethereums-defi-evolution-how-defi-is-fueling-ethereums-growth/"&gt;even higher&lt;/a&gt; than the blockchain subsidy."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Intermediate Conclusion
&lt;/h3&gt;

&lt;p&gt;People will probably hate me for this conclusion at some point in the future (assuming they ever read that far into this write-up ; if you did, good on you!), but this doesn't feel like something that's worth too much more of our time. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Merged mining is not a new concept (in fact, Satoshi Nakamoto devised the concept on the fly in responise to the proposal of Namecoin as a supplementary project designed to fulfill another duty of Bitcoin that the original protocol is not designed to do)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Considering the fact that the RSK protocol requires &lt;strong&gt;100 confirmations&lt;/strong&gt; for a "peg-in" transaction to be considered valid (3/4th of a day pretty much), it is unlikely that there will ever be an influx of users looking to submit bitcoins for a 'peg in' to the RSK network (the process feels a bit convoluted as well) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The additional requirement of a PowHSM ownership for interaction with the RSK protocol places a fairly substantive burden upon any prospective end users (and even calls into question who the target audience for this tool actually is)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
  </channel>
</rss>
