This commit is contained in:
Hykilpikonna
2021-12-07 22:28:01 -05:00
commit 6fffdf686a
151 changed files with 37985 additions and 0 deletions
@@ -0,0 +1,415 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.1 An Introduction to Cryptography</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="../tufte.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.1 An Introduction to Cryptography</h1>
</header>
<section>
<p>So far weve seen how the data types we introduced in Chapter 1 can be used to store a variety of different data. In our modern world, data is constantly being created, stored, sent, and received. But not all data is created equal; some data is inherently more sensitive than other data. And <a href="https://en.wikipedia.org/wiki/Personal_Information_Protection_and_Electronic_Documents_Act">there are laws</a> mandating the privacy of your data in Canada. Thanks to the explosion of data and the evolution of privacy policy, there are numerous technologies (backed by a strong theoretical underpinning) being developed to ensure data privacy.</p>
<p>After our work from last week, we now have the theoretical foundations necessary to learn about one of the coolest applications of number theory in computer science: encrypting messages so that only the sender and receiver can read them.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> Check out the movie <a href="https://en.wikipedia.org/wiki/The_Imitation_Game">The Imitation Game</a>, which is about some amazing codebreaking work done in World War II (and a crucial piece in the history of computing).</span> This is only one method for ensuring data privacy, but it is pervasive—nearly every time you send or receive something on your phone or web browser, cryptography plays a role. In this section, youll learn about the basics of <em>cryptography</em>, which is the study of theoretical and practical techniques for keeping data secure.</p>
<h2 id="what-is-cryptography">What is cryptography?</h2>
<p>Cryptography is the study of techniques used to keep communication secure in the face of adversaries who wish to eavesdrop on or interfere with the communication. Defining what <em>secure</em> communication between two parties means is complex, and involves several dimensions such as: confidentiality, data integrity, and authentication. In this chapter we will focus primarily on encryption, which involves turning coherent messages into seemingly-random nonsensical strings, and then back again.</p>
<p>As computers have become more powerful, cryptographic technologies have evolved to ensure that the “nonsense” strings are not easily converted back to the coherent message except by the intended recipient(s). But the growing power of computers is a double-edged sword; while cryptographic technologies have evolved, so have the technologies of malicious attackers and eavesdroppers who want to decipher the “nonsense” strings and gain access to sensitive data, such as passwords and social insurance numbers.</p>
<h2 id="setting-the-stage-alice-and-bob">Setting the stage: Alice and Bob</h2>
<p>The simplest setup that we study in cryptography is <em>two-party confidential communication</em>. In this setup, we have two people, Alice and Bob, who wish to send messages to each other that only they can read, and a third person, Eve, who has access to all of the communications between Alice and Bob, and wants to discover what theyre saying.</p>
<p>Since Eve has access to the communications between Alice and Bob, they cant just send their messages directly. So instead, Alice and Bob need to encrypt their messages using some sort of encryption algorithm, and send the encrypted versions to each other instead. The hope is that through some shared piece of information called a secret key, Alice and Bob can encrypt their messages in such a way that they will each be able to decrypt each others messages, but Eve wont be able to decrypt the messages without knowing their secret key.</p>
<p>More formally, we define a <strong>secure symmetric-key cryptosystem</strong> as a system with the following parts:</p>
<ul>
<li><p>A set <span class="math inline">\(\mathcal{P}\)</span> of possible original messages, called <strong>plaintext</strong> messages. (E.g., a set of strings)</p></li>
<li><p>A set <span class="math inline">\(\mathcal{C}\)</span> of possible encrypted messages, called <strong>ciphertext</strong> messages. (E.g., another set of strings)</p></li>
<li><p>A set <span class="math inline">\(\mathcal{K}\)</span> of possible <strong>shared secret keys</strong> (known by both Alice and Bob, but no one else).</p></li>
<li><p>Two functions <span class="math inline">\(Encrypt : \mathcal{K} \times \mathcal{P} \to \mathcal{C}\)</span> and <span class="math inline">\(Decrypt : \mathcal{K} \times \mathcal{C} \to \mathcal{P}\)</span> that satisfies the following two properties:</p>
<ul>
<li>(<em>correctness</em>) For all <span class="math inline">\(k \in \mathcal{K}\)</span> and <span class="math inline">\(m \in \mathcal{P}\)</span>, <span class="math inline">\(Decrypt(k, Encrypt(k, m)) = m\)</span>. (That is, if you encrypt and then decrypt the same message with the same key, you get back the original message.)</li>
<li>(<em>security</em>) For all <span class="math inline">\(k \in \mathcal{K}\)</span> and <span class="math inline">\(m \in \mathcal{P}\)</span>, if an eavesdropper only knows the value of <span class="math inline">\(c = Encrypt(k, m)\)</span> but does not know <span class="math inline">\(k\)</span>, it is computationally infeasible to find <span class="math inline">\(m\)</span>.</li>
</ul></li>
</ul>
<h2 id="example-caesars-substitution-cipher">Example: Caesars substitution cipher</h2>
<p>One of the earliest examples we have of a symmetric-key cryptosystem is the <em>Caesar cipher</em>, named after the Roman general Julius Caesar. In this system, the plaintext and ciphertext sets are simply strings, and the secret key is some positive integer <span class="math inline">\(k\)</span>.</p>
<p>The idea of this cryptosystem, as well as the starting point of many others, is to associate characters with numbers, because we can do more things with numbers. In this example, well first only consider messages that consist of uppercase letters and spaces, and associate each of these letters with a number as follows:</p>
<div class="reference-table">
<table>
<thead>
<tr class="header">
<th style="text-align: center;">Character</th>
<th style="text-align: center;">Value</th>
<th style="text-align: center;">Character</th>
<th style="text-align: center;">Value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: center;"><code>'A'</code></td>
<td style="text-align: center;"><code>0</code></td>
<td style="text-align: center;"><code>'O'</code></td>
<td style="text-align: center;"><code>14</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'B'</code></td>
<td style="text-align: center;"><code>1</code></td>
<td style="text-align: center;"><code>'P'</code></td>
<td style="text-align: center;"><code>15</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'C'</code></td>
<td style="text-align: center;"><code>2</code></td>
<td style="text-align: center;"><code>'Q'</code></td>
<td style="text-align: center;"><code>16</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'D'</code></td>
<td style="text-align: center;"><code>3</code></td>
<td style="text-align: center;"><code>'R'</code></td>
<td style="text-align: center;"><code>17</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'E'</code></td>
<td style="text-align: center;"><code>4</code></td>
<td style="text-align: center;"><code>'S'</code></td>
<td style="text-align: center;"><code>18</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'F'</code></td>
<td style="text-align: center;"><code>5</code></td>
<td style="text-align: center;"><code>'T'</code></td>
<td style="text-align: center;"><code>19</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'G'</code></td>
<td style="text-align: center;"><code>6</code></td>
<td style="text-align: center;"><code>'U'</code></td>
<td style="text-align: center;"><code>20</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'H'</code></td>
<td style="text-align: center;"><code>7</code></td>
<td style="text-align: center;"><code>'V'</code></td>
<td style="text-align: center;"><code>21</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'I'</code></td>
<td style="text-align: center;"><code>8</code></td>
<td style="text-align: center;"><code>'W'</code></td>
<td style="text-align: center;"><code>22</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'J'</code></td>
<td style="text-align: center;"><code>9</code></td>
<td style="text-align: center;"><code>'X'</code></td>
<td style="text-align: center;"><code>23</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'K'</code></td>
<td style="text-align: center;"><code>10</code></td>
<td style="text-align: center;"><code>'Y'</code></td>
<td style="text-align: center;"><code>24</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'L'</code></td>
<td style="text-align: center;"><code>11</code></td>
<td style="text-align: center;"><code>'Z'</code></td>
<td style="text-align: center;"><code>25</code></td>
</tr>
<tr class="odd">
<td style="text-align: center;"><code>'M'</code></td>
<td style="text-align: center;"><code>12</code></td>
<td style="text-align: center;"><code>' '</code></td>
<td style="text-align: center;"><code>26</code></td>
</tr>
<tr class="even">
<td style="text-align: center;"><code>'N'</code></td>
<td style="text-align: center;"><code>13</code></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
</tr>
</tbody>
</table>
</div>
<p>In Python, we can implement this conversion as follows:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1"></a>LETTERS <span class="op">=</span> <span class="st">&#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ &#39;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="kw">def</span> letter_to_num(c: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">int</span>:</span>
<span id="cb1-5"><a href="#cb1-5"></a> <span class="co">&quot;&quot;&quot;Return the number that corresponds to the given letter.</span></span>
<span id="cb1-6"><a href="#cb1-6"></a></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="co"> Preconditions:</span></span>
<span id="cb1-8"><a href="#cb1-8"></a><span class="co"> - len(c) == 1 and c in LETTERS</span></span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb1-10"><a href="#cb1-10"></a> <span class="cf">return</span> <span class="bu">str</span>.index(LETTERS, c)</span>
<span id="cb1-11"><a href="#cb1-11"></a></span>
<span id="cb1-12"><a href="#cb1-12"></a></span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="kw">def</span> num_to_letter(n: <span class="bu">int</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb1-14"><a href="#cb1-14"></a> <span class="co">&quot;&quot;&quot;Return the letter that corresponds to the given number.</span></span>
<span id="cb1-15"><a href="#cb1-15"></a></span>
<span id="cb1-16"><a href="#cb1-16"></a><span class="co"> Precondtions:</span></span>
<span id="cb1-17"><a href="#cb1-17"></a><span class="co"> - 0 &lt;= n &lt; len(LETTERS)</span></span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb1-19"><a href="#cb1-19"></a> <span class="cf">return</span> LETTERS[n]</span></code></pre></div>
<p>In the Caesar cipher, the secret key <span class="math inline">\(k\)</span> is an integer from the set <span class="math inline">\(\{1, 2, \dots, 26\}\)</span>. So before sending any messages, Alice and Bob meet and decide on a secret key from this set.</p>
<p>Now when Alice wants to send a string message <span class="math inline">\(m\)</span> to Bob, she <em>encrypts</em> her message as follows:</p>
<ul>
<li>For each character of <span class="math inline">\(m\)</span>, Alice shifts it by adding the secret key <span class="math inline">\(k\)</span> to its corresponding numbers, taking remainders modulo 27, the length of <code>LETTERS</code>. Note that the space character <code></code> comes after <code>Z</code>.</li>
</ul>
<p>For example, if <span class="math inline">\(k = 3\)</span>, and the plaintext message is <code>'HAPPY'</code>, encryption happens as follows:</p>
<div class="reference-table">
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 28%" />
<col style="width: 20%" />
<col style="width: 26%" />
</colgroup>
<thead>
<tr class="header">
<th>Plaintext character</th>
<th>Corresponding Integer</th>
<th>Shifted Integer</th>
<th>Ciphertext character</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>'H'</code></td>
<td><code>7</code></td>
<td><code>10</code></td>
<td><code>'K'</code></td>
</tr>
<tr class="even">
<td><code>'A'</code></td>
<td><code>0</code></td>
<td><code>3</code></td>
<td><code>'D'</code></td>
</tr>
<tr class="odd">
<td><code>'P'</code></td>
<td><code>15</code></td>
<td><code>18</code></td>
<td><code>'S'</code></td>
</tr>
<tr class="even">
<td><code>'P'</code></td>
<td><code>15</code></td>
<td><code>18</code></td>
<td><code>'S'</code></td>
</tr>
<tr class="odd">
<td><code>'Y'</code></td>
<td><code>24</code></td>
<td><code>0</code></td>
<td><code>'A'</code></td>
</tr>
</tbody>
</table>
</div>
<p>The corresponding ciphertext is <code>'KDSSA'</code>. Note that the <code>Y</code>, when shifted by 3, wraps around to become <code>A</code>.</p>
<p>Then when Bob receives the ciphertext <code>'KDSSA'</code>, he decrypts the ciphertext by applying the corresponding shift in reverse (subtracting the secret key <span class="math inline">\(k\)</span> instead of adding it). We can implement this in Python as follows:<label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"/><span class="sidenote"> Note that weve dropped the <code>_so_far</code> suffix on these accumulator variables now that youre more experience writing loops!</span></p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">def</span> encrypt_caesar(k: <span class="bu">int</span>, plaintext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb2-2"><a href="#cb2-2"></a> <span class="co">&quot;&quot;&quot;Return the encrypted message using the Caesar cipher with key k.</span></span>
<span id="cb2-3"><a href="#cb2-3"></a></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="co"> Preconditions:</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="co"> - all({x in LETTERS for x in plaintext})</span></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="co"> - 1 &lt;= k &lt;= 26</span></span>
<span id="cb2-7"><a href="#cb2-7"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb2-8"><a href="#cb2-8"></a> ciphertext <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb2-9"><a href="#cb2-9"></a></span>
<span id="cb2-10"><a href="#cb2-10"></a> <span class="cf">for</span> letter <span class="kw">in</span> plaintext:</span>
<span id="cb2-11"><a href="#cb2-11"></a> ciphertext <span class="op">=</span> ciphertext <span class="op">+</span> num_to_letter((letter_to_num(letter) <span class="op">+</span> k) <span class="op">%</span> <span class="bu">len</span>(LETTERS))</span>
<span id="cb2-12"><a href="#cb2-12"></a></span>
<span id="cb2-13"><a href="#cb2-13"></a> <span class="cf">return</span> ciphertext</span>
<span id="cb2-14"><a href="#cb2-14"></a></span>
<span id="cb2-15"><a href="#cb2-15"></a></span>
<span id="cb2-16"><a href="#cb2-16"></a><span class="kw">def</span> decrypt_caesar(k: <span class="bu">int</span>, ciphertext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb2-17"><a href="#cb2-17"></a> <span class="co">&quot;&quot;&quot;Return the decrypted message using the Caesar cipher with key k.</span></span>
<span id="cb2-18"><a href="#cb2-18"></a></span>
<span id="cb2-19"><a href="#cb2-19"></a><span class="co"> Preconditions:</span></span>
<span id="cb2-20"><a href="#cb2-20"></a><span class="co"> - all({x in LETTERS for x in ciphertext})</span></span>
<span id="cb2-21"><a href="#cb2-21"></a><span class="co"> - 1 &lt;= k &lt;= 26</span></span>
<span id="cb2-22"><a href="#cb2-22"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb2-23"><a href="#cb2-23"></a> plaintext <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb2-24"><a href="#cb2-24"></a></span>
<span id="cb2-25"><a href="#cb2-25"></a> <span class="cf">for</span> letter <span class="kw">in</span> ciphertext:</span>
<span id="cb2-26"><a href="#cb2-26"></a> plaintext <span class="op">=</span> plaintext <span class="op">+</span> num_to_letter((letter_to_num(letter) <span class="op">-</span> k) <span class="op">%</span> <span class="bu">len</span>(LETTERS))</span>
<span id="cb2-27"><a href="#cb2-27"></a></span>
<span id="cb2-28"><a href="#cb2-28"></a> <span class="cf">return</span> plaintext</span></code></pre></div>
<h3 id="expanding-the-set-of-letters">Expanding the set of letters</h3>
<p>In our example above, we restricted ourselves to only upper-case letters and spaces. But the key mathematical idea of the Caesar cipher, shifting letters based on a secret key <span class="math inline">\(k\)</span> used as an offset, generalizes to larger sets of letters.</p>
<p>To see how to do this, first we recall two built-in Python functions from <a href="../02-functions/08-representing-text.html">Section 2.8 Application: Representing Text</a>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="bu">ord</span>(<span class="st">&#39;A&#39;</span>) <span class="co"># Convert a character into an integer</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="dv">65</span></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="op">&gt;&gt;&gt;</span> <span class="bu">chr</span>(<span class="dv">33</span>) <span class="co"># Convert an integer into a character</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="co">&#39;!&#39;</span></span></code></pre></div>
<p>Using these two functions, we can modify our <code>encrypt</code> and <code>decrypt</code> functions in the Caesar cipher to operate on arbitrary Python strings. For simplicity, well stick only to the first 128 characters, which are known as the ASCII characters.<label for="sn-2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-2" class="margin-toggle"/><span class="sidenote">You might recall from Section 2.8 that <em>ASCII</em> is one of the earliest standard for encoding characters as natural numbers on a computer.</span> Our secret key will now take on values from the set <span class="math inline">\(\{1, 2, \dots, 127\}\)</span>.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">def</span> encrypt_ascii(k: <span class="bu">int</span>, plaintext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb4-2"><a href="#cb4-2"></a> <span class="co">&quot;&quot;&quot;Return the encrypted message using the Caesar cipher with key k.</span></span>
<span id="cb4-3"><a href="#cb4-3"></a></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="co"> Preconditions:</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co"> - all({ord(c) &lt; 128 for c in plaintext})</span></span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="co"> - 1 &lt;= k &lt;= 127</span></span>
<span id="cb4-7"><a href="#cb4-7"></a></span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="co"> &gt;&gt;&gt; encrypt_ascii(4, &#39;Good morning!&#39;)</span></span>
<span id="cb4-9"><a href="#cb4-9"></a><span class="co"> &#39;Kssh$qsvrmrk%&#39;</span></span>
<span id="cb4-10"><a href="#cb4-10"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb4-11"><a href="#cb4-11"></a> ciphertext <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb4-12"><a href="#cb4-12"></a></span>
<span id="cb4-13"><a href="#cb4-13"></a> <span class="cf">for</span> letter <span class="kw">in</span> plaintext:</span>
<span id="cb4-14"><a href="#cb4-14"></a> ciphertext <span class="op">=</span> ciphertext <span class="op">+</span> <span class="bu">chr</span>((<span class="bu">ord</span>(letter) <span class="op">+</span> k) <span class="op">%</span> <span class="dv">128</span>)</span>
<span id="cb4-15"><a href="#cb4-15"></a></span>
<span id="cb4-16"><a href="#cb4-16"></a> <span class="cf">return</span> ciphertext</span>
<span id="cb4-17"><a href="#cb4-17"></a></span>
<span id="cb4-18"><a href="#cb4-18"></a></span>
<span id="cb4-19"><a href="#cb4-19"></a><span class="kw">def</span> decrypt_ascii(k: <span class="bu">int</span>, ciphertext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb4-20"><a href="#cb4-20"></a> <span class="co">&quot;&quot;&quot;Return the decrypted message using the Caesar cipher with key k.</span></span>
<span id="cb4-21"><a href="#cb4-21"></a></span>
<span id="cb4-22"><a href="#cb4-22"></a><span class="co"> Preconditions:</span></span>
<span id="cb4-23"><a href="#cb4-23"></a><span class="co"> - all({ord(c) &lt; 128 for c in ciphertext})</span></span>
<span id="cb4-24"><a href="#cb4-24"></a><span class="co"> - 1 &lt;= k &lt;= 127</span></span>
<span id="cb4-25"><a href="#cb4-25"></a></span>
<span id="cb4-26"><a href="#cb4-26"></a><span class="co"> &gt;&gt;&gt; decrypt_ascii(4, &#39;Kssh$qsvrmrk%&#39;)</span></span>
<span id="cb4-27"><a href="#cb4-27"></a><span class="co"> &#39;Good morning!&#39;</span></span>
<span id="cb4-28"><a href="#cb4-28"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb4-29"><a href="#cb4-29"></a> plaintext <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb4-30"><a href="#cb4-30"></a></span>
<span id="cb4-31"><a href="#cb4-31"></a> <span class="cf">for</span> letter <span class="kw">in</span> ciphertext:</span>
<span id="cb4-32"><a href="#cb4-32"></a> plaintext <span class="op">+=</span> <span class="bu">chr</span>((<span class="bu">ord</span>(letter) <span class="op">-</span> k) <span class="op">%</span> <span class="dv">128</span>)</span>
<span id="cb4-33"><a href="#cb4-33"></a></span>
<span id="cb4-34"><a href="#cb4-34"></a> <span class="cf">return</span> plaintext</span></code></pre></div>
<p><strong>WARNING</strong>: in practice, the Caeser cipher is not secure, as it is very possible for an eavesdropper to simply try all possible secret keys to decrypt a ciphertext, and pick out the most likely message that Alice sent. So while this example is good for educational purposes, you should <em>definitely not</em> use this cryptosystem for any real-world applications!</p>
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>
+109
View File
@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.2 The One-Time Pad and Perfect Secrecy</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="../tufte.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.2 The One-Time Pad and Perfect Secrecy</h1>
</header>
<section>
<p>The Caesar cipher we studied in the previous section is simple enough as a starting point, but should never be used in practice! It suffers from the fatal flaw that each character of the plaintext is encrypted individually, using the same secret key each time. So for example, every occurrence of the character <code>'D'</code> in the plaintext is transformed into the same character in the ciphertext. Why is this a problem?</p>
<p>Consider the ciphertext <code>'OLaTO+T^+NZZW'</code> generated by the ASCII-based Caesar cipher. Even though it may look indecipherable at first, there is information that we can learn about the original plaintext just by looking at the distribution of letters in the ciphertext.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> Given these observations and the hint that the plaintext is a common phrase used in CSC110, can you determine the plaintext?</span></p>
<ul>
<li>The first and fifth letters in the plaintext must be the same, since they both map to <code>'O'</code> in the ciphertext.</li>
<li>Similarly, the sixth and ninth characters must be the same, and the eleventh and twelfth characters must be the same.</li>
<li>Because the Caesar cipher is <em>additive</em>, it preserves the relative <code>ord</code> of each character. Since <code>ord('O') = 79</code> and <code>ord('N') = 78</code>, we know that the first and tenth characters of the plaintext must be consecutive ASCII characters.</li>
</ul>
<p>In addition to what we can infer from the distribution of letters in the ciphertext, the ASCII-based Caesar cipher is vulnerable to a <em>brute-force exhaustive key search attack</em>. There are only 128 possible secret keys the cipher could use (corresponding to the possible remainders of modulo 128). So, given a ciphertext, it is possible to try out every secret key and see which key yields a meaningful plaintext message.<label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"/><span class="sidenote"> For most ciphertexts generated from English plaintexts, only one possible secret key causes the decrypted message to be a meaningful English message.</span> Thats not very secure.</p>
<p>Even if we enlarge the set of possible keys (e.g., by using a more general text encoding like UTF8), Caesar ciphers are still vulnerable to observations like the ones we made earlier. From these observations, we can identify “likely” keys that a brute force search could try first. So the main weakness of the Caesar cipher is not just the number of possible keys.</p>
<h2 id="the-one-time-pad">The one-time pad</h2>
<p>We will now introduce a new symmetric-key cryptosystem known as the <strong>one-time pad</strong> that is structurally similar to the Caesar cipher, but avoids the issues we raised earlier. Encryption in the one-time pad works by shifting each character in the plaintext message, much like the Caesar cipher. But where the one-time pad differs is that the shift is <em>not</em> the same for each character. The one-time pad accomplishes this by not using a single number for the secret key, but rather a string of length greater than or equal to the length of the plaintext message you wish to encrypt.<label for="sn-2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-2" class="margin-toggle"/><span class="sidenote"> This secret key is colloquially referred to as a “one-time pad” (of characters), from which this cryptosystem gets its name.</span></p>
<p>To <em>encrypt</em> a plaintext ASCII message <span class="math inline">\(m\)</span> with secret key <span class="math inline">\(k\)</span>, for each index <span class="math inline">\(i\)</span> between 0 and <span class="math inline">\(|m| - 1\)</span>, we compute:</p>
<ul>
<li><span class="math inline">\((m[i] + k[i]) ~\%~ 128\)</span>, where <span class="math inline">\(m[i]\)</span> and <span class="math inline">\(k[i]\)</span> are converted to their numeric representations to do the arithmetic.<label for="sn-3" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-3" class="margin-toggle"/><span class="sidenote"> In contrast, the Caesar cipher calculates <span class="math inline">\((m[i] + k) ~\%~ 128\)</span>, where <span class="math inline">\(k\)</span> is the secret key.</span></li>
</ul>
<p>Here is an example. Suppose we wanted to encrypt the plaintext <code>'HELLO'</code> with the secret key <code>'david'</code>. The ciphertext will have five characters, where the first is <code>'H' + 'd'</code> which results in <code>','</code>, the second is <code>'E' + 'A'</code> which results in <code>'&amp;'</code>, etc. The following diagram shows the full conversion:</p>
<p><img src="./images/one_time_pad.png" alt="One-Time Pad Example Diagram" /><br />
</p>
<p>Similarly, for decryption we take the ciphertext <code>c</code> and recover the plaintext by subtracting each letter of the secret key: <span class="math inline">\((c[i] - k[i]) ~\%~ 128\)</span>.</p>
<h2 id="perfect-secrecy-and-its-costs">Perfect secrecy and its costs</h2>
<p>The one-time pad cryptosystem is famous in cryptography for having a property known as <strong>perfect secrecy</strong>,<label for="sn-4" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-4" class="margin-toggle"/><span class="sidenote"> This is a term termed by the mathematician and cryptographer Claude Shannon in 1949.</span> which informally means that a ciphertext reveals no information about its corresponding plaintext other than its length. To see why, take our previous example, with ciphertext <code>',&amp;B53'</code>. This ciphertext could have been generated by <em>any</em> five-letter plaintext message, because for any such message there exists a secret key that could encrypt that message to obtain <code>',&amp;B53'</code>. The sender could have been sending plaintext message <code>'HELLO'</code> with secret key <code>'david'</code>, but it is equally likely they could have been sending the message <code>'FUNNY'</code> with secret key <code>'fQtgZ'</code>. Because of perfect secrecy, an eavesdropper cannot gain any information about the original plaintext message, even if they know the whole ciphertext.</p>
<p>This perfect secrecy comes at a cost, however. The main drawback of the one-time pad cryptosystem, and why it is not actually used in practice, is that the secret key must have at least the same length as the message being sent, and cannot be reused from one message to another.<label for="sn-5" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-5" class="margin-toggle"/><span class="sidenote"> The notion of perfect secrecy relies on every possible secret key to be chosen purely at random. This isnt the case if I reuse the same one-time pad for all my messages. This requirement is also why the term “one-time” is used for one-time pads.</span></p>
<h2 id="stream-ciphers">Stream ciphers</h2>
<p>The attraction of perfect secrecy has led cryptographers to develop <em>stream ciphers</em>, which are a type of symmetric-key cryptosystem that emulate a one-time pad but share a much smaller secret key. The details of stream ciphers are beyond the scope of this course, but the basic is idea is the following: the shared secret key is quite small (less than 1KB), and both parties use an algorithm to generate an arbitrary number of new random characters, based on both the secret key and any previously-generated characters.<label for="sn-6" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-6" class="margin-toggle"/><span class="sidenote"> We say that this is a “stream” of characters, from which this type of cryptosystem gets its name.</span> These characters are then used in the same way as a one-time pad to encrypt messages.</p>
<p>Now, stream ciphers do not have perfect secrecy, since the characters used in encryption arent truly random. But if the generating algorithm is clever enough, each new character appears “random”, and the encrypted messages are computationally impossible to decrypt without knowing the starting secret key. In other words, stream ciphers give up on perfect secrecy in exchange for “good enough” secrecy and a much, much smaller shared secret key. Of course, the “good enough” is highly dependent on the algorithm used to generate the characters. A poorly-designed algorithm may unintentionally inject patterns in the generated characters, or even allow an eavesdropper to gain some information about the secret key itself!</p>
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>
+182
View File
@@ -0,0 +1,182 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.3 Computing Shared Secret Keys</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="../tufte.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.3 Computing Shared Secret Keys</h1>
</header>
<section>
<p>A historical limitation of symmetric-key cryptosystems was how to establish a shared, but secret, key. If the two communicating parties were able to meet in person, they could agree upon a shared secret key while physically together (assuming no one else was spying on them). But what if I want to communicate with someone securely in a different city or different country? Or, to use a more modern example, to communicate with a server across the Internet, which I cannot hope to meet in person?</p>
<p>One solution to this problem is the <em>Diffie-Hellman key exchange</em>, which is an algorithm that is executed by two people (or computers) to compute a shared secret, while communicating in public (open to eavesdroppers). We will introduce the intuitions of the Diffie-Hellman key exchange with an analogy that uses our familiar Alice and Bob communicating with colours. After, we will replace colours with numbers to understand how the process works in todays digital world.</p>
<h2 id="alice-and-bob-are-mixing-paint">Alice and Bob are mixing paint</h2>
<p>Suppose that Alice and Bob would like to establish a secret <em>paint colour</em> that only the two of them know. They use the following procedure.</p>
<table class="fullwidth">
<tbody>
<tr>
<td style="width: 55%; vertical-align: top; padding-right: 2em;">
<p><em>First</em>, they both agree on a random, not-secret colour of paint to start with: yellow. They decide on this shared colour publicly, so eavesdroppers also know this colour!</p>
<p><em>Second</em>, they each choose their own secret colour, which they will never share with each other or anyone else. In our example, Alice decides on red and Bob chooses teal (a green-blue colour).</p>
<p><em>Third</em>, they each mix their secret colours with their shared colour yellow, producing a light orange for Alice and a blue for Bob. This is also done in secret.</p>
<p><em>Fourth</em>, they exchange these colours with each other, which is done publicly. At this point, there are three not-secret colours: yellow and the two mixtures. And there are two secret colours: Alices red and Bobs teal.</p>
<p><em>Fifth</em>, Alice mixes Bobs blue colour with her original secret red to produce a brown. Bob mixes Alices light orange with his original secret teal to produce the same brown. Why are these the same brown? Because they both consist of the same mixture of three colours: yellow (shared), red (Alices secret), and teal (Bobs secret)!</p>
<p>Finally, why is this brown a secret? Any eavesdropper has access to three colours: the original shared yellow (from the first step), and the two mixtures orange and blue (from the fourth step). If we assume that the colour mixtures are not easily separated (i.e., it is very difficult to extract the yellow from each mixture), then the eavesdropper cannot determine what Alice and Bobs secret colours were, and therefor cant mix them together with the yellow to produce the right shade of brown!</p>
</td>
<td>
<img src="./images/diffie-hellman-paint.png" alt="Alice and Bob paint mixing" /><br />
</td>
</tr>
</tbody>
</table>
<h2 id="the-diffie-hellman-key-exchange">The Diffie-Hellman key exchange</h2>
<p>Unfortunately, transmitting paint across digital channels is intractable, but transmitting numbers isnt. The Diffie-Hellman key exchange uses some neat (yet simple) operations from modular arithmetic to play out the same scenario as our paint analogy.</p>
<div class="framed">
<p><strong>Diffie-Hellman Key Exhange Algorithm</strong></p>
<p>Setting: Two parties, Alice and Bob</p>
<p>Result: Alice and Bob share a secret key <span class="math inline">\(k\)</span>.</p>
<ol type="1">
<li><p>Alice chooses a prime number <span class="math inline">\(p\)</span> greater than two and an integer <span class="math inline">\(g\)</span> which satisfies <span class="math inline">\(2 \leq g \leq p - 1\)</span>, and sends both to Bob.</p></li>
<li><p>Alice chooses a secret number <span class="math inline">\(a \in \{1, 2, \dots, p-1\}\)</span> and sends Bob <span class="math inline">\(A = g^a ~\%~ p\)</span> to Bob.</p></li>
<li><p>Bob chooses a secret number <span class="math inline">\(b \in \{1, 2, \dots, p-1\}\)</span> and sends <span class="math inline">\(B = g^b ~\%~ p\)</span> to Alice.</p></li>
<li><p>Alice computes <span class="math inline">\(k_A = B^a ~\%~ p\)</span>. Bob computes <span class="math inline">\(k_B = A^b ~\%~ p\)</span>.</p>
<p>It turns out that <span class="math inline">\(k_A = k_B\)</span>, and so this value is chosen as the secret key <span class="math inline">\(k\)</span> that Alice and Bob share.</p></li>
</ol>
</div>
<h3 id="an-example">An example</h3>
<p>Here is an example of the Diffie-Hellman key exchange in action.</p>
<ol type="1">
<li>Alice starts by choosing <span class="math inline">\(p = 23\)</span> and <span class="math inline">\(g = 2\)</span>. She sends both <span class="math inline">\(p\)</span> and <span class="math inline">\(g\)</span> to Bob.</li>
<li>Alice chooses a secret number <span class="math inline">\(a = 5\)</span>. She sends <span class="math inline">\(A = g^a ~\%~ p = 2^5 ~\%~ 23 = 9\)</span> to Bob.</li>
<li>Bob chooses a secret number <span class="math inline">\(b = 14\)</span>. He sends <span class="math inline">\(B = g^b ~\%~ p = 2^{14} ~\%~ 23 = 8\)</span> to Alice.</li>
<li>Alice computes <span class="math inline">\(k_A = B^a ~\%~ p = 8^5 ~\%~ 23 = 16\)</span>. Bob computes <span class="math inline">\(k_B = A^b ~\%~ p = 9^{14} ~\%~ 23 = 16\)</span>. As expected, <span class="math inline">\(k_A = k_B\)</span>, and these form the secret key <span class="math inline">\(k\)</span>!</li>
</ol>
<h2 id="correctness-are-k_a-and-k_b-always-equal">Correctness: Are <span class="math inline">\(k_A\)</span> and <span class="math inline">\(k_B\)</span> always equal?</h2>
<p>That last sentence in the Diffie-Hellman key exchange algorithm description is doing a lot of work. How do we “know” that <span class="math inline">\(k_A = k_B\)</span>? With a proof, of course!</p>
<div class="theorem">
<p>(<em>Correctness of Diffie-Hellman key exchange</em>)</p>
<p>For all <span class="math inline">\(p, g, a, b \in \Z^+\)</span>, <span class="math inline">\((g^b ~\%~ p)^a ~\%~ p = (g^a ~\%~ p)^b ~\%~ p\)</span>.</p>
<div class="discussion">
<p>Even though the Diffie-Hellman algorithm frames the communication in terms of remainders, we can analyze the numbers using modular arithmetic modulo <span class="math inline">\(p\)</span>. In this case the calculation involves just switching around exponents in <span class="math inline">\(g^{ab}\)</span>.</p>
</div>
<div class="proof">
<p>Let <span class="math inline">\(p, g, a, b \in Z^+\)</span>. Let <span class="math inline">\(A = g^a ~\%~ p\)</span> and <span class="math inline">\(B = g^b ~\%~ p\)</span>. Well prove that <span class="math inline">\(B^a ~\%~ p = A^b ~\%~ p\)</span>.</p>
<p>First, we have that <span class="math inline">\(A \equiv g^a \pmod p\)</span> and <span class="math inline">\(B \equiv g^b \pmod p\)</span>. So then <span class="math inline">\(A^b \equiv (g^a)^b \equiv g^{ab} \pmod p\)</span>, and <span class="math inline">\(B^a \equiv (g^b)^a \equiv g^{ba} \pmod p\)</span>. Since <span class="math inline">\(g^{ab} = g^{ba}\)</span>, we can conclude that <span class="math inline">\(A^b \equiv B^a \pmod p\)</span>.</p>
<p>So then <span class="math inline">\(A^b\)</span> and <span class="math inline">\(B^a\)</span> must have the same remainder when divided by <span class="math inline">\(p\)</span>, and so <span class="math inline">\(B^a ~\%~ p = A^b ~\%~ p\)</span>.</p>
</div>
</div>
<h2 id="security-how-secret-is-the-key">Security: How secret is the key?</h2>
<p>Weve just proved that the Diffie-Hellman key exchange is <em>correct</em>, meaning the result at the end of the algorithm is that Alice and Bob have a shared key. But thats not the only purpose of this algorithm: it must also ensure that this shared key is also <em>secret</em>, unknown to anyone other than Alice and Bob.</p>
<p>So lets look at the Diffie-Hellman key exchange from the perspective of an eavesdropper that has access to everything Alice and Bob communicate to each other.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> We say that Alice and Bobs communications are <em>public</em>, while their own computing devices are <em>private</em>.</span> So over the course of the algorithm, the eavesdropper has access to <span class="math inline">\(p\)</span>, <span class="math inline">\(g\)</span>, <span class="math inline">\(g^a ~\%~ p\)</span>, and <span class="math inline">\(g^b ~\%~ p\)</span>. The question is: from this information, can the eavesdropper determine the secret key <span class="math inline">\(k\)</span>?</p>
<p>One approach an eavesdropper could take is to try to compute <span class="math inline">\(a\)</span> and <span class="math inline">\(b\)</span> directly. This is an instance of the <strong>discrete logarithm problem</strong>: given <span class="math inline">\(p, g, y \in \Z^+\)</span>, find an <span class="math inline">\(x \in \Z^+\)</span> such that <span class="math inline">\(g^x \equiv y \pmod p\)</span>. While we could implement a <em>brute-force</em> algorithm for solving this problem that simply tries all possible exponents <span class="math inline">\(x \in \{0, 1, \dots, p-1\}\)</span>, this is computationally inefficient in practice when <span class="math inline">\(p\)</span> is chosen to be extremely large.<label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"/><span class="sidenote"> Well explore exactly what we mean by terms like “efficient” and “inefficient” more precisely in the next chapter.</span></p>
<p>Perhaps surprisingly, there is no known <em>efficient</em> algorithm for solving the discrete logarithm problem! So we say that the Diffie-Hellman key exchange is <strong>computationally secure</strong>: while there are known algorithms that eavesdroppers could use for determining the shared secret key, all known algorithms are computationally infeasible for standard primes chosen. In practice, Diffie-Hellman key exchanges tend to use primes on the order of <span class="math inline">\(2^{2048} \approx 10^{617}\)</span>!</p>
<!-- ## Diffie-Hellman in Practice
We have shown that Diffie-Hellman provides a way for two users to share a secret key.
However, the protocol we have presented is rarely used on its own.
The main reason for this is a lack of *authentication*;
there is no way for Bob to know that he is communicating with Alice, or vice versa.
One could imagine an evil and malicious man-in-the-middle, pretending to be Alice or Bob depending on who is sending messages.
Still, the Diffie-Hellman key exchange is typically combined with other algorithms and protocols in cryptography to allow for secure communication.
## Scalability of Symmetric Encryption
Our examples have looked at how two people, Alice and Bob, can communicate with a single key.
However, when we want more than two people to communicate, the number of keys needed will grow.
With symmetric encryption, each pair of users needs its own key to communicate securely.
So how many keys do we need for $n$ users to ensure encrypted, pairwise communication?
The answer is a summation:
$1 + 2 + 3 + ... + (n - 1) = N_k$
Which reduces to:
$N_k = n(n - 1) / 2$
Therefore, as the number of users $n$ grows, the number of keys needed $N_k$ grows quadratically (i.e., $n^2$).^[
We will introduce and define several new terms for scalability in the next chapter.
]
To understand why this is a big deal, consider this: how do we exchange all these keys if we don't have a secured form of communication?
Note that we don't have a secured form of communication until both users have the secret key.
Thus, there are two major drawbacks to symmetric encryption:
1. The number of keys needed grows quadratically with the number of users
2. Keys need to be shared securely before symmetric encryption can be used
Despite these drawbacks, symmetric encryption is still widely used today (e.g., AES).
In the next section, we will see how we can securely exchange a key over a public (i.e., unsecure) channel. -->
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>
+172
View File
@@ -0,0 +1,172 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.4 The RSA Cryptosystem</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="../tufte.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.4 The RSA Cryptosystem</h1>
</header>
<section>
<p>So far, we have studied symmetric-key cryptosystems to allow two parties to communicate securely with each other when they share a secret key. We have also studied how two parties can establish a shared secret key using the Diffie-Hellman key exchange algorithm.</p>
<p>One of the limitations of symmetric-key encryption schemes is that a shared secret key needs to be established for every pair of people who want to communicate. If there are <span class="math inline">\(n\)</span> people who each want to communicate securely with each other, there are <span class="math inline">\(\frac{n(n-1)}{2}\)</span> keys needed:</p>
<ul>
<li>The first person needs <span class="math inline">\(n-1\)</span> secret keys to communicate with everyone else.</li>
<li>The second person needs <span class="math inline">\(n-2\)</span> secret keys to communicate with everyone else besides the first person.</li>
<li>The third person needs <span class="math inline">\(n-3\)</span> secret keys to communicate with everyone else besides the first two people.</li>
<li>This pattern repeats, for a total sum of <span class="math inline">\((n-1) + (n-2) + \cdots + 1 = \frac{n(n-1)}{2}\)</span>.</li>
</ul>
<!-- At the beginning of this chapter we introduced symmetric-key cryptosystems that can encrypt and decrypt messages given some key $k$.
The main issue with symmetric-key cryptosystems is that they do not provide a mechanism for exchanging $k$ securely.
We saw how the Diffie-Hellman key exchange could address this issue by relying on both a combination of private (one for Alice and one for Bob) and public (for both Alice and Bob) data to jointly establish a key $k$.
Unfortunately, the Diffie-Hellman key exchange does not provide any form of authentication;
Alice does not know if she is actually communicating with Bob, or some malicious man-in-the-middle. -->
<p>In this section, well introduce a new form of cryptosystem called a <strong>public-key cryptosystem</strong>, for each each person has two keys: a private key known only to them, and a public key known to everyone. Well see what how to encrypt and decrypt messages in these cryptosystems, how they reduce the number of keys needed for people to communicate, and learn about the most widely-used public-key cryptosystem today, the RSA cryptosystem.</p>
<h2 id="public-key-cryptography">Public-key cryptography</h2>
<p>A <strong>public-key cryptosystem</strong> is one where each party in the communication generates a pair of keys: a <em>private</em> (or <em>secret</em> key, known only to them) and a <em>public</em> key which is known to everyone. Suppose Alice wants to send Bob a message. She uses Bobs <em>public key</em> to encrypt the message, and Bob uses his <em>private key</em> to decrypt the message.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> Recall that in a symmetric-key cryptosystem, messages are encrypted and decrypted with the same keyhence, the symmetry.</span> Similarly, if Bob wants to send a message to Alice, he uses Alices public key to encrypt the message, and Alice uses her private key to decrypt it.</p>
<p>More formally, we define a <strong>secure public-key cryptosystem</strong> as a system with the following parts:</p>
<ul>
<li><p>A set <span class="math inline">\(\mathcal{P}\)</span> of possible original messages, called <strong>plaintext</strong> messages. (E.g., a set of strings)</p></li>
<li><p>A set <span class="math inline">\(\mathcal{C}\)</span> of possible encrypted messages, called <strong>ciphertext</strong> messages. (E.g., another set of strings)</p></li>
<li><p>A set <span class="math inline">\(\mathcal{K}_1\)</span> of possible public keys and a set <span class="math inline">\(\mathcal{K}_2\)</span> of possible private keys.</p></li>
<li><p>A subset <span class="math inline">\(\mathcal{K} \subseteq \mathcal{K}_1 \times \mathcal{K}_2\)</span> of possible <strong>public-private key pairs</strong>. Note that we use <span class="math inline">\(\subseteq\)</span> and not <span class="math inline">\(=\)</span> because not every public key can be paired with every private key.</p></li>
<li><p>Two functions <span class="math inline">\(Encrypt : \mathcal{K_1} \times \mathcal{P} \to \mathcal{C}\)</span> and <span class="math inline">\(Decrypt : \mathcal{K}_2 \times \mathcal{C} \to \mathcal{P}\)</span> that satisfy the following two properties:</p>
<ul>
<li>(<em>correctness</em>) For all <span class="math inline">\((k_1, k_2) \in \mathcal{K}\)</span> and <span class="math inline">\(m \in \mathcal{P}\)</span>, <span class="math inline">\(Decrypt(k_2, Encrypt(k_1, m)) = m\)</span>. (That is, if you encrypt and then decrypt the same message with a public-private key pair, you get back the original message.)</li>
<li>(<em>security</em>) For all <span class="math inline">\((k_1, k_2) \in \mathcal{K}\)</span> and <span class="math inline">\(m \in \mathcal{P}\)</span>, if an eavesdropper only knows the values of the public key <span class="math inline">\(k_1\)</span> and the ciphertext <span class="math inline">\(c = Encrypt(k_1, m)\)</span> but does not know <span class="math inline">\(k_2\)</span>, it is computationally infeasible to find the plaintext message <span class="math inline">\(m\)</span>.</li>
</ul></li>
</ul>
<h2 id="the-rsa-cryptosystem">The RSA cryptosystem</h2>
<p>The Diffie-Hellman key exchange algorithm we studied in the last section worked by relying on the hardness of the <em>discrete logarithm problem</em>. This allowed Alice and Bob to communicate their numbers <span class="math inline">\(g^a ~\%~ p\)</span> and $<span class="math inline">\(g^b ~\%~ p\)</span> publicly, without anyone being able to find the “secret” <span class="math inline">\(a\)</span> and <span class="math inline">\(b\)</span>.</p>
<p>The <strong>Rivest-Shamir-Adleman (RSA) cryptosystem</strong> works with numbers as well, and relies on the surprising hardness of factoring large integers. For example, can you tell me which two prime numbers can be multiplied together to produce <span class="math inline">\(30,929\)</span>? You could write a small Python program to answer this question quite quickly, but that was only a number with 5 digits. What about the number <span class="math inline">\(1,455,980,635,647,702,351,701\)</span>, with 22 digits? In practice, RSA relies on the hardness of factoring integers with <em>hundreds</em> of digits!</p>
<p>Lets see how RSA works.</p>
<h3 id="phase-1-key-generation">Phase 1: Key generation</h3>
<p>Each person in a public-key cryptosystem must first generate a public-private key pair before they can communicate with anyone else. (Think about this as choosing a valid key-pair from the set <span class="math inline">\(\mathcal{K} = \mathcal{K}_1 \times \mathcal{K}_2\)</span>.) For RSA, well put ourselves in Alices shoes and see what she must do to to generate a public and private key.</p>
<ol type="1">
<li><p>First, Alice picks two distinct prime numbers <span class="math inline">\(p\)</span> and <span class="math inline">\(q\)</span>.</p></li>
<li><p>Next, Alice computes the product <span class="math inline">\(n = pq\)</span>.</p></li>
<li><p>Then, Alice chooses an integer <span class="math inline">\(e \in \{2, 3, \dots, \varphi(n) - 1\}\)</span> such that <span class="math inline">\(\gcd(e, \varphi(n)) = 1\)</span>.</p></li>
<li><p>Finally, Alice chooses an integer <span class="math inline">\(d \in \{2, 3, \dots, \varphi(n) - 1\}\)</span> that is the modular inverse of <span class="math inline">\(e\)</span> modulo <span class="math inline">\(\varphi(n)\)</span>. (That is, <span class="math inline">\(de \equiv 1 \pmod{\varphi(n)}\)</span>.)</p></li>
</ol>
<p>Thats it! Alices <em>private key</em> is the tuple <span class="math inline">\((p, q, d)\)</span>, and her public key is the tuple <span class="math inline">\((n, e)\)</span>. Alice shares her public key with the world, but she never tells her private key to anyone.</p>
<h3 id="phase-2-message-encryption">Phase 2: Message encryption</h3>
<p>Now suppose that Bob wants to send Alice a plaintext message <span class="math inline">\(m\)</span>. For now well treat the message as a number between <span class="math inline">\(1\)</span> and <span class="math inline">\(n - 1\)</span>, and will discuss string messages later on in this section. Bob uses Alices public key <span class="math inline">\((n, e)\)</span>:</p>
<ol type="1">
<li>Bob computes the ciphertext <span class="math inline">\(c = m^e ~\%~ n\)</span> and sends it to Alice.</li>
</ol>
<h3 id="phase-3-message-decryption">Phase 3: Message decryption</h3>
<p>Alice receives the ciphertext <span class="math inline">\(c\)</span>. She uses her private key <span class="math inline">\((p, q, d)\)</span> to decrypt the message:</p>
<ol type="1">
<li>Alice computes <span class="math inline">\(m&#39; = c^d ~\%~ n\)</span>.<label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"/><span class="sidenote"> Techincally, Alice can recompute <span class="math inline">\(n\)</span> from the <span class="math inline">\(p\)</span> and <span class="math inline">\(q\)</span> of her private key. Another version of RSA is actually just to store <span class="math inline">\(n\)</span> in the private key, or use the <span class="math inline">\(n\)</span> from her public key (which Alice also has access to) and keep only <span class="math inline">\(d\)</span> as the private key.</span></li>
</ol>
<h3 id="an-example">An example</h3>
<p>Before moving on, lets see an example of a full use of the RSA cryptosystem in action. Alice first needs to generate a public and private key.</p>
<ol type="1">
<li>Alice chooses the prime numbers <span class="math inline">\(p = 23\)</span> and <span class="math inline">\(q = 31\)</span>.</li>
<li>The product is <span class="math inline">\(n = p \cdot q = 23 \cdot 31 = 713\)</span></li>
<li>Next, Alice needs to choose an <span class="math inline">\(e\)</span> where <span class="math inline">\(\gcd(e, \varphi(n)) = 1\)</span>. Alice calculates that <span class="math inline">\(\varphi(713) = 660\)</span>, and chooses <span class="math inline">\(e = 547\)</span> to satisfy the constraints on <span class="math inline">\(e\)</span>.</li>
<li>Finally, Alice calculates the modular inverse to find the last part of the private key (<span class="math inline">\(d \cdot 547 \equiv 1 \pmod{660}\)</span>), so <span class="math inline">\(d = 403\)</span>.</li>
</ol>
<p>For reference, the private key is: <span class="math inline">\((p=23, q=31, d=403)\)</span> and the public key is: <span class="math inline">\((n=713, e=547)\)</span>.</p>
<p>Bob wants to send the number <span class="math inline">\(42\)</span> to Alice. He computes the encrypted number to be <span class="math inline">\(c = 42^e ~\%~ n = 42^{547} ~\%~ 713 = 106\)</span> and sends it to Alice. Alice receives the number <span class="math inline">\(106\)</span> from Bob. She computes the decrypted number to be <span class="math inline">\(m = 106^d ~\%~ 713 = 106^{403} ~\%~ 713 = 42\)</span>. Voila!</p>
<h2 id="proving-the-correctness-of-rsa">Proving the correctness of RSA</h2>
<p>In the RSA cryptosystem, the encryption and decryption algorithms are very straightforward. The “interesting” part is in how the public-private key pair is generated to make the encryption and decryption work! In this section, well come to understand why the key generation involves the steps that it does by proving that the RSA algorithm works correctly, using all the number theory work we developed last week.</p>
<div class="theorem">
<p>Let <span class="math inline">\((p, q, d) \in \Z^+ \times \Z^+ \times \Z^+\)</span> be a private key and <span class="math inline">\((n, e) \in \Z^+ \times \Z^+\)</span> its corresponding public key as generated by “RSA Phase 1”. Let <span class="math inline">\(m, c, m&#39; \in \{1, \dots, n - 1\}\)</span> be the original plaintext message, ciphertext, and decrypted message, respectively, as described in the RSA encryption and decryption phases.</p>
<p>Then <span class="math inline">\(m&#39; = m\)</span> (i.e., the decrypted message is the same as the original message).</p>
<div class="proof">
<p>Let <span class="math inline">\(p, q, n, d, e, m, c, m&#39; \in \N\)</span> be defined as in the above definition of the RSA algorithm. We need to prove that <span class="math inline">\(m&#39; = m\)</span>.</p>
<p> (It is possible to prove this theorem without this assumption, but we will not do so here.)</p>
<p>From the definition of <span class="math inline">\(m&#39;\)</span> in the decryption step, we know <span class="math inline">\(m&#39; \equiv c^d \pmod n\)</span>. From the definition of <span class="math inline">\(c\)</span> in the encryption step, we know <span class="math inline">\(c \equiv m^e \pmod n\)</span>. Putting these together, we have: <span class="math display">\[m&#39; \equiv (m^e)^d \equiv m^{ed} \pmod n.\]</span></p>
<p>So we need to prove that <span class="math inline">\(m^{ed} \equiv m \pmod n\)</span>. From Steps 3 and 4 of the RSA key generation phase, we know that <span class="math inline">\(de \equiv 1 \pmod{\varphi(n)}\)</span>, i.e., there exists a <span class="math inline">\(k \in \Z\)</span> such that <span class="math inline">\(de = k \cdot \varphi(n) + 1\)</span>.</p>
<p>We also know that since <span class="math inline">\(\gcd(m, n) = 1\)</span>, by Eulers Theorem <span class="math inline">\(m^{\varphi(n)} \equiv 1 \pmod n\)</span>.</p>
<p>Putting this all together, we have <span class="math display">\[\begin{align*}
m&#39; &amp;\equiv m^{ed} \pmod n \\
&amp;\equiv m^{k \varphi(n) + 1} \pmod n \\
&amp;\equiv (m^{\varphi(n)})^k \cdot m \pmod n \\
&amp;\equiv 1^k \cdot m \pmod n \tag{by Euler&#39;s Theorem!} \\
&amp;\equiv m \pmod n
\end{align*}\]</span></p>
<p>So <span class="math inline">\(m&#39; \equiv m \pmod n\)</span>. Since we also know <span class="math inline">\(m\)</span> and <span class="math inline">\(m&#39;\)</span> are between <span class="math inline">\(1\)</span> and <span class="math inline">\(n-1\)</span>, we can conclude that <span class="math inline">\(m&#39; = m\)</span>.</p>
</div>
</div>
<h2 id="the-security-of-rsa">The security of RSA</h2>
<p>Now that weve established the correctness of the RSA cryptosystem, lets now discuss its security. As we did for the Diffie-Hellman key exchange, well put ourselves in the role of an eavesdropper who is trying to gain information about a secret message. Suppose we observe Bob sending an encrypted message <span class="math inline">\(c\)</span> to Alice. In addition to the ciphertext, we also know Alices public key <span class="math inline">\((n, e)\)</span>.<label for="sn-2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-2" class="margin-toggle"/><span class="sidenote"> Remember that “public” means that <em>everyone</em> can see it—including possibly malicious users!</span> What information can we hope to gain about Bobs original plaintext message?</p>
<p>First, we know from the RSA encryption phase that <span class="math inline">\(c \equiv m^e \pmod n\)</span>, so if we know all three of <span class="math inline">\(c\)</span>, <span class="math inline">\(e\)</span>, and <span class="math inline">\(n\)</span>, can we determine the value of <span class="math inline">\(m\)</span>? <em>No!</em> We dont have an efficient way of computing “<span class="math inline">\(e\)</span>-th roots” in modular arithmetic.</p>
<p>Another approach we could take is to attempt to discover Alices private key. Recall that <span class="math inline">\(de \equiv 1 \pmod{\varphi(n)}\)</span>. So <span class="math inline">\(d\)</span> is the inverse of <span class="math inline">\(e\)</span> modulo <span class="math inline">\(\varphi(n)\)</span>, and we learned in the last chapter that we can compute modular inverses, so this should be easy, right?</p>
<p><em>Not so fast!</em> We can compute the modular inverse of <span class="math inline">\(d\)</span> modulo <span class="math inline">\(\varphi(n)\)</span> when we know both <span class="math inline">\(d\)</span> and <span class="math inline">\(\varphi(n)\)</span>, but right now we only know <span class="math inline">\(n\)</span>, not <span class="math inline">\(\varphi(n)\)</span>.</p>
<p>So how do we compute <span class="math inline">\(\varphi(n)\)</span>? Well, we know that if <span class="math inline">\(n = p \cdot q\)</span> where <span class="math inline">\(p\)</span> and <span class="math inline">\(q\)</span> are distinct primes, then <span class="math inline">\(\varphi(n) = (p - 1)(q - 1)\)</span>. But here is the problem: <em>it is not computationally feasible to factor <span class="math inline">\(n\)</span> when it is extremely large</em>. This is our second “computationally hard” problem in computer science, the <em>Integer Factorization Problem</em>. Despite the best efforts of computer scientists and mathematicians for centuries, there is no known efficient general algorithm for factoring integers, and it is this fact that keeps the RSA private key <span class="math inline">\((p, q, d)\)</span> secure.</p>
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>
@@ -0,0 +1,268 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.5 Implementing RSA in Python</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="../tufte.css" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.5 Implementing RSA in Python</h1>
</header>
<section>
<p>In the previous section we defined the RSA cryptosystem that used both a public key and private key to send encrypted messages between two parties. In this section, we will see how to implement the RSA cryptosystem in Python. First, we will see how to generate a private key when given two prime numbers. Second, we will see how to encrypt and decrypt a single number. Finally, we will see how to encrypt and decrypt text.</p>
<h2 id="key-generation">Key generation</h2>
<p>Here is our implementation of the first phase of RSA: generating the public-private key pair. In this implementation, we will assume that the prime numbers <span class="math inline">\(p\)</span> and <span class="math inline">\(q\)</span> are given.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> Algorithms do exist for generating these prime numbers, we just wont go over them here.</span></p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">def</span> rsa_generate_key(p: <span class="bu">int</span>, q: <span class="bu">int</span>) <span class="op">-&gt;</span> <span class="op">\</span></span>
<span id="cb1-2"><a href="#cb1-2"></a> <span class="bu">tuple</span>[<span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>, <span class="bu">int</span>], <span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>]]:</span>
<span id="cb1-3"><a href="#cb1-3"></a> <span class="co">&quot;&quot;&quot;Return an RSA key pair generated using primes p and q.</span></span>
<span id="cb1-4"><a href="#cb1-4"></a></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="co"> The return value is a tuple containing two tuples:</span></span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="co"> 1. The first tuple is the private key, containing (p, q, d).</span></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="co"> 2. The second tuple is the public key, containing (n, e).</span></span>
<span id="cb1-8"><a href="#cb1-8"></a></span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="co"> Preconditions:</span></span>
<span id="cb1-10"><a href="#cb1-10"></a><span class="co"> - p and q are prime</span></span>
<span id="cb1-11"><a href="#cb1-11"></a><span class="co"> - p != q</span></span>
<span id="cb1-12"><a href="#cb1-12"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb1-13"><a href="#cb1-13"></a> <span class="co"># Compute the product of p and q</span></span>
<span id="cb1-14"><a href="#cb1-14"></a> n <span class="op">=</span> p <span class="op">*</span> q</span>
<span id="cb1-15"><a href="#cb1-15"></a></span>
<span id="cb1-16"><a href="#cb1-16"></a> <span class="co"># Choose e such that gcd(e, phi_n) == 1.</span></span>
<span id="cb1-17"><a href="#cb1-17"></a> phi_n <span class="op">=</span> (p <span class="op">-</span> <span class="dv">1</span>) <span class="op">*</span> (q <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb1-18"><a href="#cb1-18"></a></span>
<span id="cb1-19"><a href="#cb1-19"></a> <span class="co"># Since e is chosen randomly, we repeat the random choice</span></span>
<span id="cb1-20"><a href="#cb1-20"></a> <span class="co"># until e is coprime to phi_n.</span></span>
<span id="cb1-21"><a href="#cb1-21"></a> e <span class="op">=</span> random.randint(<span class="dv">2</span>, phi_n <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb1-22"><a href="#cb1-22"></a> <span class="cf">while</span> math.gcd(e, phi_n) <span class="op">!=</span> <span class="dv">1</span>:</span>
<span id="cb1-23"><a href="#cb1-23"></a> e <span class="op">=</span> random.randint(<span class="dv">2</span>, phi_n <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb1-24"><a href="#cb1-24"></a></span>
<span id="cb1-25"><a href="#cb1-25"></a> <span class="co"># Choose d such that e * d % phi_n = 1.</span></span>
<span id="cb1-26"><a href="#cb1-26"></a> <span class="co"># Notice that we&#39;re using our modular_inverse from our work in the last chapter!</span></span>
<span id="cb1-27"><a href="#cb1-27"></a> d <span class="op">=</span> modular_inverse(e, phi_n)</span>
<span id="cb1-28"><a href="#cb1-28"></a></span>
<span id="cb1-29"><a href="#cb1-29"></a> <span class="cf">return</span> ((p, q, d), (n, e))</span></code></pre></div>
<p>The algorithm makes use of both a <code>while</code> loop and the <code>random</code> module. The <code>random</code> module is used to generate an <code>e</code>, but the while loop ensures that the <code>e</code> we finally choose is valid. That is, we continue to randomly generate an <code>e</code> <em>until</em> <code>e</code> and <code>phi_n</code> have a greatest common divisor of 1. Once we have <code>e</code>, we can finally calculate the last part of our private key: <code>d</code>. To do so, we make use of the <code>modular_inverse</code> function we defined in the last chapter (which, in turn, used the <code>extended_gcd</code> function).</p>
<h2 id="encrypting-and-decrypting-a-number">Encrypting and decrypting a number</h2>
<p>Next, lets look at RSA encryption, which only uses the public key. Recall that the plaintext here is a number <span class="math inline">\(m\)</span> between <span class="math inline">\(1\)</span> and <span class="math inline">\(n - 1\)</span> inclusive, and the ciphertext is another number <span class="math inline">\(c = m^e ~\%~ n\)</span>. This mathematical definition translates directly into Python:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">def</span> rsa_encrypt(public_key: <span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>], plaintext: <span class="bu">int</span>) <span class="op">-&gt;</span> <span class="bu">int</span>:</span>
<span id="cb2-2"><a href="#cb2-2"></a> <span class="co">&quot;&quot;&quot;Encrypt the given plaintext using the recipient&#39;s public key.</span></span>
<span id="cb2-3"><a href="#cb2-3"></a></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="co"> Preconditions:</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="co"> - public_key is a valid RSA public key (n, e)</span></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="co"> - 0 &lt; plaintext &lt; public_key[0]</span></span>
<span id="cb2-7"><a href="#cb2-7"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb2-8"><a href="#cb2-8"></a> n, e <span class="op">=</span> public_key</span>
<span id="cb2-9"><a href="#cb2-9"></a></span>
<span id="cb2-10"><a href="#cb2-10"></a> encrypted <span class="op">=</span> (plaintext <span class="op">**</span> e) <span class="op">%</span> n</span>
<span id="cb2-11"><a href="#cb2-11"></a></span>
<span id="cb2-12"><a href="#cb2-12"></a> <span class="cf">return</span> encrypted</span></code></pre></div>
<p>The implementation for RSA decryption is almost identical, except we use the private key (i.e., <code>d</code>) for exponentiation.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">def</span> rsa_decrypt(private_key: <span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>, <span class="bu">int</span>] ciphertext: <span class="bu">int</span>) <span class="op">-&gt;</span> <span class="bu">int</span>:</span>
<span id="cb3-2"><a href="#cb3-2"></a> <span class="co">&quot;&quot;&quot;Decrypt the given ciphertext using the recipient&#39;s private key.</span></span>
<span id="cb3-3"><a href="#cb3-3"></a></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="co"> Preconditions:</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="co"> - private_key is a valid RSA private key (p, q, d)</span></span>
<span id="cb3-6"><a href="#cb3-6"></a><span class="co"> - 0 &lt; ciphertext &lt; private_key[0] * private_key[1]</span></span>
<span id="cb3-7"><a href="#cb3-7"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb3-8"><a href="#cb3-8"></a> p, q, d <span class="op">=</span> private_key</span>
<span id="cb3-9"><a href="#cb3-9"></a> n <span class="op">=</span> p <span class="op">*</span> q</span>
<span id="cb3-10"><a href="#cb3-10"></a></span>
<span id="cb3-11"><a href="#cb3-11"></a> decrypted <span class="op">=</span> (ciphertext <span class="op">**</span> d) <span class="op">%</span> n</span>
<span id="cb3-12"><a href="#cb3-12"></a></span>
<span id="cb3-13"><a href="#cb3-13"></a> <span class="cf">return</span> decrypted</span></code></pre></div>
<h2 id="encrypting-and-decrypting-text-using-rsa">Encrypting and decrypting text using RSA</h2>
<p>The above implementation of RSA is correct, but is a little unsatisfying because it encrypts numbers instead of strings, like we saw with the Caesar cipher and One-Time Pad cryptosystem. So next, well see how to adapt the RSA encryption and decryption algorithms to strings.</p>
<p>Our strategy will be to take a string and break it up into individual characters and encrypt each character, just as we did with the Caesar cipher. Well use this approach for both encryption and decryption, using <code>ord</code>/<code>chr</code> to convert between characters and numbers, and a string accumulator to keep track of the encrypted/decrypted results.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">def</span> rsa_encrypt_text(public_key: <span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>], plaintext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb4-2"><a href="#cb4-2"></a> <span class="co">&quot;&quot;&quot;Encrypt the given plaintext using the recipient&#39;s public key.</span></span>
<span id="cb4-3"><a href="#cb4-3"></a></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="co"> Preconditions:</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="co"> - public_key is a valid RSA public key (n, e)</span></span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="co"> - all({0 &lt; ord(c) &lt; public_key[0] for c in plaintext})</span></span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb4-8"><a href="#cb4-8"></a> n, e <span class="op">=</span> public_key</span>
<span id="cb4-9"><a href="#cb4-9"></a></span>
<span id="cb4-10"><a href="#cb4-10"></a> encrypted <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb4-11"><a href="#cb4-11"></a> <span class="cf">for</span> letter <span class="kw">in</span> plaintext:</span>
<span id="cb4-12"><a href="#cb4-12"></a> <span class="co"># Note: we could have also used our rsa_encrypt function here instead</span></span>
<span id="cb4-13"><a href="#cb4-13"></a> encrypted <span class="op">=</span> encrypted <span class="op">+</span> <span class="bu">chr</span>((<span class="bu">ord</span>(letter) <span class="op">**</span> e) <span class="op">%</span> n)</span>
<span id="cb4-14"><a href="#cb4-14"></a></span>
<span id="cb4-15"><a href="#cb4-15"></a> <span class="cf">return</span> encrypted</span>
<span id="cb4-16"><a href="#cb4-16"></a></span>
<span id="cb4-17"><a href="#cb4-17"></a></span>
<span id="cb4-18"><a href="#cb4-18"></a><span class="kw">def</span> rsa_decrypt_text(private_key: <span class="bu">tuple</span>[<span class="bu">int</span>, <span class="bu">int</span>, <span class="bu">int</span>], ciphertext: <span class="bu">str</span>) <span class="op">-&gt;</span> <span class="bu">str</span>:</span>
<span id="cb4-19"><a href="#cb4-19"></a> <span class="co">&quot;&quot;&quot;Decrypt the given ciphertext using the recipient&#39;s private key.</span></span>
<span id="cb4-20"><a href="#cb4-20"></a></span>
<span id="cb4-21"><a href="#cb4-21"></a><span class="co"> Preconditions:</span></span>
<span id="cb4-22"><a href="#cb4-22"></a><span class="co"> - private_key is a valid RSA private key (p, q, d)</span></span>
<span id="cb4-23"><a href="#cb4-23"></a><span class="co"> - all({0 &lt; ord(c) &lt; private_key[0] * private_key[1] for c in ciphertext})</span></span>
<span id="cb4-24"><a href="#cb4-24"></a><span class="co"> &quot;&quot;&quot;</span></span>
<span id="cb4-25"><a href="#cb4-25"></a> p, q, d <span class="op">=</span> private_key</span>
<span id="cb4-26"><a href="#cb4-26"></a> n <span class="op">=</span> p <span class="op">*</span> q</span>
<span id="cb4-27"><a href="#cb4-27"></a></span>
<span id="cb4-28"><a href="#cb4-28"></a> decrypted <span class="op">=</span> <span class="st">&#39;&#39;</span></span>
<span id="cb4-29"><a href="#cb4-29"></a> <span class="cf">for</span> letter <span class="kw">in</span> ciphertext:</span>
<span id="cb4-30"><a href="#cb4-30"></a> <span class="co"># Note: we could have also used our rsa_decrypt function here instead</span></span>
<span id="cb4-31"><a href="#cb4-31"></a> decrypted <span class="op">=</span> decrypted <span class="op">+</span> <span class="bu">chr</span>((<span class="bu">ord</span>(letter) <span class="op">**</span> d) <span class="op">%</span> n)</span>
<span id="cb4-32"><a href="#cb4-32"></a></span>
<span id="cb4-33"><a href="#cb4-33"></a> <span class="cf">return</span> decrypted</span></code></pre></div>
<!-- ### Putting it all together
Let us use the prime numbers 23 and 31 as $p$ and $q$, respectively, to generate our private and public key.
Next, Bob will send the message that `'Shannon is also cool'` using only the public key.
Alice can decrypt the message using her own private key along with the public key.
```python
if __name__ == '__main__':
# 23 and 31 are prime numbers
private_key, public_key = rsa_generate_key(23, 31)
print(f'Private key: {private_key}')
print(f'Public key: {public_key}')
message = 'Shannon is also cool'
print(f'Message: {message_key}')
# Bob uses only the public key to encrypt the message
encrypted_msg = rsa_encrypt(public_key, message)
print(f'Encrypted: {encrypted_msg}')
# Alice uses her private key to decrypt the message
decrypted_msg = rsa_decrypt(private_key, encrypted_msg)
print(f'Decrypted: {decrypted_msg}')
``` -->
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>
@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>7.6 Application: Securing Online Communications</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="../tufte.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<div style="display:none">
\(
\newcommand{\NOT}{\neg}
\newcommand{\AND}{\wedge}
\newcommand{\OR}{\vee}
\newcommand{\XOR}{\oplus}
\newcommand{\IMP}{\Rightarrow}
\newcommand{\IFF}{\Leftrightarrow}
\newcommand{\TRUE}{\text{True}\xspace}
\newcommand{\FALSE}{\text{False}\xspace}
\newcommand{\IN}{\,{\in}\,}
\newcommand{\NOTIN}{\,{\notin}\,}
\newcommand{\TO}{\rightarrow}
\newcommand{\DIV}{\mid}
\newcommand{\NDIV}{\nmid}
\newcommand{\MOD}[1]{\pmod{#1}}
\newcommand{\MODS}[1]{\ (\text{mod}\ #1)}
\newcommand{\N}{\mathbb N}
\newcommand{\Z}{\mathbb Z}
\newcommand{\Q}{\mathbb Q}
\newcommand{\R}{\mathbb R}
\newcommand{\C}{\mathbb C}
\newcommand{\cA}{\mathcal A}
\newcommand{\cB}{\mathcal B}
\newcommand{\cC}{\mathcal C}
\newcommand{\cD}{\mathcal D}
\newcommand{\cE}{\mathcal E}
\newcommand{\cF}{\mathcal F}
\newcommand{\cG}{\mathcal G}
\newcommand{\cH}{\mathcal H}
\newcommand{\cI}{\mathcal I}
\newcommand{\cJ}{\mathcal J}
\newcommand{\cL}{\mathcal L}
\newcommand{\cK}{\mathcal K}
\newcommand{\cN}{\mathcal N}
\newcommand{\cO}{\mathcal O}
\newcommand{\cP}{\mathcal P}
\newcommand{\cQ}{\mathcal Q}
\newcommand{\cS}{\mathcal S}
\newcommand{\cT}{\mathcal T}
\newcommand{\cV}{\mathcal V}
\newcommand{\cW}{\mathcal W}
\newcommand{\cZ}{\mathcal Z}
\newcommand{\emp}{\emptyset}
\newcommand{\bs}{\backslash}
\newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor}
\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
\newcommand{\abs}[1]{\left | #1 \right |}
\newcommand{\xspace}{}
\newcommand{\proofheader}[1]{\underline{\textbf{#1}}}
\)
</div>
<header id="title-block-header">
<h1 class="title">7.6 Application: Securing Online Communications</h1>
</header>
<section>
<p>Cryptography is central to all kinds of computing and online communication in todays modern world. Modern security practices inform every stage of how we interact online, from the Wifi networks we connect to, to how data is transmitted back and forth between our computer and a server halfway around the world, and even how data is encrypted for storage on those servers. Every time we visit a website, watch a video on our phone, or post a photo or tweet, we are relying on modern cryptography to keep our communications private.</p>
<p>In this section, we will tie together our study of cryptography by looking at one specific link in the chain of Internet communication. While doing so, we will explore some of the real-world design decisions and trade-offs that go into implementing a secure communication protocol used by billions of people around the world.</p>
<h2 id="https-and-the-transport-layer-security-protocol">HTTPS and the Transport Layer Security protocol</h2>
<p>Whether you are browsing a website on your computer or on your phone, you can probably see a little padlock icon next to the websites URL. Heres what happens when you click on it:</p>
<div style="text-align: center">
<p><img src="images/https_browser.png" alt="Browser image showing HTTPS icon" /><br />
</p>
</div>
<p>This icon is our web browsers way of telling us that the the data being sent from the server (<code>www.teach.cs.toronto.edu</code> in our above picture) has been encrypted using a communication protocol called <em>HTTPS</em>.<label for="sn-0" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-0" class="margin-toggle"/><span class="sidenote"> We wont define the term “protocol” formally in this course, but you can think of it as an algorithm where the steps are split among two (or more) parties, rather than just a single computer. For example, the Diffie-Hellman key exchange is more commonly referred to as a <em>protocol</em> rather than an algorithm.</span> This protocol consists of two parts:</p>
<ul>
<li><strong>HTTP (Hypertext Transfer Protocol)</strong>, which governs the format of the data being exchanged between your computer and the server.</li>
<li><strong>TLS (Transport Layer Security)</strong>, which governs how the data formatted by HTTP is encrypted during the communication process.</li>
</ul>
<p>On its own, HTTP allows your computer to communicate with servers around the world. But when combined with TLS, those communications are secure and cannot be “snooped” by an eavesdropper (at least not easily!).</p>
<p>An analogy here might be helpful. Suppose youre living in pre-Internet times, and writing a book (or set of course notes!), and want to send a draft to your publisher through mail. <em>HTTP</em> corresponds to the format in which you deliver the book: perhaps chapter by chapter, with a table of contents in front and appendices or an index at the end. <em>TLS</em> corresponds to how you encrypt the contents of what you send in this format. For example, you might apply a Caesar cipher to shift every character in your book or you might enclose each chapter in a separate locked briefcase for which only you and your publisher know the combination. Of course, TLS is much more sophisticated than either of the example “security” approaches. For the rest of this section, well study how TLS uses the concepts weve learned across this chapter to encrypt your online communications.</p>
<h2 id="tls-an-overview-simplified">TLS: An overview (simplified)</h2>
<p>For our description of the TLS protocol, well use the term <em>client</em> to refer to your computer and <em>server</em> to refer to the website you are communicating with. TLS starts off with the client initiating a request to the server (e.g., when you type in a URL into your web browser and press “Enter”). The following happens:</p>
<ol type="1">
<li>When the client initiates the request, the server sends a “proof of identity” that the client has connected with the intended server, which the client verifies. <em>This communication is not encrypted.</em></li>
<li>Then, the client and server perform the <a href="03-key-exchange.html">Diffie-Hellman key exchange algorithm</a> to establish a shared secret key.<label for="sn-1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-1" class="margin-toggle"/><span class="sidenote"> A new secret key is chosen every time you visit a given website. This provides <em>forward secrecy</em>, which means that if an attacker records your communication with a server across multiple sessions, but is only able to discover what your key for a single session, they can only decrypt your communication for that session rather than all your past sessions.</span> <em>This communication is not encrypted either.</em></li>
<li>All remaining communication (e.g., the actual website data!) is encrypted using an agreed-upon symmetric-key cryptosystem, like a <a href="02-one-time-pad.html#stream-ciphers">stream cipher</a>.</li>
</ol>
<p>Thats it! While the protocol seems straightforward, there are a few real-world details that well look at. Let us investigate two questions:</p>
<ol type="1">
<li>Why is symmetric-key encryption (rather than public-key encryption) used to encrypt the communication in step 3?</li>
<li>Given that the first two steps of of TLS are unencrypted, how can the client be sure it is actually communicating with the intended server the whole time?</li>
</ol>
<h2 id="why-symmetric-key-encryption">Why symmetric-key encryption?</h2>
<p>Our first example of symmetric encryption, Caesars cipher, shows just how old the idea is. Public-key encryption is, relatively, much more modern and does not require that the two communicating parties share a secret key. But modern doesnt always mean better—TLS relies on symmetric-key encryption because public-key cryptosystems, like RSA, are significantly <em>slower</em> than their symmetric-key counterparts. While RSA relies on modular exponentiation as the key encryption and decryption steps, modern symmetric-key cryptosystems use faster operations<label for="sn-2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-2" class="margin-toggle"/><span class="sidenote">Typically these operations act on swapping or combining individual bytes in computer memory.</span> to encrypt and decrypt data.</p>
<p>When computers became household commodities, performance was king. Here, performance is a broad term that typically refers to how quickly a computer can do something. For example: how long does it take to encrypt the frame of a video, send it over a wireless connection, and decrypt that frame on your phone? Consider that your phone is likely streaming at least 30 frames per second in order for you to enjoy a video of reasonable quality. Its also increasingly likely that, today, the frame of video is high-definition, which requires even more data to be encrypted and decrypted. While security and privacy is king in todays world, performance cannot be forgotten.</p>
<h2 id="who-am-i-connected-to">Who am I connected to?</h2>
<p>The first two steps of the TLS protocol are “setup” steps for the actual communication of data between the client and server. While a symmetric cryptosystem is used to encrypt the communicated data, these setup steps are unencrypted, and raise a natural question: how do we know we are communicating with the right server?</p>
<p>For example, when we visit <code>www.google.com</code>, and our computer performs the TLS protocol with a distant server, how do we know our computer is connecting to a real Google server, and not some fake server thats simply pretending to be Google? The consequences of establishing a connection with such a “fake Google” server are severe: that server might give us manipulated or fake search results, save our login information, or store text, images, and videos we upload to Google Drive or YouTube. Even if we encrypt all of this data in Step 3 of TLS, that encryption does not protect us from a malicious fake server posing as an honest one.</p>
<p>In order to avoid such a dangerous situation, we need some way to verify that the server (e.g., Google) we intended to speak with is actually who they say they are. Herein lies one of the main benefits of public-key cryptosystems. Every public-key cryptosystem, including RSA, can implement two additional algorithms to:</p>
<ol type="1">
<li>Sign message using the private key</li>
<li>Verify a signature using the public key</li>
</ol>
<p>These algorithms allow a server to <em>sign every message it sends</em> with is private key, and then have the client <em>verify</em> each message signature using the servers public key. We call these <strong>digital signatures</strong>, and they help us identify exactly who we are speaking with. We wont go into the specifics of the algorithms here, but the process for the RSA cryptosystem is similar to what weve outlined in this chapter (i.e., they exploit modular arithmetic). Alice can add her signature, which is a function of her private key, to a message. Bob can verify that Alice is the sender with Alices public key.</p>
<p>Digital signatures are used in each of the first two steps in the TLS protocol, which is what well look at next.</p>
<h3 id="establishing-identity-digital-certificates">Establishing identity: digital certificates</h3>
<p>In the first step of TLS, we said that the server sends the client a “proof of identity”. To make that more precise, the data the server sends in this step is called a <strong>digital certificate</strong>, which has identifying information for the server, including its domain (e.g., <code>www.google.com</code>), its organization name (e.g., “Google LLC”), and its <em>public key</em>.</p>
<p>But how do we know this digital certificate is the “real” one? The certificate also includes the digital signature of a <em>certificate authority</em>, which is an organization whose purpose is to issue digital certificates to website domains and verify the identities of the operators of each of those domains.<label for="sn-3" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-3" class="margin-toggle"/><span class="sidenote"> The largest of these worldwide are IdenTrust and DigiCert, though a recent non-profit called <em>Lets Encrypt</em> launched in 2016.</span> So when the client “verifies” the digital certificate provided by the server, whats actually happening is that the client is verifying the digital signature provided by the certificate authority, using the certificate authoritys public key.<label for="sn-4" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-4" class="margin-toggle"/><span class="sidenote"> You might ask: how does the client know the certificate authoritys public key? It turns out that web browsers come <em>pre-installed</em> with the public keys of many certificate authorities!</span></p>
<h3 id="maintaining-identity-during-diffie-hellman">Maintaining identity during Diffie-Hellman</h3>
<p>After Step 1 of TLS, the client is confident that it has connected with the right server. But we arent in the clear yet—because the Diffie-Hellman algorithm is performed unencrypted, there is still the danger that an attacker might wait for Step 1 to complete and then intercept the messages for Diffie-Hellman in Step 2. Thus the attacker tricking the client into sharing a secret key with the attacker instead of the intended server.</p>
<p>The servers digital certificate doesnt help here! Instead, the server <em>signs all messages</em> it sends during the Diffie-Hellman algorithm, so that at every step the client can verify that the message came from the intended server. Of course, this relies on the client knowing the servers public key, which it gets from the digital certificate in the previous step!</p>
<p>It is this <em>digital signature</em> from the server that allows the client to consistently verify that it is communicating with the server, and that the messages havent been tampered with. At the end of Step 2, the client and server have a shared secret key, and can now communicate safely using symmetric-key encryption.</p>
<!-- ### Key Management
Symmetric encryption only needs one key, but public-key cryptosystems requires both a public and private key (for each person who wants to receive messages).
With public-key cryptosystems, there must be some mechanism to actually *find* public keys.
Typically, public keys are found as *digital certificates* that identify a particular server and organization.
When you connect to the University of Toronto's WiFi for the first time, your computer discovered and validated a certificate.^[
On older operating systems, this may need to be [done manually](https://onesearch.library.utoronto.ca/ic-faq/36617).
]
The details of [key management](https://en.wikipedia.org/wiki/Key_management) is beyond the scope of this course, but it is an important necessity in the world of public-key cryptosystems. -->
<h2 id="ineffectiveness-of-cryptography">(In)effectiveness of Cryptography</h2>
<p>Weve mentioned that Diffie-Hellman and RSA are secure because it is very difficult to extract the private part of the data from what is being publicly communicated. But what if it wasnt that difficult? Remember that both RSA and Diffie-Hellman rely on very large prime numbers. But, as we saw in Chapter 6, generating these prime numbers is costly. And it turns out that, unfortunately, many servers use the same group of prime numbers.</p>
<p>Recall that Diffie-Hellman relies on the discrete logarithm problem being difficult to solve. But some steps of the algorithm can be precomputed for a specific group of prime numbers. In 2015, <a href="https://dl.acm.org/doi/abs/10.1145/2810103.2813707">a team of academics</a> discovered that 82% of servers used the same 512-bit group of prime numbers. The team proposed the Logjam attack, which exploited this vulnerability and compromised communications. They also extrapolated that Logjam applied to the 1024-bit case. Today, 2048-bit keys are used to avoid the Logjam attack—for example, Google <a href="https://www.computing.co.uk/news/2285984/google-updates-ssl-certificates-to-2048bit-encryption">announced in 2013</a> that it switched from 1024- to 2048-bit keys.</p>
<p>The Logjam attack is not an isolated incident. Security protocols are constantly being revised, leading to important updates for web browsers, email clients, servers, etc. Earlier versions of the TLS protocol (1.0 and 1.1) are <a href="https://arstechnica.com/gadgets/2018/10/browser-vendors-unite-to-end-support-for-20-year-old-tls-1-0/">deprecated as of March 2020</a>, which means that “secure” communication must use more recent versions of the protocol. Nor are attacks limited to cryptography. The security and privacy of our data can be attacked at multiple points, and attackers are not limited to exploiting weaknesses when we communicate data. The fields of computer security and data privacy are becoming one of the most important problems to solve as laws and policies slowly catch up to a world where a persons private information is used as a common commodity sold and exchanged by corporations.</p>
</section>
<footer>
<a href="https://www.teach.cs.toronto.edu/~csc110y/fall/notes/">CSC110 Course Notes Home</a>
</footer>
</body>
</html>