<?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>DEV Community: Lozi</title>
    <description>The latest articles on DEV Community by Lozi (@0xlozi).</description>
    <link>https://dev.to/0xlozi</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3968658%2Ffb8db326-4cec-4f7c-8d49-97e717f9936f.jpg</url>
      <title>DEV Community: Lozi</title>
      <link>https://dev.to/0xlozi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xlozi"/>
    <language>en</language>
    <item>
      <title>Bounce Buffer | Staging Buffer</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Tue, 01 Sep 2026 22:58:00 +0000</pubDate>
      <link>https://dev.to/0xlozi/bounce-buffer-staging-buffer-4ogd</link>
      <guid>https://dev.to/0xlozi/bounce-buffer-staging-buffer-4ogd</guid>
      <description>&lt;p&gt;While I was translating a decryption tool from C++ to Rust, I stumble across a really weird syntax that kept popping me up for hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;The function that I'm about to show you, it's purpose is to prepare the pointer for the decryption process using the KIRK encryption algorithm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;kirk1block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pbIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pbOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x1040&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;aligned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
    &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pbIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sceUtilsBufferCopyWithRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1040&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pbOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;Ok don't get scared, let's understand what exactly this function was made for. First of all let me introduce a really quick summary what exactly is "kirk".&lt;/p&gt;

&lt;h4&gt;
  
  
  What is KIRK?
&lt;/h4&gt;

&lt;p&gt;KIRK is a dedicated piece of hardware inside PSP that is respondible for permorfing cryptographic operations, such as encryption, decryption, and hashing.&lt;br&gt;
So instead of having the main CPU from the PSP to perform all of those operations itself, software can communicate with KIRK and ask it to perform a certain cryptographic operation. Then KIRK processes the data and returns a result.&lt;br&gt;
You can think of it as a specialize cryptographic processor rather than a general-purpose CPU.&lt;/p&gt;

&lt;p&gt;And this function was made in order to use THAT PSP'S KIRK cryptographic engine.&lt;/p&gt;

&lt;p&gt;Since KIRK was built for maximizing speed and not safety, it physically requires memory to be processed in a strict way: hypothetically 64 byte chunks (and also aligned to addresses ending in &lt;code&gt;0x00&lt;/code&gt;, &lt;code&gt;0x40&lt;/code&gt;, &lt;code&gt;0x80&lt;/code&gt;, and so on...). NOW you understand where this is going:&lt;/p&gt;

&lt;p&gt;So because KIRK is hardware rather than a simple software function, it contains certain requirements about how data must be presented to it. Therefore some KIRK operations expects their input and outbut buffers to be a 64 bytes aligned and proccessed in a specific block sizes (that's why I say hypothetically, since this is not a universal truth).&lt;/p&gt;

&lt;p&gt;This, in other words, means that a buffer might need to start at an address such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0x1000&lt;/code&gt; → aligned
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x1040&lt;/code&gt; → aligned
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x1080&lt;/code&gt; → aligned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because each of these addresses is a multiple of &lt;code&gt;0x40&lt;/code&gt; (64).&lt;/p&gt;

&lt;p&gt;KIRK has a strict memory alignment and block size requirements in order to perform certain operations. So by passing a buffer that doesn't satisfy those requirements can cause the operation to fail or produce incorrect behavior.&lt;/p&gt;
&lt;h3&gt;
  
  
  Now that we know why we need alignment, we can explain what is Bounce Buffer
&lt;/h3&gt;

&lt;p&gt;So if KIRK is that strict about memory, we could run into a massive problem when we look at our function arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;kirk1block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pbIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pbOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our encrypted data is being sent throuhg &lt;code&gt;const u8 *pbIn&lt;/code&gt;. Since data comes from any adress in the program, we don't have guarantee that &lt;code&gt;pbIn&lt;/code&gt; starts at an address that is multiple of &lt;code&gt;64&lt;/code&gt;. Therefore if it starts at &lt;code&gt;0x1013&lt;/code&gt; for example, and we feed it directly to &lt;strong&gt;KIRK&lt;/strong&gt;, the whole system &lt;strong&gt;could crash&lt;/strong&gt;.&lt;br&gt;
Because of that we can't trust the input address, so we have to create a safe &lt;strong&gt;middle-man&lt;/strong&gt;. In low-level programming, this is known as a &lt;strong&gt;Bounce Buffer&lt;/strong&gt; (or Staging Buffer).&lt;/p&gt;
&lt;h3&gt;
  
  
  Bounce Buffer | Staging Buffer
&lt;/h3&gt;

&lt;p&gt;In simple terms, a bounce buffer is exactly just like what it sounds like: A temporary but highly controlled workspace. So if you have data being stored in an unpredictable, bad or incompatible spot (like out &lt;code&gt;pbIn&lt;/code&gt; pointer), we don't use it directly. Instead we create a new buffer, then "bounce" our data into it, let the hardware do it's job safely and then bounce the clean results to their final destination.&lt;/p&gt;

&lt;p&gt;Since we are the ones creating this temporary buffer, we can dictate exactly where it lives inside memory. Therefore we can force it in order to follow KIRK's strict alignment rules!!!&lt;br&gt;
And that's exactly what that weird syntax I faced is doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x1040&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;aligned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;g_dataTmp[0x1040]&lt;/code&gt;: We are creating an array of bytes that's sightly larger than the &lt;code&gt;0x1000&lt;/code&gt; chunk of data that we desire to process (Soon I'll explain why "sightly larger", just follow me)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__atribute__ ((aligned(0x40)))&lt;/code&gt;: This is us telling to the C compiler a rule!!! We are explicitly telling this (or somewhat...): "I don't care where you put other variables, but this specific array MUST start at a memory address that is multiple of 64!!!".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;static&lt;/code&gt;: Well, If you know C you'll probably know this, but basically means that the buffer isn't destroyed when the function ends. Therefore it's only created once in permanent memory, meaning that we are not gonna waste CPU time clocks rebuilding that workspace every time we process a block of data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then once our aligned workplace is ready, the next step will be moving the data in and then move it to our desired destination once it finishes processing data KIRK.&lt;/p&gt;

&lt;h4&gt;
  
  
  But why &lt;code&gt;+0x40&lt;/code&gt;?
&lt;/h4&gt;

&lt;p&gt;Now that our workbench is built, let's look at the actual data movement. Here are the next lines of our function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pbIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sceUtilsBufferCopyWithRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1040&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g_dataTmp&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look closely at the first &lt;code&gt;memcpy&lt;/code&gt;. Since we aren't copying our encrypted data at the start of our buffer. We are copying it into &lt;code&gt;g_dataTmp + 0x40&lt;/code&gt; (&lt;strong&gt;In other words:&lt;/strong&gt; We are skipping the first 64 bytes!!).&lt;/p&gt;

&lt;p&gt;Remember when I told you our buffer was sightly larger (&lt;code&gt;0x1040&lt;/code&gt;) than the data we wanted to process (&lt;code&gt;0x1000&lt;/code&gt;)? This is the explanation about this manner if you are interested:&lt;/p&gt;

&lt;p&gt;The original &lt;strong&gt;PSP&lt;/strong&gt; only had &lt;strong&gt;32 MB OF RAM&lt;/strong&gt;!!!. And memory was extremely limited because of that. So instead of wasting space by creating a two separated aligned arrays (one por the input and one for the clean output), the programmer used an old-school trick which is called &lt;strong&gt;In-Place Decryption&lt;/strong&gt;. They used the same exact array for both!!!! (I have an article explaining this concept, you should watch it).&lt;br&gt;
But then why a 64-byte gap? Why not just start at 0?&lt;/p&gt;

&lt;p&gt;This is because of the &lt;strong&gt;Read&lt;/strong&gt; / &lt;strong&gt;Write&lt;/strong&gt; Race.&lt;br&gt;
If we started at the exact line, we would have a massive problem. Since te Write Head might step on the Read "Rail", therefore it can overwrite a byte of encrypted data just before the hardware had a chance to read it. So the data would corrupt itself!!!&lt;/p&gt;

&lt;p&gt;By putting the encrypted data 64 bytes ahead, we are giving the &lt;strong&gt;Read Head&lt;/strong&gt; a massive head start. Instead of hoping for the best and pray it doesn't overwrite encrypted data, we are securing it in a much better way. So that 64-byte empty buffer zone acts as a safety caution, making sure the Write Head always stays safely behind the Read Head while the hardware does its thing.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>rust</category>
    </item>
    <item>
      <title>Traits in Rust</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Sun, 02 Aug 2026 16:15:45 +0000</pubDate>
      <link>https://dev.to/0xlozi/traits-in-rust-3bgl</link>
      <guid>https://dev.to/0xlozi/traits-in-rust-3bgl</guid>
      <description>&lt;p&gt;In Rust, a trait is a way to define shared behavior. It acts as a "contact" or "label" that you can attach to different structs.&lt;/p&gt;

&lt;p&gt;Instead of caring about what struct is, a trait tells the &lt;strong&gt;Rust Compiler&lt;/strong&gt; what a struct can do. So if multiple, completely unrelated structs need to perform &lt;strong&gt;the same kind of action&lt;/strong&gt;, you can group them under a &lt;strong&gt;single trait.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's make an analogy about USB's into actual Rust code.&lt;br&gt;
A computer doesn't have a separate hole for &lt;code&gt;Mouse&lt;/code&gt;, &lt;code&gt;Keyboard&lt;/code&gt;, and &lt;code&gt;Webcam&lt;/code&gt;. It just has a USB port, right?. So in Rust, we represent these concepts by creating a &lt;code&gt;USBDevice&lt;/code&gt; trait.&lt;/p&gt;
&lt;h3&gt;
  
  
  Definition of Trait and Structs
&lt;/h3&gt;

&lt;p&gt;First, we have to define the trait (the label we've already talked about) and some structs that have nothing in common internally:&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="c1"&gt;// The trait (label)&lt;/span&gt;
&lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;UsbDevice&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;connect&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;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// First Struct&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Mouse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dpi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Second Struct&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Keyboard&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mechanical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&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;h3&gt;
  
  
  Implementing the Trait
&lt;/h3&gt;

&lt;p&gt;Then, we have to put our structs into the Trait. So we are proving to the compiler that both of these items can act as USB device:&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;impl&lt;/span&gt; &lt;span class="n"&gt;UsbDevice&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Mouse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;connect&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mouse Connecteeeeed! And ready to do some clicking"&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="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;UsbDevice&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Keyboard&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;connect&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Keyboard connected! And ready to do some typingggg"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the Trait inside a function (POLYMOPHISM)
&lt;/h3&gt;

&lt;p&gt;Here is where the "cool thing" happens. We write a function that represents the computer plugging &lt;strong&gt;something in&lt;/strong&gt;. So instead of writing &lt;code&gt;plug_in_mouse(device: Mouse)&lt;/code&gt; and &lt;code&gt;plug_in_keyboard(device: Keyboard)&lt;/code&gt;, we write only &lt;strong&gt;ONE&lt;/strong&gt; function that accepts &lt;strong&gt;ANYTHING&lt;/strong&gt; with the &lt;code&gt;UsbDevice&lt;/code&gt; label.&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="c1"&gt;// The "impl UsbDevice" syntax here means that it accepts ANY struct that has this trait!!!&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;plug_into_computer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&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;impl&lt;/span&gt; &lt;span class="n"&gt;UsbDevice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_mouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Mouse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;dpi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1600&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_keyboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Keyboard&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mechanical&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;plug_into_computer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;my_mouse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;plug_into_computer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;my_keyboard&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;h2&gt;
  
  
  But why are Traits so important?
&lt;/h2&gt;

&lt;p&gt;Here I'm gonna point out essential things that you have to consider in order to make yourself understand and start using &lt;strong&gt;Traits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; As shown in the &lt;strong&gt;USB example&lt;/strong&gt;, traits allows you to write more generic functions that can handle different types of data. So you build the function &lt;strong&gt;1 time&lt;/strong&gt;, and it automatically works for any struct that you create in the future &lt;strong&gt;AS LONG AS&lt;/strong&gt; it has the expected trait.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DRY (Don't repeat yourself):&lt;/strong&gt; Traits allows you to write "default methods". So if 200 different structs share the same logic for a certain function, you can write the function's code inside the trait once. And all of the 200 different structs will INHERIT IT, saving it from copying and pasting code everytime you need an implementation of that function that is the same from the rest of the 200 structs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extensibility:&lt;/strong&gt; You can also implement traits on structs &lt;strong&gt;that you didn't even write!!!&lt;/strong&gt;. Let's make an example: If you import a library that contains &lt;code&gt;VideoPlayer&lt;/code&gt; struct, you can write your own custom &lt;code&gt;Trait&lt;/code&gt; and attach it to their &lt;code&gt;VideoPlayer&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unlocking Built-in Rust Features:&lt;/strong&gt; This one is really important since sometimes you want to use a function inside a crate and sometimes the compiler tells you that &lt;code&gt;method_x&lt;/code&gt; is not implemented or some shit. Well... Rust uses standard traits behind for almost everyting!!!. If you wanna print a struct into the screen, you have to implement the &lt;code&gt;Display&lt;/code&gt; Trait. And if you wanna copy a &lt;code&gt;struct&lt;/code&gt;, you implement the &lt;code&gt;Clone&lt;/code&gt; trait. &lt;strong&gt;TRAITS&lt;/strong&gt; are how you "talk" to the rust compiler. &lt;strong&gt;Remember this since it's very important...&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Rust allows many readers but only One Writer</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Tue, 14 Jul 2026 16:53:23 +0000</pubDate>
      <link>https://dev.to/0xlozi/why-rust-allows-many-readers-but-only-one-writer-4b6p</link>
      <guid>https://dev.to/0xlozi/why-rust-allows-many-readers-but-only-one-writer-4b6p</guid>
      <description>&lt;p&gt;While programming in Rust, we stumble across many rules that, at first, are really unfamiliar to begin with.&lt;br&gt;
However, there's a certain rule that, while programming, I face the most: &lt;strong&gt;Multiple Mutable References&lt;/strong&gt;.&lt;br&gt;
It usually happens when you try to pass a variable into a function as a reader, and then pass that same variable as a writer. &lt;strong&gt;C&lt;/strong&gt; or &lt;strong&gt;C++&lt;/strong&gt; will happily compile and let you run the code, but &lt;strong&gt;Rust throws a massive red error in your face!!!.&lt;/strong&gt;&lt;br&gt;
In order to understand why this happens, we have to look at how C programmers dealt with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointers
&lt;/h3&gt;

&lt;p&gt;Back in the old days, programming in C was like having everything &lt;strong&gt;at your disposal&lt;/strong&gt;. A pointer was just an address in memory, nothing else. If you wanted to have ten different pointers all pointing at the same byte of &lt;strong&gt;RAM&lt;/strong&gt; (Aliasing) and you wanted three of them for example to simultaneously try to edit that &lt;strong&gt;byte&lt;/strong&gt; (Mutation), the C compiler would say, &lt;strong&gt;"Whatever you say, Boss".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But this absolute freedom of memory management created &lt;strong&gt;LOTS&lt;/strong&gt; of bugs that kept devs awake for days!!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imagine processing bank transactions: Two Threads (workers), Alice and Bob are running at the exact same time:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alice is reading your account balance in order to deposit $70&lt;/li&gt;
&lt;li&gt;Bob is reading your account balance because you just bought a $30 game&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because C places &lt;strong&gt;almost no restrictions on aliasing and mutation&lt;/strong&gt;, multiple parts of a program can read from and write to the same memory simultaneously. As a result, both workers read your balance and see &lt;strong&gt;$100&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alice says:&lt;/strong&gt; "Alright: $100 + $70 = $170". And then Alice prepares to write $170&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bob says:&lt;/strong&gt; "$100 - $30 = $70". And then Bob prepares to write $70&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They both put their new numbers into the database. So whichever one writes a millisecond slower &lt;strong&gt;OVERWRITES&lt;/strong&gt; the other. It can make your $70 profit vanish into the void (This is called &lt;strong&gt;Data Race&lt;/strong&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  The Single-Thread
&lt;/h3&gt;

&lt;p&gt;Even if you don't use multi threading. C would still shoot you at your own feet. Imagine like you are reading a list of names, right?. Then you have a pointer &lt;strong&gt;looking at the first name (Aliasing)&lt;/strong&gt;. But further down your code, you accidentally tell the program to &lt;strong&gt;add a hundred thousand new names to that list (Mutation).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The computer realizes the current memory array is &lt;strong&gt;too small&lt;/strong&gt; to hold a hundred thousand  new names, so what it does it silently pick up the entire list, moves it into a bigger space in &lt;strong&gt;RAM&lt;/strong&gt;, and &lt;strong&gt;DELETES&lt;/strong&gt; the old one. But your original reading pointer &lt;strong&gt;doesn't know that the program did that!!!!&lt;/strong&gt;. So then It tries to read the next name and reads literal &lt;strong&gt;deleted garbage&lt;/strong&gt;, causing the program to instantly crash. This behavior is called &lt;strong&gt;Iterator Invalidation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;For decades, language researchers studied these crashes and behaviors. And eventually they realized something profound:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aliasing by itself is literally &lt;strong&gt;harmless&lt;/strong&gt;: Like if you have a million threads reading a list simultaneously. If nobody changes throughout that time, then &lt;strong&gt;nothing breaks&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Mutation by itself is also &lt;strong&gt;harmless&lt;/strong&gt;: If only &lt;strong&gt;Bob&lt;/strong&gt; is allowed in the room to edit the bank account, then the math is always perfect.
The &lt;strong&gt;crashes&lt;/strong&gt; only happened when &lt;strong&gt;Aliasing&lt;/strong&gt; and &lt;strong&gt;Mutation&lt;/strong&gt; were combined.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The XOR Gate
&lt;/h3&gt;

&lt;p&gt;When Graydon Hoare started building Rust, one of his goals was to eliminate an entire class of memory safety bugs before a program could even run. Rust achieves this by enforcing a fundamental principle at compile time, commonly summarized as &lt;strong&gt;Aliasing XOR Mutation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Just like the XOR logic gate many of us encounter in our first digital logic course, a piece of data can have &lt;strong&gt;aliases&lt;/strong&gt; (multiple shared references) &lt;strong&gt;or&lt;/strong&gt; it can be &lt;strong&gt;mutated&lt;/strong&gt; (through one exclusive mutable reference), but never both at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you didn't get it at first, I'll give you an analogy from a professor that I had at university:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You can have your wife in the house, or your lover when she's not inside, but not at the same time or it'll be a disaster".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's essentially what Rust enforces. You can have many readers, or one writer—but never both at the same time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Option A (Aliasing):&lt;/strong&gt; You can have unlimited read-only references (&lt;code&gt;&amp;amp;name&lt;/code&gt;). But the moment you create one, the compiler locks the data and no one is allowed to mutate it until everyone is done READING.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Option B (Mutation):&lt;/strong&gt; You can have exactly one mutable reference (&lt;code&gt;&amp;amp;mut name&lt;/code&gt;). But in order to get it, you must be THE ONLY POINTER int he room!!.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Global Variables in Rust &amp; C/C++</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Sun, 12 Jul 2026 20:30:44 +0000</pubDate>
      <link>https://dev.to/0xlozi/global-variables-in-rust-cc-3h4p</link>
      <guid>https://dev.to/0xlozi/global-variables-in-rust-cc-3h4p</guid>
      <description>&lt;p&gt;&lt;strong&gt;What's a global variable?&lt;/strong&gt;&lt;br&gt;
A global variable is a variable with global scope, meaning that it visible throughout the program, unless it's shadowed. In compiled languages, global variables are generally static, which means their lifetime is &lt;strong&gt;the entire runtime of the program&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which one's programming languages are actually compiled?&lt;/strong&gt;&lt;br&gt;
Is a &lt;strong&gt;programming language&lt;/strong&gt; that is usually implemented with a compiler &lt;strong&gt;rather than an interpreter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why we use them?&lt;/strong&gt;&lt;br&gt;
Global variables are used to pass information between sections of code that do not share a relation like concurrent threads and signal handlers. Languages (Including C) defines implicitly a namespace for earch global variable inside a certain file so that eliminates most of the problems seen with languages with a global namespace, though problems may persist without their proper encapsulation. Without a proper locking (like mutex) code, using global variables will not be thread-safe except for read only values in protected memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interesting, so using global variables in parallel programs is not the best idea UNLESS we use a proper locking (which is mutex)...&lt;/strong&gt;&lt;br&gt;
Rust is known as a safe programming language, therefore MAYBE this can be the cause of why I can't declare a global variable that can be edited at runtime: BECAUSE IT'S RISKY.&lt;br&gt;
But my program isn't parallel, then why I can't do it then?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's investigate&lt;/strong&gt;&lt;br&gt;
I stumble upon a thread from stack overflow from a person who had somewhat the same problem that I'm facing currently, and the answer to that manner was to use the "unsafe" type in order to stop fighting with the compiler, but at a certain cost: "Unless your program wouldn't be in te future concurrent, then is perfectly fine to use the unsafe keyword".&lt;/p&gt;

&lt;p&gt;But I want in the future make this decryption tool concurrent, so then I can learn more about concurrency in Rust. Thus, I think I might make the global variable "Safe".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But how do we make it "Safe"?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Let's investigate:&lt;/strong&gt;&lt;br&gt;
I stumble upon a really GOOD diagram explaining what to use depending on what do you wanna do with your global variable in Rust. You can find the diagram here: &lt;a href="https://www.sitepoint.com/rust-global-variables/" rel="noopener noreferrer"&gt;https://www.sitepoint.com/rust-global-variables/&lt;/a&gt; At Overview section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frbk2hffo25davg6gj8yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frbk2hffo25davg6gj8yu.png" alt="Rust Concurrent Tree Decision Taking" width="799" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing that I need now is make my global variable "Safe", so then in the future I can use it without any problem.&lt;br&gt;
For single threading if I wanna store at runtime inside the const, I have to use Rc. But since I've told already that I want to make this in the future a concurrent program. Then I'll use Arc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Arc btw&lt;/strong&gt;&lt;br&gt;
I made a summary before about this Arc thing, so I might just copy and paste in case someone is interested:&lt;/p&gt;
&lt;h4&gt;
  
  
  Rc and Arc note:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://app.notion.com/p/Rc-T-and-Arc-T-39bfcd22531880c1a6c0fb1446359574?source=copy_link" rel="noopener noreferrer"&gt;https://app.notion.com/p/Rc-T-and-Arc-T-39bfcd22531880c1a6c0fb1446359574?source=copy_link&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Solution to my problem
&lt;/h4&gt;

&lt;p&gt;This was my code before the refactoring:&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="c1"&gt;// std::array&amp;lt;std::vector&amp;lt;char&amp;gt;, 13&amp;gt; g_tables;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;G_TABLES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;13&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="nn"&gt;Vec&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="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By combining Arc (Atomic Reference Counted) and Mutex (Mutual Exclusion), you create a single, shared source of truth that can be safely accessed and modified from anywhere in your program, even across multiple cores.&lt;/p&gt;

&lt;p&gt;In the Rust community, wrapping a type like this is so common it's often jokingly called "the Arc&amp;gt; sandwich."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&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;static&lt;/span&gt; &lt;span class="n"&gt;g_tables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&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="nn"&gt;Mutex&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="nn"&gt;Vec&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="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahhhh I'm so close but the Rust compiler is telling me something:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;= note: the `Copy` trait is required because this value will be copied for each element of the array
help: create an inline `const` block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I don't understand why in order to get the Copy trait I have to put the Vec::new() inside a const...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I found:&lt;/strong&gt;&lt;br&gt;
Copying vs. Re-running&lt;br&gt;
When I write [value; 13], Rust doesn't run the value code 13 times&lt;br&gt;
Instead, Rust does this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluates &lt;code&gt;Vec::new()&lt;/code&gt; exactly one&lt;/li&gt;
&lt;li&gt;Takes that single vector and tries to copy it 13 TIMES in order to fill the array&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So this si where the Copy trait comes in. Simple types like u8 or booleans Implement Copy because copying them is just duplicating bits in memory.&lt;br&gt;
But a Vec is: A dynamic data structure that points to a chunk of memory on the heap. So if Rust blindly copied the vector 13 times, you would end up with 13 vectors &lt;strong&gt;all pointing to the exact same memory location&lt;/strong&gt;. So when you tried to add data to one, it would corrupt the others. And when the program ends, Rust would try to clean up the same memory 13 TIMES, causing a massive crash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: const Block&lt;/strong&gt;&lt;br&gt;
When we add the const block like the compiler tells us to do: &lt;code&gt;[const { Vec::new() }; 13]&lt;/code&gt;, we are changing the rules of the array syntax itself!!!.&lt;br&gt;
I'm telling the compiler "Not evaluate this once, copy it instead, treat is as a constant expression, and run it 13 SEPARATE TIMES".&lt;/p&gt;

&lt;p&gt;Arc (Atomic Reference Counting) is used to share ownership of a variable when you don't know how long it needs to live. But a static variable lives forever, for the entire duration of the program, and is already globally accessible to every thread.&lt;/p&gt;

&lt;p&gt;If it's global, I only need the Mutex to safely mutate it!!!&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Result:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// std::array&amp;lt;std::vector&amp;lt;char&amp;gt;, 13&amp;gt; g_tables;&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;G_TABLES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Mutex&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="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;Vec&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="p"&gt;};&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Fat Pointers &amp; Smart Pointers in Rust</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Sat, 27 Jun 2026 14:55:38 +0000</pubDate>
      <link>https://dev.to/0xlozi/fat-pointers-smart-pointers-in-rust-45mb</link>
      <guid>https://dev.to/0xlozi/fat-pointers-smart-pointers-in-rust-45mb</guid>
      <description>&lt;p&gt;When transitioning from C or C++ to Rust, the hardest habit to break is how you think about memory. In C/C++, pointers are mostly just memory addresses. Rust adds ownership and richer pointer types to make memory access safe without sacrificing performance.&lt;br&gt;
In order to understand Rust, you have to know 2 key concepts: &lt;strong&gt;Smart Pointers&lt;/strong&gt; and &lt;strong&gt;Fat Pointers&lt;/strong&gt;. The entire decision of which to use depends on one rule: &lt;strong&gt;Ownership&lt;/strong&gt; and &lt;strong&gt;Borrowing&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smart Pointer: Definition
&lt;/h3&gt;

&lt;p&gt;A data structure that acts like a normal pointer, but it comes with a "Property Manager" (Ownership Manager), let me explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It owns some resource (commonly heap memory) and knows exactly &lt;strong&gt;when that resource is no longer needed.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;strong&gt;Rust&lt;/strong&gt;, common Smart Pointers have &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt;, or &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it useful?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The CPU Stack is really fast but tiny. So if you try to create a 3000000 byte array on the stack, your program will crash instantly raising a &lt;code&gt;Stack Overflow&lt;/code&gt;. Smart pointers allocate their data on the &lt;strong&gt;heap&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Some smart pointers, like &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt;, can dynamically grow or shrink.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No memory leaks:&lt;/strong&gt; Smart pointers automatically clean up the resources they own when they go out of scope, so you don't need to call &lt;code&gt;free()&lt;/code&gt; manually!!!.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Fat Pointer (Borrower &amp;amp; Viewer)
&lt;/h3&gt;

&lt;p&gt;A Fat Pointer is a "borrowed" reference to a contiguos sequence of memory. Conceptually, a fat pointer is like a &lt;strong&gt;small struct&lt;/strong&gt; containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Address:&lt;/strong&gt; Where the data starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The length:&lt;/strong&gt; How many elements exist in the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Rust, &lt;strong&gt;Fat Pointers&lt;/strong&gt; are represented as &lt;strong&gt;Slices&lt;/strong&gt; (e.d., &lt;code&gt;&amp;amp;[u8]&lt;/code&gt; or &lt;code&gt;&amp;amp;str&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is this useful?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Windows:&lt;/strong&gt; If you have a 500MB file in RAM, you don't want to duplicate data just to look at the header. A Fat Pointer create a "window" into that existing file. It requieres zero memory allocation or zero copying. Which is very useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bounds Safety:&lt;/strong&gt; Because the Fat Pointer has it's own length, the Because the fat pointer carries its length, Rust performs a bounds check before doing the indexing. If the index is out of range, the program safely panics instead of reading invalid memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rust vs C/C++
&lt;/h3&gt;

&lt;p&gt;The reason why these concepts feel weird at first is because C &amp;amp; C++ rely almost entirely on Naked Pointers (const u8*)&lt;br&gt;
A naked Pointer is just a note with an address (&lt;code&gt;0x7FFF0042&lt;/code&gt;), so it has no conext, length and no context.&lt;/p&gt;

&lt;h3&gt;
  
  
  First difference: Bounds checking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;strong&gt;C/C++&lt;/strong&gt; when you write ptr[500], the CPU does the math (ptr+500) and walks blindly 500 steps past the address. So if your array was only 15 bytes long, you may read unrelated memory from your own process or trigger a segmentation fault.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust:&lt;/strong&gt; When you write slice[500], Rust automatically checks whether 500 is within the slice's length. If it's out of bounds, the program safely stops itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Second Difference: Memory Leaks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C/C++:&lt;/strong&gt; Heap allocations are not automatically cleaned up. Even if a pointer variable goes out of scope, the allocated memory stays alive until you explicitly call free() or delete. If you forget, the program leaks memory.&lt;br&gt;
&lt;strong&gt;Rust:&lt;/strong&gt; By using a Smart Pointer (&lt;code&gt;Vec&lt;/code&gt;), Rust automatically inserts calls to drop when ownership ends. As a result, you can't accidentally forget to &lt;strong&gt;free memory&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third Difference: Creating vs. Passing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C/C++:&lt;/strong&gt; You pass naked pointers everywhere. You pass them in order to create data, and also to read it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In Rust:&lt;/strong&gt; You use Smart Pointers (Vec) only when you need to create and own data. So immediately after, you slice them into Fat Pointers in order to pass to your functions so they can efficiently borrow and read the data.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>The Ilusion of Arrays: Pointer Casting, and the Danger of memory Reinterpretation</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:10:34 +0000</pubDate>
      <link>https://dev.to/0xlozi/the-ilusion-of-arrays-pointer-casting-and-the-danger-of-memory-reinterpretation-4ek7</link>
      <guid>https://dev.to/0xlozi/the-ilusion-of-arrays-pointer-casting-and-the-danger-of-memory-reinterpretation-4ek7</guid>
      <description>&lt;p&gt;When optimizing software to run as fast as possible, developers tend to hit a wall with high-level data structures. To squeeze every inch of performance out of a processor, we have to stop looking at arrays as safe little boxes, and start lookin at RAM for what it really is: a MASSIVE, contiguous strip of single bytes!!!&lt;br&gt;
One of the most powerful optimization tricks in C, C++, and algo unsafe Rust is Pointer Casting, reinterpreting an array of 1 byte-data (u8) as an array of 4 bytes (u32). But this raw pointer comes with a high risk of hardware crashes. Here’s why:&lt;/p&gt;
&lt;h3&gt;
  
  
  The Optimization: Why the bother of casting &lt;code&gt;u8&lt;/code&gt; to &lt;code&gt;u32&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;A processor executes instructions in CPU CYCLES. If you need to read 4 bytes of data, a naive approach processes it through &lt;code&gt;u8&lt;/code&gt; (1 byte) pointer.&lt;br&gt;
&lt;strong&gt;Cycles:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load Byte 0&lt;/li&gt;
&lt;li&gt;Load Byte 1&lt;/li&gt;
&lt;li&gt;Load Byte 2&lt;/li&gt;
&lt;li&gt;Load Byte 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To optimize this, we change the “glasses” (just to make an analogy) the CPU is currently wearing. By taking the starting address of that &lt;code&gt;u8&lt;/code&gt; array and telling the compiler “Hey, pretend this is actually 🤓 a pointer of &lt;code&gt;u32&lt;/code&gt; data”, we change the &lt;strong&gt;memory stride&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Wait, wtf is a memory stride?
&lt;/h3&gt;

&lt;p&gt;A memory stride is &lt;strong&gt;the distance in bytes between consecutive elements in memory along a particular dimension of an array.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Let’s make an example:&lt;/strong&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="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;uint32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;per&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Inside the memory will be:&lt;/strong&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="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;   &lt;span class="mi"&gt;1004&lt;/span&gt;   &lt;span class="mi"&gt;1008&lt;/span&gt;   &lt;span class="mi"&gt;1012&lt;/span&gt;
&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mi"&gt;10&lt;/span&gt;     &lt;span class="mi"&gt;20&lt;/span&gt;     &lt;span class="mi"&gt;30&lt;/span&gt;     &lt;span class="mi"&gt;40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To go from 10 to 20, &lt;strong&gt;you have to move 4 bytes&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;To go from 20 to 30, &lt;strong&gt;you move another 4 bytes&lt;/strong&gt;
&lt;strong&gt;So:&lt;/strong&gt; &lt;code&gt;stride = 4&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffjfa5j2lsns6n33ju0zp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffjfa5j2lsns6n33ju0zp.png" alt="memory stride" width="708" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Result when we “change the glasses”
&lt;/h3&gt;

&lt;p&gt;Now when we tell the CPU to read index 0, it uses a 32-bit hardware register in order to &lt;strong&gt;swallow&lt;/strong&gt; &lt;code&gt;Bytes 0, 1, 2, and 3&lt;/code&gt; simultaneously; which leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cycle 1: Load Bytes 0, 1, 2, and also 3!!!!!!!
We just made the memory read almost 400% faster. However, lying to the compiler about the shape of your memory could open two massive failures at a hardware level…&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Problem 1: Alignment Fault
&lt;/h3&gt;

&lt;p&gt;Processors are wired to expect certain data types to align with specific &lt;strong&gt;memory boundaries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An u8 (1 byte) can start at any addres&lt;/li&gt;
&lt;li&gt;A u32 (4 bytes) is strictly expected to start at an addres that is perfectly dividisible by 4 (0, 4, 8…)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have an &lt;code&gt;u8&lt;/code&gt; array, and you decide to put on your &lt;code&gt;u32&lt;/code&gt; glasses starting at &lt;code&gt;Address 1&lt;/code&gt;, you just created an &lt;strong&gt;Unaligned Pointer&lt;/strong&gt;.&lt;br&gt;
So, when you ask the CPU to read a 4-byte chunk starting at A&lt;code&gt;ddress 1&lt;/code&gt;, the hardware struggles. Some processors (like modern intel x86) will silently fix the mistake behind the scenes. But processors liek ARM chips found in movile devices, consoles or embedded systems, physically can’t do it. So they will instantly panic and triggfer a Fatal Alignment Fault.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem 2: Modulo Trap
&lt;/h3&gt;

&lt;p&gt;Even if your starting Address is &lt;strong&gt;perfectly aligned&lt;/strong&gt;, the &lt;strong&gt;overall size&lt;/strong&gt; of your memory buffer can kill the program if it doesn’t divide perfectly into your &lt;strong&gt;new stride&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s imagine that you have a raw &lt;code&gt;u8&lt;/code&gt; buffer which is exactly 17 bytes long. Then you cast the pointer to &lt;code&gt;u32&lt;/code&gt; in order to read it faster&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="mi"&gt;17&lt;/span&gt; &lt;span class="n"&gt;modulo&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that you have 4 perfect chunks , but 1 &lt;strong&gt;trailing byte&lt;/strong&gt; remaining…&lt;br&gt;
So... when you loop through the memory with your u32 glasses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Index [0]:&lt;/code&gt; Reads bytes 0-3 (Safe…)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Index [1]:&lt;/code&gt; Reads bytes 4-7 (Safe…)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Index [2]:&lt;/code&gt; Reads bytes 8-11 (Safe…)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Index [3]:&lt;/code&gt; Reads bytes 12-15 (Safe…)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Index [4]:&lt;/code&gt; Reads byte 16... and bytes 17, 18, and 19 💀💀💀&lt;/strong&gt;
Since you told the CPU it was reading a 4 byte structure.. It blindly reads past the end of your 17 byte buffer…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If bytes 17, 18, and 19 belong to the Operating System's restricted memory, the OS kills your program with a** Segmentation Fault** for trespassing.&lt;br&gt;
Worse, if those bytes belong to another variable inside your own program, the CPU reads or overwrites them silently. Your program keeps running but with corrupted data… This is the definition of &lt;strong&gt;Undefined Behavior (UB)&lt;/strong&gt;. Good luck with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  C/C++ vs. Safe Rust
&lt;/h3&gt;

&lt;p&gt;In C and C++, the compiler implicitly trusts the developer. If you cast a &lt;code&gt;char*&lt;/code&gt; to an &lt;code&gt;int*&lt;/code&gt;, the compiler assumes you have &lt;strong&gt;manually verified&lt;/strong&gt; the alignment and &lt;strong&gt;modulo math&lt;/strong&gt;. When human error inevitably occurs, it results in security vulnerabilities.&lt;br&gt;
&lt;strong&gt;Rust solves this by splitting the logic:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;unsafe Rust:&lt;/strong&gt;
You can still perform raw pointer casting using &lt;code&gt;std::slice::from_raw_parts&lt;/code&gt; and pointer casting (as &lt;code&gt;*const u32&lt;/code&gt;). But you must wrap it in an &lt;code&gt;unsafe {}&lt;/code&gt; block, taking personal responsibility for the math. If it crashes, you know exactly which block of code to blame!!!.
&lt;strong&gt;2. Safe Rust (Zero-Cost Abstractions):&lt;/strong&gt;
Instead of manually casting pointers, safe Rust provides methods like &lt;code&gt;.copy_from_slice()&lt;/code&gt;, &lt;code&gt;.copy_within()&lt;/code&gt;, or &lt;code&gt;.try_into()&lt;/code&gt;.
When you use these, the Rust compiler checks the alignment and array lengths at compile time or safely handles them under the hood. It compiles down to the exact same hyper-efficient hardware instructions (like &lt;code&gt;memmove&lt;/code&gt; or &lt;code&gt;SIMD&lt;/code&gt; loads) that a manual C-pointer cast would achieve, but mathematically guarantees &lt;strong&gt;you cannot trigger an Alignment Fault or step out of bounds.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>From C++ to Rust: When Structure Layout Becomes Part of the Algorithm</title>
      <dc:creator>Lozi</dc:creator>
      <pubDate>Thu, 04 Jun 2026 17:49:17 +0000</pubDate>
      <link>https://dev.to/0xlozi/from-c-to-rust-when-structure-layout-becomes-part-of-the-algorithm-4poi</link>
      <guid>https://dev.to/0xlozi/from-c-to-rust-when-structure-layout-becomes-part-of-the-algorithm-4poi</guid>
      <description>&lt;p&gt;Have you ever stumbled upon code that works almost like a miracle, entirely because of how the compiler lays out data in memory?&lt;/p&gt;

&lt;p&gt;Recently, while I was working on a port of a decryption for executable files (specifically EBOOT.BIN) from the PSP that was originally written in C++, I found a design pattern that brought me different emotions such as "fascination" and "paranoia"...&lt;/p&gt;

&lt;p&gt;Today I want to document how a PSP decryption routine relies on contiguous structure layout to treat multiple adjacent fields as a single cryptographic workspace, the challenges of porting this design to Rust, and how I validated the implementation using an integration test with a real EBOOT.BIN file from Lego Batman.&lt;/p&gt;

&lt;h2&gt;
  
  
  First case: When The Structure Layout Becomes Part of the Algorithm
&lt;/h2&gt;

&lt;p&gt;Let's analyze the original C++ structure I used to map the encrypted executable layout of the &lt;code&gt;PRXType1&lt;/code&gt; format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;PRXType1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;explicit&lt;/span&gt; &lt;span class="n"&gt;PRXType1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0xD0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0xD4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0xE8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unused&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kirkBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kirkBlock&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kirkBlock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prxHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prxHeader&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// LOOK AT THIS NOW&lt;/span&gt;
        &lt;span class="n"&gt;kirk7&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sha1&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0xC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sha1&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0xC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;         &lt;span class="c1"&gt;// 4 bytes&lt;/span&gt;
    &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x14&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;     &lt;span class="c1"&gt;// 20 bytes (0x14)&lt;/span&gt;
    &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x28&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;   &lt;span class="c1"&gt;// 40 bytes&lt;/span&gt;
    &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;kirkBlock&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x90&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="c1"&gt;// 144 bytes&lt;/span&gt;
    &lt;span class="n"&gt;u8&lt;/span&gt; &lt;span class="n"&gt;prxHeader&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="c1"&gt;// 128 bytes&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PRXType1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mh"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"inconsistent size of PRX Type 1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now u may ask: Where is the trick?
&lt;/h3&gt;

&lt;p&gt;Pay attention to the &lt;code&gt;decrypt&lt;/code&gt; fn. It calls the PSP's cryptographic engine (which is &lt;code&gt;kirk7&lt;/code&gt;), passing as a source &lt;code&gt;SHA1 + 0xC&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;sha1&lt;/code&gt; array is EXACTLY &lt;code&gt;0x14&lt;/code&gt; (20 bytes) long&lt;/li&gt;
&lt;li&gt;If we move &lt;code&gt;0xC&lt;/code&gt; (12 bytes) FORWARD, we only have 8 bytes left in that specific array&lt;/li&gt;
&lt;li&gt;HOWEVER, the third parameter says to process &lt;code&gt;0xA0&lt;/code&gt; (which is 160 BYTES)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we know that, Why the program didn't crash? Because the fields reside in a single contiguous structure object. (one after another). Although the pointer originates inside the sha1 field, the cryptographic routine processes 160 consecutive bytes. In practice, this means that the operation spans the remaining bytes of sha1, all of unused, and part of kirkBlock. The implementation therefore treats several adjacent fields as a single contiguous cryptographic workspace.&lt;/p&gt;

&lt;p&gt;Because the decryption routine depends on a very specific memory layout, changing the declaration order of the fields would alter the 160-byte region processed by kirk7. Such a change would likely corrupt the decrypted data and break the algorithm entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does kirk7 Actually Do?
&lt;/h3&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;kirk7&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;outbuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;inbuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;keyId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AES_ctx&lt;/span&gt; &lt;span class="n"&gt;aesKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kirk_4_7_get_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;AES_set_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aesKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;AES_cbc_decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;aesKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outbuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&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;Since the pointer begins at sha1 + 0xC and the requested size is 0xA0 (160 bytes), the operation spans the remaining bytes of sha1, all of unused, and part of kirkBlock.&lt;br&gt;
In other words, the algorithm is not really interested in the sha1 field itself. It is operating on a 160-byte cryptographic workspace whose starting point happens to lie inside sha1.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Rust Philosophy: Explicit safety without sacrificing performance.
&lt;/h2&gt;

&lt;p&gt;When I decided to port this to Rust, I quickly realized that the original implementation relies on pointer arithmetic spanning multiple adjacent fields. While Rust can express the same behavior through raw pointers and unsafe code, I wanted a solution that made the memory region explicit and remained fully safe. Instead of relying on a pointer that implicitly goes to several fields, I represented the entire workspace as a single byte array and passed the exact range required by the decryption routine.&lt;/p&gt;

&lt;p&gt;To solve this, I decided to use a single flat byte array (which is &lt;code&gt;[u8; 0x150&lt;/code&gt;) and create read-only views (slices) based on fixed offsets. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is my implementation:&lt;/strong&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;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PrxType1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;PrxType1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/// Constructs a new PrxType1 from raw file bytes.&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&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;prx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="c1"&gt;// Reconstruct the layout respecting the original C++ offsets:&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xD4&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;         &lt;span class="c1"&gt;// tag&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x18&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xD4&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xE8&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;      &lt;span class="c1"&gt;// sha1 (20 bytes)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x18&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xE8&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x110&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;  &lt;span class="c1"&gt;// unused (40 bytes)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x40&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x110&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// kirkBlock part 1 (64 bytes)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x80&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x80&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;   &lt;span class="c1"&gt;// kirkBlock part 2&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;     &lt;span class="c1"&gt;// prxHeader (128 bytes)&lt;/span&gt;

        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;decrypt&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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;KirkError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// In C++ the signature was: kirk7(sha1+0xC, sha1+0xC, 0xA0, key);&lt;/span&gt;
        &lt;span class="c1"&gt;// Our 'sha1' starts at offset 4.&lt;/span&gt;
        &lt;span class="c1"&gt;// 4 + 12 (0xC) = 16 (0x10).&lt;/span&gt;
        &lt;span class="c1"&gt;// If we want to decrypt 160 bytes (0xA0): 16 + 160 = 176 (0xB0).&lt;/span&gt;

        &lt;span class="c1"&gt;// Rust allows us to express the exact memory range explicitly and safely:&lt;/span&gt;
        &lt;span class="nf"&gt;kirk7&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="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x10&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xB0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;key_id&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// --- Safe Views (Read-only Slices) ---&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;tag&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;]&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;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;sha1&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;]&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;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x18&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;unused&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;]&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;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x18&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;kirk_block&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;]&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;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x40&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;prx_header&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;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;]&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;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0xD0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x150&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    

    &lt;span class="cd"&gt;/// This verifies integrity by recalculating the header hash (it does this in the original decrypt project but I prefer doing it here)&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_valid&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;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xorbuf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&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;hasher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Sha1&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;hasher&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;xorbuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0x14&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="n"&gt;hasher&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.unused&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;hasher&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.kirk_block&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;hasher&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.prx_header&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hash_calculated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hasher&lt;/span&gt;&lt;span class="nf"&gt;.finalize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;hash_calculated&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="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.sha1&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why I think this solution is great?
&lt;/h3&gt;

&lt;p&gt;We keep the extreme performance of C++ because we are doing 0 dynamic allocations or array cloning. By passing the range &lt;code&gt;&amp;amp;mut self.data[0x10..0xB0]&lt;/code&gt; to kirk7, Rust guarantees via bounds checking that the cryptographic function operates strictly within those 160 bytes. So if we were to miscalculate the offsets, the program would trigger panic rather than silentyly corrupting other memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  The moment of Truth
&lt;/h3&gt;

&lt;p&gt;To ensure that this implementation was mathematically justified and the offset math was perfect, I wrote an integration test using the actual EBOOT.BIN file from the Lego Batman Game from the PSP.&lt;br&gt;
This test load the specified file, extract the TAG dinamically, looks up to the corresponding hardware key using a key service (allocated into keys_service.rs), it generates the XOR buffer, runs the decryption, and validates via SHA-1 if the resulting bytes match the game's original structure!!!.&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="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&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;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&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;Read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_lego_batman_type1_valido&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Load the real PSP binary&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ruta_eboot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/home/snake/Downloads/lego_batman_game/PSP_GAME/SYSDIR/EBOOT.BIN"&lt;/span&gt;&lt;span class="p"&gt;;&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;File&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="n"&gt;ruta_eboot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not open EBOOT!"&lt;/span&gt;&lt;span class="p"&gt;);&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;eboot_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&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_end&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;eboot_data&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;// 2. Map data to our flat structure&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;type1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PrxType1&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;eboot_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Extract the crypto Tag (Should evaluate to 0xC0CB167C automatically)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tag_bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="nf"&gt;.tag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.try_into&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tag doesn't have 4 bytes"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_le_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag_bytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

        &lt;span class="c1"&gt;// 4. Fetch the keys for this specific game&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;key_eboot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;keys_service&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_tag_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This game's Tag is missing from the database!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;key_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_eboot&lt;/span&gt;&lt;span class="py"&gt;.code&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&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;xorbuf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;144&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;key_eboot&lt;/span&gt;&lt;span class="py"&gt;.key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;KeyType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;U8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;xorbuf&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;key_array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nn"&gt;KeyType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;U32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;key_array&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;xorbuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.copy_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.to_le_bytes&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="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// 5. Decrypt using our safe Rust memory range!&lt;/span&gt;
        &lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="nf"&gt;.decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AES engine failed..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 6. Final validation: Does the calculated hash match the EBOOT offset?&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;es_valido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="nf"&gt;.is_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;xorbuf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// If this passes, our contiguous memory emulation was an absolute success&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;es_valido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SHA-1 hash mismatch... Decryption failed!"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result: &lt;code&gt;TEST PASSED (OK)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We managed to replicate the exact behavior of the original PSP implementation without inheriting it's dangerous security risks&lt;/p&gt;

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

&lt;p&gt;I am writing this article in order to prevent myself from forgetting this architectural headache as the project continues to scale...&lt;br&gt;
Mastering memory isn't just about programming retro consoles. It's about understanding how data layout, performance, and correctness interact in every system we build.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
