Files
CSC110/07-cryptography/01-intro-to-cryptography.html
T
Hykilpikonna 6fffdf686a deploy
2021-12-07 22:28:01 -05:00

416 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>